Merge branch 'main' into feat/structured-output

This commit is contained in:
Novice 2025-04-15 10:27:55 +08:00
commit 33d2c21c56
184 changed files with 5332 additions and 4627 deletions

View File

@ -89,7 +89,7 @@ class AnnotationReplyActionStatusApi(Resource):
app_annotation_job_key = "{}_app_annotation_job_{}".format(action, str(job_id))
cache_result = redis_client.get(app_annotation_job_key)
if cache_result is None:
raise ValueError("The job is not exist.")
raise ValueError("The job does not exist.")
job_status = cache_result.decode()
error_msg = ""
@ -226,7 +226,7 @@ class AnnotationBatchImportStatusApi(Resource):
indexing_cache_key = "app_annotation_batch_import_{}".format(str(job_id))
cache_result = redis_client.get(indexing_cache_key)
if cache_result is None:
raise ValueError("The job is not exist.")
raise ValueError("The job does not exist.")
job_status = cache_result.decode()
error_msg = ""
if job_status == "error":

View File

@ -398,7 +398,7 @@ class DatasetDocumentSegmentBatchImportApi(Resource):
indexing_cache_key = "segment_batch_import_{}".format(job_id)
cache_result = redis_client.get(indexing_cache_key)
if cache_result is None:
raise ValueError("The job is not exist.")
raise ValueError("The job does not exist.")
return {"job_id": job_id, "job_status": cache_result.decode()}, 200

View File

@ -249,6 +249,31 @@ class PluginInstallFromMarketplaceApi(Resource):
return jsonable_encoder(response)
class PluginFetchMarketplacePkgApi(Resource):
@setup_required
@login_required
@account_initialization_required
@plugin_permission_required(install_required=True)
def get(self):
tenant_id = current_user.current_tenant_id
parser = reqparse.RequestParser()
parser.add_argument("plugin_unique_identifier", type=str, required=True, location="args")
args = parser.parse_args()
try:
return jsonable_encoder(
{
"manifest": PluginService.fetch_marketplace_pkg(
tenant_id,
args["plugin_unique_identifier"],
)
}
)
except PluginDaemonClientSideError as e:
raise ValueError(e)
class PluginFetchManifestApi(Resource):
@setup_required
@login_required
@ -488,6 +513,7 @@ api.add_resource(PluginDeleteInstallTaskApi, "/workspaces/current/plugin/tasks/<
api.add_resource(PluginDeleteAllInstallTaskItemsApi, "/workspaces/current/plugin/tasks/delete_all")
api.add_resource(PluginDeleteInstallTaskItemApi, "/workspaces/current/plugin/tasks/<task_id>/delete/<path:identifier>")
api.add_resource(PluginUninstallApi, "/workspaces/current/plugin/uninstall")
api.add_resource(PluginFetchMarketplacePkgApi, "/workspaces/current/plugin/marketplace/pkg")
api.add_resource(PluginChangePermissionApi, "/workspaces/current/plugin/permission/change")
api.add_resource(PluginFetchPermissionApi, "/workspaces/current/plugin/permission/fetch")

View File

@ -13,6 +13,7 @@ from fields.dataset_fields import dataset_detail_fields
from libs.login import current_user
from models.dataset import Dataset, DatasetPermissionEnum
from services.dataset_service import DatasetPermissionService, DatasetService
from services.entities.knowledge_entities.knowledge_entities import RetrievalModel
def _validate_name(name):
@ -120,8 +121,11 @@ class DatasetListApi(DatasetApiResource):
nullable=True,
required=False,
)
args = parser.parse_args()
parser.add_argument("retrieval_model", type=dict, required=False, nullable=True, location="json")
parser.add_argument("embedding_model", type=str, required=False, nullable=True, location="json")
parser.add_argument("embedding_model_provider", type=str, required=False, nullable=True, location="json")
args = parser.parse_args()
try:
dataset = DatasetService.create_empty_dataset(
tenant_id=tenant_id,
@ -133,6 +137,9 @@ class DatasetListApi(DatasetApiResource):
provider=args["provider"],
external_knowledge_api_id=args["external_knowledge_api_id"],
external_knowledge_id=args["external_knowledge_id"],
embedding_model_provider=args["embedding_model_provider"],
embedding_model_name=args["embedding_model"],
retrieval_model=RetrievalModel(**args["retrieval_model"]),
)
except services.errors.dataset.DatasetNameDuplicateError:
raise DatasetNameDuplicateError()

View File

@ -49,7 +49,9 @@ class DocumentAddByTextApi(DatasetApiResource):
parser.add_argument(
"indexing_technique", type=str, choices=Dataset.INDEXING_TECHNIQUE_LIST, nullable=False, location="json"
)
parser.add_argument("retrieval_model", type=dict, required=False, nullable=False, location="json")
parser.add_argument("retrieval_model", type=dict, required=False, nullable=True, location="json")
parser.add_argument("embedding_model", type=str, required=False, nullable=True, location="json")
parser.add_argument("embedding_model_provider", type=str, required=False, nullable=True, location="json")
args = parser.parse_args()
dataset_id = str(dataset_id)
@ -57,7 +59,7 @@ class DocumentAddByTextApi(DatasetApiResource):
dataset = db.session.query(Dataset).filter(Dataset.tenant_id == tenant_id, Dataset.id == dataset_id).first()
if not dataset:
raise ValueError("Dataset is not exist.")
raise ValueError("Dataset does not exist.")
if not dataset.indexing_technique and not args["indexing_technique"]:
raise ValueError("indexing_technique is required.")
@ -114,7 +116,7 @@ class DocumentUpdateByTextApi(DatasetApiResource):
dataset = db.session.query(Dataset).filter(Dataset.tenant_id == tenant_id, Dataset.id == dataset_id).first()
if not dataset:
raise ValueError("Dataset is not exist.")
raise ValueError("Dataset does not exist.")
# indexing_technique is already set in dataset since this is an update
args["indexing_technique"] = dataset.indexing_technique
@ -172,7 +174,7 @@ class DocumentAddByFileApi(DatasetApiResource):
dataset = db.session.query(Dataset).filter(Dataset.tenant_id == tenant_id, Dataset.id == dataset_id).first()
if not dataset:
raise ValueError("Dataset is not exist.")
raise ValueError("Dataset does not exist.")
if not dataset.indexing_technique and not args.get("indexing_technique"):
raise ValueError("indexing_technique is required.")
@ -239,7 +241,7 @@ class DocumentUpdateByFileApi(DatasetApiResource):
dataset = db.session.query(Dataset).filter(Dataset.tenant_id == tenant_id, Dataset.id == dataset_id).first()
if not dataset:
raise ValueError("Dataset is not exist.")
raise ValueError("Dataset does not exist.")
# indexing_technique is already set in dataset since this is an update
args["indexing_technique"] = dataset.indexing_technique
@ -303,7 +305,7 @@ class DocumentDeleteApi(DatasetApiResource):
dataset = db.session.query(Dataset).filter(Dataset.tenant_id == tenant_id, Dataset.id == dataset_id).first()
if not dataset:
raise ValueError("Dataset is not exist.")
raise ValueError("Dataset does not exist.")
document = DocumentService.get_document(dataset.id, document_id)

View File

@ -153,6 +153,7 @@ class MessageBasedAppGenerator(BaseAppGenerator):
query = application_generate_entity.query or "New conversation"
else:
query = next(iter(application_generate_entity.inputs.values()), "New conversation")
query = query or "New conversation"
conversation_name = (query[:20] + "") if len(query) > 20 else query
if not conversation:

View File

@ -453,7 +453,7 @@ class TraceTask:
"version": workflow_run_version,
"total_tokens": total_tokens,
"file_list": file_list,
"triggered_form": workflow_run.triggered_from,
"triggered_from": workflow_run.triggered_from,
"user_id": user_id,
}

View File

@ -70,6 +70,9 @@ class PluginDeclaration(BaseModel):
models: Optional[list[str]] = Field(default_factory=list)
endpoints: Optional[list[str]] = Field(default_factory=list)
class Meta(BaseModel):
minimum_dify_version: Optional[str] = Field(default=None, pattern=r"^\d{1,4}(\.\d{1,4}){1,3}(-\w{1,16})?$")
version: str = Field(..., pattern=r"^\d{1,4}(\.\d{1,4}){1,3}(-\w{1,16})?$")
author: Optional[str] = Field(..., pattern=r"^[a-zA-Z0-9_-]{1,64}$")
name: str = Field(..., pattern=r"^[a-z0-9_-]{1,128}$")
@ -86,6 +89,7 @@ class PluginDeclaration(BaseModel):
model: Optional[ProviderEntity] = None
endpoint: Optional[EndpointProviderDeclaration] = None
agent_strategy: Optional[AgentStrategyProviderEntity] = None
meta: Meta
@model_validator(mode="before")
@classmethod

View File

@ -444,7 +444,7 @@ class QdrantVectorFactory(AbstractVectorFactory):
if dataset_collection_binding:
collection_name = dataset_collection_binding.collection_name
else:
raise ValueError("Dataset Collection Bindings is not exist!")
raise ValueError("Dataset Collection Bindings does not exist!")
else:
if dataset.index_struct_dict:
class_prefix: str = dataset.index_struct_dict["vector_store"]["class_prefix"]

View File

@ -186,6 +186,8 @@ class ParameterExtractorNode(LLMNode):
"usage": None,
"function": {} if not prompt_message_tools else jsonable_encoder(prompt_message_tools[0]),
"tool_call": None,
"model_provider": model_config.provider,
"model_name": model_config.model,
}
try:

View File

@ -130,6 +130,8 @@ class QuestionClassifierNode(LLMNode):
),
"usage": jsonable_encoder(usage),
"finish_reason": finish_reason,
"model_provider": model_config.provider,
"model_name": model_config.model,
}
outputs = {"class_name": category_name, "class_id": category_id}

View File

@ -36,6 +36,8 @@ def init_app(app: DifyApp):
handlers=log_handlers,
force=True,
)
# Disable propagation for noisy loggers to avoid duplicate logs
logging.getLogger("sqlalchemy.engine").propagate = False
log_tz = dify_config.LOG_TZ
if log_tz:
from datetime import datetime

View File

@ -169,6 +169,9 @@ class DatasetService:
provider: str = "vendor",
external_knowledge_api_id: Optional[str] = None,
external_knowledge_id: Optional[str] = None,
embedding_model_provider: Optional[str] = None,
embedding_model_name: Optional[str] = None,
retrieval_model: Optional[RetrievalModel] = None,
):
# check if dataset name already exists
if Dataset.query.filter_by(name=name, tenant_id=tenant_id).first():
@ -176,9 +179,30 @@ class DatasetService:
embedding_model = None
if indexing_technique == "high_quality":
model_manager = ModelManager()
if embedding_model_provider and embedding_model_name:
# check if embedding model setting is valid
DatasetService.check_embedding_model_setting(tenant_id, embedding_model_provider, embedding_model_name)
embedding_model = model_manager.get_model_instance(
tenant_id=tenant_id,
provider=embedding_model_provider,
model_type=ModelType.TEXT_EMBEDDING,
model=embedding_model_name,
)
else:
embedding_model = model_manager.get_default_model_instance(
tenant_id=tenant_id, model_type=ModelType.TEXT_EMBEDDING
)
if retrieval_model and retrieval_model.reranking_model:
if (
retrieval_model.reranking_model.reranking_provider_name
and retrieval_model.reranking_model.reranking_model_name
):
# check if reranking model setting is valid
DatasetService.check_embedding_model_setting(
tenant_id,
retrieval_model.reranking_model.reranking_provider_name,
retrieval_model.reranking_model.reranking_model_name,
)
dataset = Dataset(name=name, indexing_technique=indexing_technique)
# dataset = Dataset(name=name, provider=provider, config=config)
dataset.description = description
@ -187,6 +211,7 @@ class DatasetService:
dataset.tenant_id = tenant_id
dataset.embedding_model_provider = embedding_model.provider if embedding_model else None
dataset.embedding_model = embedding_model.model if embedding_model else None
dataset.retrieval_model = retrieval_model.model_dump() if retrieval_model else None
dataset.permission = permission or DatasetPermissionEnum.ONLY_ME
dataset.provider = provider
db.session.add(dataset)

View File

@ -309,6 +309,22 @@ class PluginService:
],
)
@staticmethod
def fetch_marketplace_pkg(
tenant_id: str, plugin_unique_identifier: str, verify_signature: bool = False
) -> PluginDeclaration:
"""
Fetch marketplace package
"""
manager = PluginInstallationManager()
try:
declaration = manager.fetch_plugin_manifest(tenant_id, plugin_unique_identifier)
except Exception:
pkg = download_plugin_pkg(plugin_unique_identifier)
declaration = manager.upload_pkg(tenant_id, pkg, verify_signature).manifest
return declaration
@staticmethod
def install_from_marketplace_pkg(
tenant_id: str, plugin_unique_identifiers: Sequence[str], verify_signature: bool = False

View File

@ -124,7 +124,7 @@ const ConfigPopup: FC<PopupProps> = ({
)
const configuredProviderPanel = () => {
const configuredPanels: any[] = []
const configuredPanels: JSX.Element[] = []
if (langSmithConfig)
configuredPanels.push(langSmithPanel)
@ -139,7 +139,7 @@ const ConfigPopup: FC<PopupProps> = ({
}
const moreProviderPanel = () => {
const notConfiguredPanels: any[] = []
const notConfiguredPanels: JSX.Element[] = []
if (!langSmithConfig)
notConfiguredPanels.push(langSmithPanel)

View File

@ -1,8 +1,6 @@
import React from 'react'
type Props = {}
const page = (props: Props) => {
const page = () => {
return (
<div>dataset detail api</div>
)

View File

@ -1,22 +1,22 @@
'use client'
import type { FC, SVGProps } from 'react'
import type { FC } from 'react'
import React, { useEffect, useMemo } from 'react'
import { usePathname } from 'next/navigation'
import useSWR from 'swr'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import {
Cog8ToothIcon,
DocumentTextIcon,
RiEqualizer2Fill,
RiEqualizer2Line,
RiFileTextFill,
RiFileTextLine,
RiFocus2Fill,
RiFocus2Line,
} from '@remixicon/react'
import {
PaperClipIcon,
} from '@heroicons/react/24/outline'
import {
Cog8ToothIcon as Cog8ToothSolidIcon,
// CommandLineIcon as CommandLineSolidIcon,
DocumentTextIcon as DocumentTextSolidIcon,
} from '@heroicons/react/24/solid'
import { RiApps2AddLine, RiBookOpenLine, RiInformation2Line } from '@remixicon/react'
import s from './style.module.css'
import classNames from '@/utils/classnames'
import { fetchDatasetDetail, fetchDatasetRelatedApps } from '@/service/datasets'
import type { RelatedAppResponse } from '@/models/datasets'
@ -37,27 +37,6 @@ export type IAppDetailLayoutProps = {
params: { datasetId: string }
}
const TargetIcon = ({ className }: SVGProps<SVGElement>) => {
return <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" className={className ?? ''}>
<g clipPath="url(#clip0_4610_6951)">
<path d="M10.6666 5.33325V3.33325L12.6666 1.33325L13.3332 2.66659L14.6666 3.33325L12.6666 5.33325H10.6666ZM10.6666 5.33325L7.9999 7.99988M14.6666 7.99992C14.6666 11.6818 11.6818 14.6666 7.99992 14.6666C4.31802 14.6666 1.33325 11.6818 1.33325 7.99992C1.33325 4.31802 4.31802 1.33325 7.99992 1.33325M11.3333 7.99992C11.3333 9.84087 9.84087 11.3333 7.99992 11.3333C6.15897 11.3333 4.66659 9.84087 4.66659 7.99992C4.66659 6.15897 6.15897 4.66659 7.99992 4.66659" stroke="#344054" strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round" />
</g>
<defs>
<clipPath id="clip0_4610_6951">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>
}
const TargetSolidIcon = ({ className }: SVGProps<SVGElement>) => {
return <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" className={className ?? ''}>
<path fillRule="evenodd" clipRule="evenodd" d="M12.7733 0.67512C12.9848 0.709447 13.1669 0.843364 13.2627 1.03504L13.83 2.16961L14.9646 2.73689C15.1563 2.83273 15.2902 3.01486 15.3245 3.22639C15.3588 3.43792 15.2894 3.65305 15.1379 3.80458L13.1379 5.80458C13.0128 5.92961 12.8433 5.99985 12.6665 5.99985H10.9426L8.47124 8.47124C8.21089 8.73159 7.78878 8.73159 7.52843 8.47124C7.26808 8.21089 7.26808 7.78878 7.52843 7.52843L9.9998 5.05707V3.33318C9.9998 3.15637 10.07 2.9868 10.1951 2.86177L12.1951 0.861774C12.3466 0.710244 12.5617 0.640794 12.7733 0.67512Z" fill="#155EEF" />
<path d="M1.99984 7.99984C1.99984 4.68613 4.68613 1.99984 7.99984 1.99984C8.36803 1.99984 8.6665 1.70136 8.6665 1.33317C8.6665 0.964981 8.36803 0.666504 7.99984 0.666504C3.94975 0.666504 0.666504 3.94975 0.666504 7.99984C0.666504 12.0499 3.94975 15.3332 7.99984 15.3332C12.0499 15.3332 15.3332 12.0499 15.3332 7.99984C15.3332 7.63165 15.0347 7.33317 14.6665 7.33317C14.2983 7.33317 13.9998 7.63165 13.9998 7.99984C13.9998 11.3135 11.3135 13.9998 7.99984 13.9998C4.68613 13.9998 1.99984 11.3135 1.99984 7.99984Z" fill="#155EEF" />
<path d="M5.33317 7.99984C5.33317 6.52708 6.52708 5.33317 7.99984 5.33317C8.36803 5.33317 8.6665 5.03469 8.6665 4.6665C8.6665 4.29831 8.36803 3.99984 7.99984 3.99984C5.7907 3.99984 3.99984 5.7907 3.99984 7.99984C3.99984 10.209 5.7907 11.9998 7.99984 11.9998C10.209 11.9998 11.9998 10.209 11.9998 7.99984C11.9998 7.63165 11.7014 7.33317 11.3332 7.33317C10.965 7.33317 10.6665 7.63165 10.6665 7.99984C10.6665 9.4726 9.4726 10.6665 7.99984 10.6665C6.52708 10.6665 5.33317 9.4726 5.33317 7.99984Z" fill="#155EEF" />
</svg>
}
type IExtraInfoProps = {
isMobile: boolean
relatedApps?: RelatedAppResponse
@ -98,9 +77,9 @@ const ExtraInfo = ({ isMobile, relatedApps, expand }: IExtraInfoProps) => {
</Tooltip>
)}
{isMobile && <div className={classNames(s.subTitle, 'flex items-center justify-center !px-0 gap-1')}>
{isMobile && <div className={classNames('uppercase text-xs text-text-tertiary font-medium pb-2 pt-4', 'flex items-center justify-center !px-0 gap-1')}>
{relatedAppsTotal || '--'}
<PaperClipIcon className='h-4 w-4 text-gray-700' />
<PaperClipIcon className='h-4 w-4 text-text-secondary' />
</div>}
</>
)}
@ -164,17 +143,16 @@ const DatasetDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
const navigation = useMemo(() => {
const baseNavigation = [
{ name: t('common.datasetMenus.hitTesting'), href: `/datasets/${datasetId}/hitTesting`, icon: TargetIcon, selectedIcon: TargetSolidIcon },
// { name: 'api & webhook', href: `/datasets/${datasetId}/api`, icon: CommandLineIcon, selectedIcon: CommandLineSolidIcon },
{ name: t('common.datasetMenus.settings'), href: `/datasets/${datasetId}/settings`, icon: Cog8ToothIcon, selectedIcon: Cog8ToothSolidIcon },
{ name: t('common.datasetMenus.hitTesting'), href: `/datasets/${datasetId}/hitTesting`, icon: RiFocus2Line, selectedIcon: RiFocus2Fill },
{ name: t('common.datasetMenus.settings'), href: `/datasets/${datasetId}/settings`, icon: RiEqualizer2Line, selectedIcon: RiEqualizer2Fill },
]
if (datasetRes?.provider !== 'external') {
baseNavigation.unshift({
name: t('common.datasetMenus.documents'),
href: `/datasets/${datasetId}/documents`,
icon: DocumentTextIcon,
selectedIcon: DocumentTextSolidIcon,
icon: RiFileTextLine,
selectedIcon: RiFileTextFill,
})
}
return baseNavigation

View File

@ -1,9 +0,0 @@
.statusPoint {
@apply flex justify-center items-center absolute -right-0.5 -bottom-0.5 w-2.5 h-2.5 bg-white rounded;
}
.subTitle {
@apply uppercase text-xs text-gray-500 font-medium px-3 pb-2 pt-4;
}
.emptyIconDiv {
@apply h-7 w-7 bg-gray-50 border border-[#EAECF5] inline-flex justify-center items-center rounded-lg;
}

View File

@ -61,7 +61,7 @@ const DatasetCard = ({
if (onSuccess)
onSuccess()
}
catch (e: any) {
catch {
}
setShowConfirmDelete(false)
}, [dataset.id, notify, onSuccess, t])

View File

@ -37,7 +37,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Col>
This API is based on an existing knowledge and creates a new document through text based on this knowledge.
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -175,7 +175,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Col>
This API is based on an existing knowledge and creates a new document through a file based on this knowledge.
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -314,6 +314,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
</Property>
<Property name='indexing_technique' type='string' key='indexing_technique'>
Index technique (optional)
If this is not set, embedding_model, embedding_provider_name and retrieval_model will be set to null
- <code>high_quality</code> High quality
- <code>economy</code> Economy
</Property>
@ -334,6 +335,26 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Property name='external_knowledge_id' type='str' key='external_knowledge_id'>
External knowledge ID (optional)
</Property>
<Property name='embedding_model' type='str' key='embedding_model'>
Embedding model name (optional)
</Property>
<Property name='embedding_provider_name' type='str' key='embedding_provider_name'>
Embedding model provider name (optional)
</Property>
<Property name='retrieval_model' type='object' key='retrieval_model'>
Retrieval model (optional)
- <code>search_method</code> (string) Search method
- <code>hybrid_search</code> Hybrid search
- <code>semantic_search</code> Semantic search
- <code>full_text_search</code> Full-text search
- <code>reranking_enable</code> (bool) Whether to enable reranking
- <code>reranking_model</code> (object) Rerank model configuration
- <code>reranking_provider_name</code> (string) Rerank model provider
- <code>reranking_model_name</code> (string) Rerank model name
- <code>top_k</code> (int) Number of results to return
- <code>score_threshold_enabled</code> (bool) Whether to enable score threshold
- <code>score_threshold</code> (float) Score threshold
</Property>
</Properties>
</Col>
<Col sticky>
@ -461,7 +482,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Query
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge Base ID
@ -542,7 +563,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Query
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge Base ID
@ -650,7 +671,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -689,7 +710,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Col>
This API is based on an existing knowledge and updates the document through text based on this knowledge.
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -791,7 +812,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Col>
This API is based on an existing knowledge, and updates documents through files based on this knowledge
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -888,7 +909,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -943,7 +964,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -985,7 +1006,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1060,7 +1081,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1252,10 +1273,10 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
title="Request"
tag="DELETE"
label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}"
targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
>
```bash {{ title: 'cURL' }}
curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/segments/{segment_id}' \
curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \
--header 'Authorization: Bearer {api_key}' \
--header 'Content-Type: application/json'
```
@ -1369,7 +1390,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1440,7 +1461,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1517,7 +1538,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1565,7 +1586,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1834,7 +1855,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1881,7 +1902,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1930,7 +1951,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1963,7 +1984,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID
@ -1996,7 +2017,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
Knowledge ID

View File

@ -37,7 +37,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Col>
この API は既存のナレッジに基づいており、このナレッジを基にテキストを使用して新しいドキュメントを作成します。
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -175,7 +175,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Col>
この API は既存のナレッジに基づいており、このナレッジを基にファイルを使用して新しいドキュメントを作成します。
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -334,6 +334,26 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Property name='external_knowledge_id' type='str' key='external_knowledge_id'>
外部ナレッジ ID (オプション)
</Property>
<Property name='embedding_model' type='str' key='embedding_model'>
埋め込みモデル名(任意)
</Property>
<Property name='embedding_provider_name' type='str' key='embedding_provider_name'>
埋め込みモデルのプロバイダ名(任意)
</Property>
<Property name='retrieval_model' type='object' key='retrieval_model'>
検索モデル(任意)
- <code>search_method</code> (文字列) 検索方法
- <code>hybrid_search</code> ハイブリッド検索
- <code>semantic_search</code> セマンティック検索
- <code>full_text_search</code> 全文検索
- <code>reranking_enable</code> (ブール値) リランキングを有効にするかどうか
- <code>reranking_model</code> (オブジェクト) リランクモデルの設定
- <code>reranking_provider_name</code> (文字列) リランクモデルのプロバイダ
- <code>reranking_model_name</code> (文字列) リランクモデル名
- <code>top_k</code> (整数) 返される結果の数
- <code>score_threshold_enabled</code> (ブール値) スコア閾値を有効にするかどうか
- <code>score_threshold</code> (浮動小数点数) スコア閾値
</Property>
</Properties>
</Col>
<Col sticky>
@ -500,7 +520,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Col>
この API は既存のナレッジに基づいており、このナレッジを基にテキストを使用してドキュメントを更新します。
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -602,7 +622,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Col>
この API は既存のナレッジに基づいており、このナレッジを基にファイルを使用してドキュメントを更新します。
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -754,7 +774,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -796,7 +816,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -871,7 +891,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1063,10 +1083,10 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
title="リクエスト"
tag="DELETE"
label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}"
targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
>
```bash {{ title: 'cURL' }}
curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/segments/{segment_id}' \
curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \
--header 'Authorization: Bearer {api_key}' \
--header 'Content-Type: application/json'
```
@ -1180,7 +1200,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1251,7 +1271,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1328,7 +1348,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1376,7 +1396,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1645,7 +1665,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1692,7 +1712,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1741,7 +1761,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1774,7 +1794,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1807,7 +1827,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID
@ -1848,7 +1868,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### パラメータ
### パ
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
ナレッジ ID

View File

@ -335,6 +335,26 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
<Property name='external_knowledge_id' type='str' key='external_knowledge_id'>
外部知识库 ID选填
</Property>
<Property name='embedding_model' type='str' key='embedding_model'>
Embedding 模型名称
</Property>
<Property name='embedding_provider_name' type='str' key='embedding_provider_name'>
Embedding 模型供应商
</Property>
<Property name='retrieval_model' type='object' key='retrieval_model'>
检索模式
- <code>search_method</code> (string) 检索方法
- <code>hybrid_search</code> 混合检索
- <code>semantic_search</code> 语义检索
- <code>full_text_search</code> 全文检索
- <code>reranking_enable</code> (bool) 是否开启rerank
- <code>reranking_model</code> (object) Rerank 模型配置
- <code>reranking_provider_name</code> (string) Rerank 模型的提供商
- <code>reranking_model_name</code> (string) Rerank 模型的名称
- <code>top_k</code> (int) 召回条数
- <code>score_threshold_enabled</code> (bool)是否开启召回分数限制
- <code>score_threshold</code> (float) 召回分数限制
</Property>
</Properties>
</Col>
<Col sticky>
@ -462,7 +482,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Query
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
知识库 ID
@ -543,11 +563,15 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Query
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
知识库 ID
</Property>
</Properties>
### Request Body
<Properties>
<Property name='indexing_technique' type='string' key='indexing_technique'>
索引模式(选填,建议填写)
- <code>high_quality</code> 高质量
@ -1917,7 +1941,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
知识库 ID
@ -1966,7 +1990,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
知识库 ID
@ -1999,7 +2023,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
知识库 ID
@ -2032,7 +2056,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Params
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
知识库 ID
@ -2073,7 +2097,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
/>
<Row>
<Col>
### Query
### Path
<Properties>
<Property name='dataset_id' type='string' key='dataset_id'>
知识库 ID

View File

@ -85,7 +85,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
setAppDetail(app)
mutateApps()
}
catch (e) {
catch {
notify({ type: 'error', message: t('app.editFailed') })
}
}, [appDetail, mutateApps, notify, setAppDetail, t])
@ -112,7 +112,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
onPlanInfoChanged()
getRedirection(true, newApp, replace)
}
catch (e) {
catch {
notify({ type: 'error', message: t('app.newApp.appCreateFailed') })
}
}
@ -131,7 +131,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
a.download = `${appDetail.name}.yml`
a.click()
}
catch (e) {
catch {
notify({ type: 'error', message: t('app.exportFailed') })
}
}
@ -152,7 +152,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
}
setSecretEnvList(list)
}
catch (e) {
catch {
notify({ type: 'error', message: t('app.exportFailed') })
}
}
@ -175,7 +175,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
})
}
setShowConfirmDelete(false)
}, [appDetail, mutateApps, notify, onPlanInfoChanged, replace, t])
}, [appDetail, mutateApps, notify, onPlanInfoChanged, replace, setAppDetail, t])
const { isCurrentWorkspaceEditor } = useAppContext()

View File

@ -1,7 +1,6 @@
import React, { useEffect } from 'react'
import { useShallow } from 'zustand/react/shallow'
import { RiLayoutRight2Line } from '@remixicon/react'
import { LayoutRight2LineMod } from '../base/icons/src/public/knowledge'
import { RiLayoutLeft2Line, RiLayoutRight2Line } from '@remixicon/react'
import NavLink from './navLink'
import type { NavIcon } from './navLink'
import AppBasic from './basic'
@ -108,13 +107,13 @@ const AppDetailNav = ({ title, desc, isExternal, icon, icon_background, navigati
`}
>
<div
className='flex h-6 w-6 cursor-pointer items-center justify-center text-gray-500'
className='flex h-6 w-6 cursor-pointer items-center justify-center'
onClick={() => handleToggle(appSidebarExpand)}
>
{
expand
? <RiLayoutRight2Line className='h-5 w-5 text-components-menu-item-text' />
: <LayoutRight2LineMod className='h-5 w-5 text-components-menu-item-text' />
: <RiLayoutLeft2Line className='h-5 w-5 text-components-menu-item-text' />
}
</div>
</div>

View File

@ -56,7 +56,7 @@ const AddAnnotationModal: FC<Props> = ({
try {
await onAdd(payload)
}
catch (e) {
catch {
}
setIsSaving(false)

View File

@ -90,7 +90,7 @@ const Annotation: FC<Props> = ({
setList(data as AnnotationItem[])
setTotal(total)
}
catch (e) {
catch {
}
setIsLoading(false)

View File

@ -55,7 +55,7 @@ const ViewAnnotationModal: FC<Props> = ({
setHitHistoryList(data as HitHistoryItem[])
setTotal(total)
}
catch (e) {
catch {
}
}

View File

@ -241,7 +241,8 @@ const Prompt: FC<ISimplePromptInput> = ({
selectable: !hasSetBlockStatus.query,
}}
onChange={(value) => {
handleChange?.(value, [])
if (handleChange)
handleChange(value, [])
}}
onBlur={() => {
handleChange(promptTemplate, getVars(promptTemplate))

View File

@ -73,7 +73,7 @@ const AgentTools: FC = () => {
formattingChangedDispatcher()
}
const handleToolAuthSetting = (value: any) => {
const handleToolAuthSetting = (value: AgentToolWithMoreInfo) => {
const newModelConfig = produce(modelConfig, (draft) => {
const tool = (draft.agentConfig.tools).find((item: any) => item.provider_id === value?.collection?.id && item.tool_name === value?.tool_name)
if (tool)
@ -121,7 +121,7 @@ const AgentTools: FC = () => {
}
headerRight={
<div className='flex items-center'>
<div className='text-xs font-normal leading-[18px] text-text-tertiary'>{tools.filter((item: any) => !!item.enabled).length}/{tools.length}&nbsp;{t('appDebug.agent.tools.enabled')}</div>
<div className='text-xs font-normal leading-[18px] text-text-tertiary'>{tools.filter(item => !!item.enabled).length}/{tools.length}&nbsp;{t('appDebug.agent.tools.enabled')}</div>
{tools.length < MAX_TOOLS_NUM && (
<>
<div className='ml-3 mr-1 h-3.5 w-px bg-divider-regular'></div>
@ -273,7 +273,7 @@ const AgentTools: FC = () => {
{isShowSettingTool && (
<SettingBuiltInTool
toolName={currentTool?.tool_name as string}
setting={currentTool?.tool_parameters as any}
setting={currentTool?.tool_parameters}
collection={currentTool?.collection as Collection}
isBuiltIn={currentTool?.collection?.type === CollectionType.builtIn}
isModel={currentTool?.collection?.type === CollectionType.model}
@ -291,7 +291,7 @@ const AgentTools: FC = () => {
type: 'success',
message: t('common.api.actionSuccess'),
})
handleToolAuthSetting(currentTool as any)
handleToolAuthSetting(currentTool)
setShowSettingAuth(false)
}}
/>

View File

@ -56,8 +56,8 @@ const SettingBuiltInTool: FC<Props> = ({
const [tools, setTools] = useState<Tool[]>([])
const currTool = tools.find(tool => tool.name === toolName)
const formSchemas = currTool ? toolParametersToFormSchemas(currTool.parameters) : []
const infoSchemas = formSchemas.filter((item: any) => item.form === 'llm')
const settingSchemas = formSchemas.filter((item: any) => item.form !== 'llm')
const infoSchemas = formSchemas.filter(item => item.form === 'llm')
const settingSchemas = formSchemas.filter(item => item.form !== 'llm')
const hasSetting = settingSchemas.length > 0
const [tempSetting, setTempSetting] = useState(setting)
const [currType, setCurrType] = useState('info')
@ -88,7 +88,7 @@ const SettingBuiltInTool: FC<Props> = ({
setTempSetting(addDefaultValue(setting, formSchemas))
}
}
catch (e) { }
catch { }
setIsLoading(false)
})()
}, [collection?.name, collection?.id, collection?.type])
@ -99,7 +99,7 @@ const SettingBuiltInTool: FC<Props> = ({
const isValid = (() => {
let valid = true
settingSchemas.forEach((item: any) => {
settingSchemas.forEach((item) => {
if (item.required && !tempSetting[item.name])
valid = false
})
@ -120,7 +120,7 @@ const SettingBuiltInTool: FC<Props> = ({
<div className=''>
{infoSchemas.length > 0 && (
<div className='space-y-1 py-2'>
{infoSchemas.map((item: any, index) => (
{infoSchemas.map((item, index) => (
<div key={index} className='py-1'>
<div className='flex items-center gap-2'>
<div className='code-sm-semibold text-text-secondary'>{item.label[language]}</div>
@ -147,7 +147,7 @@ const SettingBuiltInTool: FC<Props> = ({
<Form
value={tempSetting}
onChange={setTempSetting}
formSchemas={settingSchemas as any}
formSchemas={settingSchemas}
isEditMode={false}
showOnVariableMap={{}}
validating={false}

View File

@ -368,8 +368,8 @@ const ConfigContent: FC<Props> = ({
provider={model?.provider}
completionParams={model?.completion_params}
modelId={model?.name}
setModel={onSingleRetrievalModelChange as any}
onCompletionParamsChange={onSingleRetrievalModelParamsChange as any}
setModel={onSingleRetrievalModelChange}
onCompletionParamsChange={onSingleRetrievalModelParamsChange}
hideDebugWithMultipleModel
debugWithMultipleModel={false}
/>

View File

@ -150,7 +150,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
retrieval_model_dict: retrievalConfig,
})
}
catch (e) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
finally {

View File

@ -8,6 +8,7 @@ import ModelParameterModal from '@/app/components/header/account-setting/model-p
import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon'
import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name'
import {
type FormValue,
MODEL_STATUS_TEXT,
ModelStatusEnum,
} from '@/app/components/header/account-setting/model-provider-page/declarations'
@ -45,7 +46,7 @@ const ModelParameterTrigger: FC<ModelParameterTriggerProps> = ({
}
onMultipleModelConfigsChange(true, newModelConfigs)
}
const handleParamsChange = (params: any) => {
const handleParamsChange = (params: FormValue) => {
const newModelConfigs = [...multipleModelConfigs]
newModelConfigs[index] = {
...newModelConfigs[index],

View File

@ -227,7 +227,7 @@ const Configuration: FC = () => {
}, [modelModeType])
const [dataSets, setDataSets] = useState<DataSet[]>([])
const contextVar = modelConfig.configs.prompt_variables.find((item: any) => item.is_context_var)?.key
const contextVar = modelConfig.configs.prompt_variables.find(item => item.is_context_var)?.key
const hasSetContextVar = !!contextVar
const [isShowSelectDataSet, { setTrue: showSelectDataSet, setFalse: hideSelectDataSet }] = useBoolean(false)
const selectedIds = dataSets.map(item => item.id)
@ -245,7 +245,7 @@ const Configuration: FC = () => {
formattingChangedDispatcher()
let newDatasets = data
if (data.find(item => !item.name)) { // has not loaded selected dataset
const newSelected = produce(data, (draft: any) => {
const newSelected = produce(data, (draft) => {
data.forEach((item, index) => {
if (!item.name) { // not fetched database
const newItem = dataSets.find(i => i.id === item.id)
@ -513,7 +513,7 @@ const Configuration: FC = () => {
if (modelConfig.chat_prompt_config && modelConfig.chat_prompt_config.prompt.length > 0)
setChatPromptConfig(modelConfig.chat_prompt_config)
else
setChatPromptConfig(clone(DEFAULT_CHAT_PROMPT_CONFIG) as any)
setChatPromptConfig(clone(DEFAULT_CHAT_PROMPT_CONFIG))
setCompletionPromptConfig(modelConfig.completion_prompt_config || clone(DEFAULT_COMPLETION_PROMPT_CONFIG) as any)
setCanReturnToSimpleMode(false)
}

View File

@ -79,7 +79,7 @@ const PromptValuePanel: FC<IPromptValuePanelProps> = ({
}
const onClear = () => {
const newInputs: Record<string, any> = {}
const newInputs: Inputs = {}
promptVariables.forEach((item) => {
newInputs[item.key] = ''
})

View File

@ -151,7 +151,7 @@ const ExternalDataToolModal: FC<ExternalDataToolModalProps> = ({
return
}
if (localeData.variable && !/[a-zA-Z_][a-zA-Z0-9_]{0,29}/g.test(localeData.variable)) {
if (localeData.variable && !/[a-zA-Z_]\w{0,29}/g.test(localeData.variable)) {
notify({ type: 'error', message: t('appDebug.varKeyError.notValid', { key: t('appDebug.feature.tools.modal.variableName.title') }) })
return
}

View File

@ -153,7 +153,7 @@ const Apps = ({
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
getRedirection(isCurrentWorkspaceEditor, { id: app.app_id!, mode }, push)
}
catch (e) {
catch {
Toast.notify({ type: 'error', message: t('app.newApp.appCreateFailed') })
}
}

View File

@ -90,7 +90,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate }: CreateAppProps)
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
getRedirection(isCurrentWorkspaceEditor, app, push)
}
catch (e) {
catch {
notify({ type: 'error', message: t('app.newApp.appCreateFailed') })
}
isCreatingRef.current = false
@ -287,7 +287,6 @@ type AppTypeCardProps = {
onClick: () => void
}
function AppTypeCard({ icon, title, description, active, onClick }: AppTypeCardProps) {
const { t } = useTranslation()
return <div
className={
cn(`relative box-content h-[84px] w-[191px] cursor-pointer rounded-xl

View File

@ -30,7 +30,7 @@ const LogAnnotation: FC<Props> = ({
{ value: PageType.log, text: t('appLog.title') },
{ value: PageType.annotation, text: t('appAnnotation.title') },
]
}, [appDetail])
}, [appDetail?.mode, t])
if (!appDetail) {
return (

View File

@ -547,7 +547,7 @@ const CompletionConversationDetailComp: FC<{ appId?: string; conversationId?: st
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
return true
}
catch (err) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
return false
}
@ -560,7 +560,7 @@ const CompletionConversationDetailComp: FC<{ appId?: string; conversationId?: st
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
return true
}
catch (err) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
return false
}
@ -591,7 +591,7 @@ const ChatConversationDetailComp: FC<{ appId?: string; conversationId?: string }
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
return true
}
catch (err) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
return false
}
@ -603,7 +603,7 @@ const ChatConversationDetailComp: FC<{ appId?: string; conversationId?: string }
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
return true
}
catch (err) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
return false
}

View File

@ -110,7 +110,7 @@ const Embedded = ({ siteInfo, isShow, onClose, appBaseUrl, accessToken, classNam
}
const navigateToChromeUrl = () => {
window.open('https://chrome.google.com/webstore/detail/dify-chatbot/ceehdapohffmjmkdcifjofadiaoeggaf', '_blank')
window.open('https://chrome.google.com/webstore/detail/dify-chatbot/ceehdapohffmjmkdcifjofadiaoeggaf', '_blank', 'noopener,noreferrer')
}
useEffect(() => {

View File

@ -82,7 +82,7 @@ const SwitchAppModal = ({ show, appDetail, inAppDetail = false, onSuccess, onClo
removeOriginal ? replace : push,
)
}
catch (e) {
catch {
notify({ type: 'error', message: t('app.newApp.appCreateFailed') })
}
}

View File

@ -36,7 +36,7 @@ const AgentLogDetail: FC<AgentLogDetailProps> = ({
const [list, setList] = useState<AgentIteration[]>([])
const tools = useMemo(() => {
const res = uniq(flatten(runDetail?.iterations.map((iteration: any) => {
const res = uniq(flatten(runDetail?.iterations.map((iteration) => {
return iteration.tool_calls.map((tool: any) => tool.tool_name).filter(Boolean)
})).filter(Boolean))
return res

View File

@ -33,7 +33,7 @@ export class AudioPlayerManager {
this.audioPlayers.cacheBuffers = []
this.audioPlayers.sourceBuffer?.abort()
}
catch (e) {
catch {
}
}

View File

@ -125,7 +125,7 @@ export default class AudioPlayer {
this.receiveAudioData(value)
}
}
catch (error) {
catch {
this.isLoadData = false
this.callback && this.callback('error')
}

View File

@ -29,7 +29,7 @@ const AudioBtn = ({
const params = useParams()
const pathname = usePathname()
const audio_finished_call = (event: string): any => {
const audio_finished_call = (event: string): void => {
switch (event) {
case 'ended':
setAudioState('ended')
@ -97,7 +97,7 @@ const AudioBtn = ({
</div>
)
: (
<div className={`flex h-full w-full items-center justify-center rounded-md ${!isAudition ? 'hover:bg-gray-50' : 'hover:bg-gray-50'}`}>
<div className={'flex h-full w-full items-center justify-center rounded-md hover:bg-gray-50'}>
<div className={`h-4 w-4 ${(audioState === 'playing') ? s.pauseIcon : s.playIcon}`}></div>
</div>
)}

View File

@ -124,7 +124,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({ src }) => {
setWaveformData(normalizedWaveform)
setIsAudioAvailable(true)
}
catch (error) {
catch {
const waveform: number[] = []
let prevValue = Math.random()

View File

@ -512,7 +512,7 @@ export const useChat = (
responseItem.workflowProcess!.tracing!.push({
...iterationStartedData,
status: WorkflowRunningStatus.Running,
} as any)
})
updateCurrentQAOnTree({
placeholderQuestionId,
questionItem,
@ -528,7 +528,7 @@ export const useChat = (
...tracing[iterationIndex],
...iterationFinishedData,
status: WorkflowRunningStatus.Succeeded,
} as any
}
updateCurrentQAOnTree({
placeholderQuestionId,
@ -547,7 +547,7 @@ export const useChat = (
responseItem.workflowProcess!.tracing!.push({
...nodeStartedData,
status: WorkflowRunningStatus.Running,
} as any)
})
updateCurrentQAOnTree({
placeholderQuestionId,
questionItem,
@ -590,7 +590,7 @@ export const useChat = (
responseItem.workflowProcess!.tracing!.push({
...loopStartedData,
status: WorkflowRunningStatus.Running,
} as any)
})
updateCurrentQAOnTree({
placeholderQuestionId,
questionItem,
@ -606,7 +606,7 @@ export const useChat = (
...tracing[loopIndex],
...loopFinishedData,
status: WorkflowRunningStatus.Succeeded,
} as any
}
updateCurrentQAOnTree({
placeholderQuestionId,

View File

@ -196,7 +196,8 @@ const Chat: FC<ChatProps> = ({
const chatContainer = chatContainerRef.current
if (chatContainer) {
const setUserScrolled = () => {
if (chatContainer)
// eslint-disable-next-line sonarjs/no-gratuitous-expressions
if (chatContainer) // its in event callback, chatContainer may be null
userScrolledRef.current = chatContainer.scrollHeight - chatContainer.scrollTop > chatContainer.clientHeight
}
chatContainer.addEventListener('scroll', setUserScrolled)

View File

@ -14,7 +14,7 @@ function getValue(value: string, isValueArray: boolean, index: number) {
try {
return JSON.parse(value)[index]
}
catch (e) {
catch {
}
}
return value
@ -29,7 +29,7 @@ const Thought: FC<IThoughtProps> = ({
if (Array.isArray(JSON.parse(thought.tool)))
return [JSON.parse(thought.tool), true]
}
catch (e) {
catch {
}
return [[thought.tool], false]
})()

View File

@ -138,16 +138,7 @@ const ChatWrapper = () => {
isPublicAPI: !isInstalledApp,
},
)
}, [
chatList,
handleNewConversationCompleted,
handleSend,
currentConversationId,
currentConversationItem,
newConversationInputs,
isInstalledApp,
appId,
])
}, [currentConversationId, currentConversationInputs, newConversationInputs, chatList, handleSend, isInstalledApp, appId, handleNewConversationCompleted])
const doRegenerate = useCallback((chatItem: ChatItemInTree) => {
const question = chatList.find(item => item.id === chatItem.parentMessageId)!

View File

@ -24,7 +24,6 @@ const InputsFormContent = ({ showTip }: Props) => {
handleNewConversationInputsChange,
} = useEmbeddedChatbotContext()
const inputsFormValue = currentConversationId ? currentConversationInputs : newConversationInputs
const readonly = !!currentConversationId
const handleFormChange = useCallback((variable: string, value: any) => {
setCurrentConversationInputs({

View File

@ -12,6 +12,7 @@ import useAnnotationConfig from '@/app/components/base/features/new-feature-pane
import ConfigParamModal from '@/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal'
import AnnotationFullModal from '@/app/components/billing/annotation-full/modal'
import { ANNOTATION_DEFAULT } from '@/config'
import type { AnnotationReplyConfig } from '@/models/debug'
type Props = {
disabled?: boolean
@ -30,7 +31,7 @@ const AnnotationReply = ({
const featuresStore = useFeaturesStore()
const annotationReply = useFeatures(s => s.features.annotationReply)
const updateAnnotationReply = useCallback((newConfig: any) => {
const updateAnnotationReply = useCallback((newConfig: AnnotationReplyConfig) => {
const {
features,
setFeatures,

View File

@ -348,14 +348,14 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
config={localeData.config?.inputs_config || { enabled: false, preset_response: '' }}
onConfigChange={config => handleDataContentChange('inputs_config', config)}
info={(localeData.type === 'api' && t('appDebug.feature.moderation.modal.content.fromApi')) || ''}
showPreset={!(localeData.type === 'api')}
showPreset={localeData.type !== 'api'}
/>
<ModerationContent
title={t('appDebug.feature.moderation.modal.content.output') || ''}
config={localeData.config?.outputs_config || { enabled: false, preset_response: '' }}
onConfigChange={config => handleDataContentChange('outputs_config', config)}
info={(localeData.type === 'api' && t('appDebug.feature.moderation.modal.content.fromApi')) || ''}
showPreset={!(localeData.type === 'api')}
showPreset={localeData.type !== 'api'}
/>
<div className='mb-8 mt-1 text-xs font-medium text-text-tertiary'>{t('appDebug.feature.moderation.modal.content.condition')}</div>
<div className='flex items-center justify-end'>

View File

@ -128,7 +128,7 @@ const CodeBlock: any = memo(({ inline, className, children, ...props }: any) =>
try {
return JSON.parse(String(children).replace(/\n$/, ''))
}
catch (error) { }
catch { }
}
return JSON.parse('{"title":{"text":"ECharts error - Wrong JSON format."}}')
}, [language, children])

View File

@ -1,6 +0,0 @@
.default-page-icon {
width: 20px;
height: 20px;
background: url(../notion-page-selector/assets/notion-page.svg) center center no-repeat;
background-size: cover;
}

View File

@ -1,4 +1,4 @@
import s from './index.module.css'
import { RiFileTextLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import type { DataSourceNotionPage } from '@/models/common'
@ -51,7 +51,7 @@ const NotionIcon = ({
}
return (
<div className={cn(s['default-page-icon'], className)} />
<RiFileTextLine className={cn('h-5 w-5 text-text-tertiary', className)} />
)
}

View File

@ -47,7 +47,7 @@ const WorkflowVariableBlockReplacementBlock = ({
}
}, [])
const transformListener = useCallback((textNode: any) => {
const transformListener = useCallback((textNode: CustomTextNode) => {
resetReg()
return decoratorTransform(textNode, getMatch, createWorkflowVariableBlockNode)
}, [createWorkflowVariableBlockNode, getMatch])

View File

@ -51,7 +51,7 @@ export const SVGRenderer = ({ content }: { content: string }) => {
setImagePreview(svgToDataURL(svgElement as Element))
})
}
catch (error) {
catch {
if (svgRef.current)
svgRef.current.innerHTML = '<span style="padding: 1rem;">Error rendering SVG. Wait for the image content to complete.</span>'
}

View File

@ -48,7 +48,7 @@ const TagManagementModal = ({ show, type }: TagManagementModalProps) => {
setName('')
setPending(false)
}
catch (e: any) {
catch {
notify({ type: 'error', message: t('common.tag.failed') })
setPending(false)
}

View File

@ -73,7 +73,7 @@ const Panel = (props: PanelProps) => {
setCreating(false)
onCreate()
}
catch (e: any) {
catch {
notify({ type: 'error', message: t('common.tag.failed') })
setCreating(false)
}
@ -83,7 +83,7 @@ const Panel = (props: PanelProps) => {
await bindTag(tagIDs, targetID, type)
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
}
catch (e: any) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
}
@ -92,7 +92,7 @@ const Panel = (props: PanelProps) => {
await unBindTag(tagID, targetID, type)
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
}
catch (e: any) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
}

View File

@ -59,7 +59,7 @@ const TagItemEditor: FC<TagItemEditorProps> = ({
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
setName(name)
}
catch (e: any) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
setName(tag.name)
const recoverList = tagList.map((tag) => {
@ -92,7 +92,7 @@ const TagItemEditor: FC<TagItemEditorProps> = ({
])
setPending(false)
}
catch (e: any) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
setPending(false)
}

View File

@ -1,3 +1,4 @@
import type { ReactNode } from 'react'
import React from 'react'
import { act, render, screen, waitFor } from '@testing-library/react'
import Toast, { ToastProvider, useToastContext } from '.'
@ -80,7 +81,7 @@ describe('Toast', () => {
const CustomToastContext = React.createContext({ notify: noop, close: undefined })
// Create a wrapper component using the custom context
const Wrapper = ({ children }: any) => (
const Wrapper = ({ children }: { children: ReactNode }) => (
<CustomToastContext.Provider value={{ notify: noop, close: undefined }}>
{children}
</CustomToastContext.Provider>

View File

@ -111,7 +111,7 @@ const VoiceInput = ({
onConverted(audioResponse.text)
onCancel()
}
catch (e) {
catch {
onConverted('')
onCancel()
}
@ -125,7 +125,7 @@ const VoiceInput = ({
if (canvasRef.current && ctxRef.current)
drawRecord()
}
catch (e) {
catch {
onCancel()
}
}

View File

@ -30,7 +30,7 @@ try {
localStorage = globalThis.localStorage
sessionStorage = globalThis.sessionStorage
}
catch (e) {
catch {
localStorage = new StorageMock()
sessionStorage = new StorageMock()
}

View File

@ -1,8 +1,6 @@
import React from 'react'
type Props = {}
const index = (props: Props) => {
const index = () => {
return (
<div>index</div>
)

View File

@ -184,7 +184,7 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
await sleep(2500)
await startQueryStatus()
}
catch (e) {
catch {
await sleep(2500)
await startQueryStatus()
}

View File

@ -40,7 +40,7 @@ const EmptyDatasetCreationModal = ({
onHide()
router.push(`/datasets/${dataset.id}/documents`)
}
catch (err) {
catch {
notify({ type: 'error', message: t('datasetCreation.stepOne.modal.failed') })
}
}

View File

@ -29,7 +29,7 @@
.previewContent .loading {
width: 100%;
height: 180px;
background: #f9fafb center no-repeat url(../assets/Loading.svg);
background: transparent center no-repeat url(../assets/Loading.svg);
background-size: contain;
}

View File

@ -2,6 +2,7 @@
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { XMarkIcon } from '@heroicons/react/20/solid'
import Loading from '@/app/components/base/loading'
import s from './index.module.css'
import cn from '@/utils/classnames'
import type { CustomFile as File } from '@/models/datasets'
@ -57,7 +58,7 @@ const FilePreview = ({
</div>
</div>
<div className={cn(s.previewContent)}>
{loading && <div className={cn(s.loading)} />}
{loading && <Loading type='area' />}
{!loading && (
<div className={cn(s.fileContent, 'body-md-regular')}>{previewContent}</div>
)}

View File

@ -2,6 +2,7 @@
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { XMarkIcon } from '@heroicons/react/20/solid'
import Loading from '@/app/components/base/loading'
import s from './index.module.css'
import cn from '@/utils/classnames'
import type { NotionPage } from '@/models/common'
@ -62,7 +63,7 @@ const NotionPagePreview = ({
</div>
</div>
<div className={cn(s.previewContent, 'body-md-regular')}>
{loading && <div className={cn(s.loading)} />}
{loading && <Loading type='area' />}
{!loading && (
<div className={cn(s.fileContent, 'body-md-regular')}>{previewContent}</div>
)}

View File

@ -60,13 +60,6 @@
width: 120px;
}
.dividerLine {
margin: 32px 0;
max-width: 640px;
height: 1px;
background-color: #eaecf0;
}
.notionIcon {
background: var(--color-components-card-bg) center no-repeat url(../assets/notion.svg);
background-size: 24px;

View File

@ -301,7 +301,7 @@ const StepOne = ({
)}
{!datasetId && (
<>
<div className={s.dividerLine} />
<div className='my-8 h-px max-w-[640px] bg-divider-regular' />
<span className="inline-flex cursor-pointer items-center text-[13px] leading-4 text-text-accent" onClick={modalShowHandle}>
<RiFolder6Line className="mr-1 size-4" />
{t('datasetCreation.stepOne.emptyDatasetCreation')}

View File

@ -130,7 +130,7 @@ const JinaReader: FC<Props> = ({
},
}
}
}, [crawlOptions.limit])
}, [crawlOptions.limit, onCheckedCrawlResultChange])
const handleRun = useCallback(async (url: string) => {
const { isValid, errorMsg } = checkValid(url)
@ -186,7 +186,7 @@ const JinaReader: FC<Props> = ({
finally {
setStep(Step.finished)
}
}, [checkValid, crawlOptions, onJobIdChange, t, waitForCrawlFinished])
}, [checkValid, crawlOptions, onCheckedCrawlResultChange, onJobIdChange, t, waitForCrawlFinished])
return (
<div>

View File

@ -15,6 +15,7 @@ import { RETRIEVE_METHOD } from '@/types/app'
import cn from '@/utils/classnames'
import Divider from '@/app/components/base/divider'
import { ToastContext } from '@/app/components/base/toast'
import type { IndexingStatusResponse } from '@/models/datasets'
import { ProcessMode, type ProcessRuleResponse } from '@/models/datasets'
import type { CommonResponse } from '@/models/common'
import { asyncRunSafe, sleep } from '@/utils'
@ -166,7 +167,7 @@ const EmbeddingDetail: FC<IEmbeddingDetailProps> = ({
const localDatasetId = dstId ?? datasetId
const localDocumentId = docId ?? documentId
const [indexingStatusDetail, setIndexingStatusDetail] = useState<any>(null)
const [indexingStatusDetail, setIndexingStatusDetail] = useState<IndexingStatusResponse | null>(null)
const fetchIndexingStatus = async () => {
const status = await doFetchIndexingStatus({ datasetId: localDatasetId, documentId: localDocumentId })
setIndexingStatusDetail(status)
@ -193,7 +194,7 @@ const EmbeddingDetail: FC<IEmbeddingDetailProps> = ({
await sleep(2500)
await startQueryStatus()
}
catch (e) {
catch {
await sleep(2500)
await startQueryStatus()
}

View File

@ -4,7 +4,7 @@ import React, { useMemo, useState } from 'react'
import { createContext, useContext, useContextSelector } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import { useRouter } from 'next/navigation'
import { RiArrowLeftLine, RiLayoutRight2Line } from '@remixicon/react'
import { RiArrowLeftLine, RiLayoutLeft2Line, RiLayoutRight2Line } from '@remixicon/react'
import { OperationAction, StatusItem } from '../list'
import DocumentPicker from '../../common/document-picker'
import Completed from './completed'
@ -21,7 +21,6 @@ import type { ChunkingMode, ParentMode, ProcessMode } from '@/models/datasets'
import { useDatasetDetailContext } from '@/context/dataset-detail'
import FloatRightContainer from '@/app/components/base/float-right-container'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { LayoutRight2LineMod } from '@/app/components/base/icons/src/public/knowledge'
import { useCheckSegmentBatchImportProgress, useChildSegmentListKey, useSegmentBatchImport, useSegmentListKey } from '@/service/knowledge/use-segment'
import { useDocumentDetail, useDocumentMetadata, useInvalidDocumentList } from '@/service/knowledge/use-document'
import { useInvalid } from '@/service/use-base'
@ -135,7 +134,7 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
params: { metadata: 'without' },
})
const { data: documentMetadata, error: metadataErr, refetch: metadataMutate } = useDocumentMetadata({
const { data: documentMetadata } = useDocumentMetadata({
datasetId,
documentId,
params: { metadata: 'only' },
@ -146,7 +145,6 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
}
const isDetailLoading = !documentDetail && !error
const isMetadataLoading = !documentMetadata && !metadataErr
const embedding = ['queuing', 'indexing', 'paused'].includes((documentDetail?.display_status || '').toLowerCase())
@ -251,7 +249,7 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
>
{
showMetadata
? <LayoutRight2LineMod className='h-4 w-4 text-components-button-secondary-text' />
? <RiLayoutLeft2Line className='h-4 w-4 text-components-button-secondary-text' />
: <RiLayoutRight2Line className='h-4 w-4 text-components-button-secondary-text' />
}
</button>

View File

@ -14,7 +14,7 @@ const ChildChunks: FC<Props> = ({
payload,
isShowAll,
}) => {
const { id, score, content, position } = payload
const { score, content, position } = payload
return (
<div
className={!isShowAll ? 'line-clamp-2 break-all' : ''}

View File

@ -1,3 +1,4 @@
import type { ChangeEvent } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
@ -13,7 +14,6 @@ import type { ExternalKnowledgeBaseHitTestingResponse, HitTestingResponse } from
import { externalKnowledgeBaseHitTesting, hitTesting } from '@/service/datasets'
import { asyncRunSafe } from '@/utils'
import { RETRIEVE_METHOD, type RetrievalConfig } from '@/types/app'
import promptS from '@/app/components/app/configuration/config-prompt/style.module.css'
type TextAreaWithButtonIProps = {
datasetId: string
@ -59,7 +59,7 @@ const TextAreaWithButton = ({
setIsSettingsOpen(false)
}
function handleTextChange(event: any) {
function handleTextChange(event: ChangeEvent<HTMLTextAreaElement>) {
setText(event.target.value)
}
@ -107,7 +107,7 @@ const TextAreaWithButton = ({
const icon = <Image className='size-3.5 text-util-colors-purple-purple-600' src={getIcon(retrievalMethod)} alt='' />
return (
<>
<div className={cn('relative rounded-xl', promptS.gradientBorder)}>
<div className={cn('relative rounded-xl bg-gradient-to-r from-components-input-border-active-prompt-1 to-components-input-border-active-prompt-2 p-0.5 shadow-xs')}>
<div className='relative rounded-t-xl bg-background-section-burn pt-1.5'>
<div className="flex h-8 items-center justify-between pb-1 pl-4 pr-1.5">
<span className="text-[13px] font-semibold uppercase leading-4 text-text-secondary">

View File

@ -57,7 +57,7 @@ const InfoGroup: FC<Props> = ({
}
return (
<div className={cn('bg-white', className)}>
<div className={cn(className)}>
{!noHeader && (
<div className='flex items-center justify-between'>
<div className='flex items-center space-x-1'>

View File

@ -55,7 +55,7 @@ const RenameDatasetModal = ({ show, dataset, onSuccess, onClose }: RenameDataset
onSuccess()
onClose()
}
catch (e) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
finally {

View File

@ -160,7 +160,7 @@ const Form = () => {
mutate(unstable_serialize(getKey))
}
}
catch (e) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
finally {

View File

@ -114,17 +114,17 @@ const PermissionSelector = ({ disabled, permission, value, memberList, onChange,
<PortalToFollowElemContent className='z-[1002]'>
<div className='relative w-[480px] rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg backdrop-blur-sm'>
<div className='p-1'>
<div className='cursor-pointer rounded-lg py-1 pl-3 pr-2 hover:bg-gray-50' onClick={() => {
<div className='cursor-pointer rounded-lg py-1 pl-3 pr-2 hover:bg-state-base-hover' onClick={() => {
onChange(DatasetPermission.onlyMe)
setOpen(false)
}}>
<div className='flex items-center gap-2'>
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className='mr-2 shrink-0' size={24} />
<div className='mr-2 grow text-sm leading-5 text-gray-900'>{t('datasetSettings.form.permissionsOnlyMe')}</div>
<div className='mr-2 grow text-sm leading-5 text-text-primary'>{t('datasetSettings.form.permissionsOnlyMe')}</div>
{isOnlyMe && <Check className='h-4 w-4 text-primary-600' />}
</div>
</div>
<div className='cursor-pointer rounded-lg py-1 pl-3 pr-2 hover:bg-gray-50' onClick={() => {
<div className='cursor-pointer rounded-lg py-1 pl-3 pr-2 hover:bg-state-base-hover' onClick={() => {
onChange(DatasetPermission.allTeamMembers)
setOpen(false)
}}>
@ -132,11 +132,11 @@ const PermissionSelector = ({ disabled, permission, value, memberList, onChange,
<div className='mr-2 flex h-6 w-6 items-center justify-center rounded-lg bg-[#EEF4FF]'>
<Users01 className='h-3.5 w-3.5 text-[#444CE7]' />
</div>
<div className='mr-2 grow text-sm leading-5 text-gray-900'>{t('datasetSettings.form.permissionsAllMember')}</div>
<div className='mr-2 grow text-sm leading-5 text-text-primary'>{t('datasetSettings.form.permissionsAllMember')}</div>
{isAllTeamMembers && <Check className='h-4 w-4 text-primary-600' />}
</div>
</div>
<div className='cursor-pointer rounded-lg py-1 pl-3 pr-2 hover:bg-gray-50' onClick={() => {
<div className='cursor-pointer rounded-lg py-1 pl-3 pr-2 hover:bg-state-base-hover' onClick={() => {
onChange(DatasetPermission.partialMembers)
onMemberSelect([userProfile.id])
}}>
@ -144,14 +144,14 @@ const PermissionSelector = ({ disabled, permission, value, memberList, onChange,
<div className={cn('mr-2 flex h-6 w-6 items-center justify-center rounded-lg bg-[#FFF6ED]', isPartialMembers && '!bg-[#EEF4FF]')}>
<UsersPlus className={cn('h-3.5 w-3.5 text-[#FB6514]', isPartialMembers && '!text-[#444CE7]')} />
</div>
<div className='mr-2 grow text-sm leading-5 text-gray-900'>{t('datasetSettings.form.permissionsInvitedMembers')}</div>
<div className='mr-2 grow text-sm leading-5 text-text-primary'>{t('datasetSettings.form.permissionsInvitedMembers')}</div>
{isPartialMembers && <Check className='h-4 w-4 text-primary-600' />}
</div>
</div>
</div>
{isPartialMembers && (
<div className='max-h-[360px] overflow-y-auto border-t-[1px] border-gray-100 p-1'>
<div className='sticky left-0 top-0 bg-white p-2 pb-1'>
<div className='max-h-[360px] overflow-y-auto border-t-[1px] border-divider-regular p-1'>
<div className='sticky left-0 top-0 p-2 pb-1'>
<Input
showLeftIcon
showClearIcon

View File

@ -148,7 +148,7 @@ const Apps = ({
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
getRedirection(isCurrentWorkspaceEditor, { id: app.app_id!, mode }, push)
}
catch (e) {
catch {
Toast.notify({ type: 'error', message: t('app.newApp.appCreateFailed') })
}
}

View File

@ -14,10 +14,7 @@ type IAccountSettingProps = {
langeniusVersionInfo: LangGeniusVersionResponse
onCancel: () => void
}
const buttonClassName = `
shrink-0 flex items-center h-8 px-3 rounded-lg border border-gray-200
text-xs text-gray-800 font-medium
`
export default function AccountAbout({
langeniusVersionInfo,
onCancel,

View File

@ -24,7 +24,7 @@ const WorkplaceSelector = () => {
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
location.assign(`${location.origin}`)
}
catch (e) {
catch {
notify({ type: 'error', message: t('common.provider.saveFailed') })
}
}

View File

@ -1,12 +1,10 @@
import useSWR from 'swr'
import { useTranslation } from 'react-i18next'
import DataSourceNotion from './data-source-notion'
import DataSourceWebsite from './data-source-website'
import { fetchDataSource } from '@/service/common'
import { DataSourceProvider } from '@/models/common'
export default function DataSourcePage() {
const { t } = useTranslation()
const { data } = useSWR({ url: 'data-source/integrates' }, fetchDataSource)
const notionWorkspaces = data?.data.filter(item => item.provider === 'notion') || []

View File

@ -21,7 +21,7 @@ const EditWorkspaceModal = ({
}: IEditWorkspaceModalProps) => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const { currentWorkspace, isCurrentWorkspaceOwner, mutateCurrentWorkspace } = useAppContext()
const { currentWorkspace, isCurrentWorkspaceOwner } = useAppContext()
const [name, setName] = useState<string>(currentWorkspace.name)
const changeWorkspaceInfo = async (name: string) => {
@ -35,7 +35,7 @@ const EditWorkspaceModal = ({
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
location.assign(`${location.origin}`)
}
catch (e) {
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
}
}

View File

@ -49,7 +49,7 @@ const InviteModal = ({
onSend(invitation_results)
}
}
catch (e) { }
catch { }
}
else {
notify({ type: 'error', message: t('common.members.emailInvalid') })

View File

@ -53,7 +53,7 @@ const Operation = ({
onOperate()
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
}
catch (e) {
catch {
}
}
@ -66,7 +66,7 @@ const Operation = ({
onOperate()
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
}
catch (e) {
catch {
}
}

View File

@ -50,10 +50,7 @@ jest.mock('@/app/components/plugins/marketplace/utils', () => ({
getMarketplacePluginsByCollectionId: jest.fn(),
}))
jest.mock('./provider-added-card', () => {
// eslint-disable-next-line no-labels, ts/no-unused-expressions
UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST: []
})
jest.mock('./provider-added-card', () => jest.fn())
after(() => {
jest.resetModules()

View File

@ -85,7 +85,6 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({
renderTrigger,
readonly,
isInWorkflow,
scope = 'text-generation',
}) => {
const { t } = useTranslation()
const { isAPIKeySet } = useProviderContext()

View File

@ -37,7 +37,7 @@ const ParameterItem: FC<ParameterItemProps> = ({
if (parameterRule.type === 'int' || parameterRule.type === 'float')
defaultValue = isNullOrUndefined(parameterRule.default) ? (parameterRule.min || 0) : parameterRule.default
else if (parameterRule.type === 'string' || parameterRule.type === 'text')
defaultValue = parameterRule.options?.length ? (parameterRule.default || '') : (parameterRule.default || '')
defaultValue = parameterRule.default || ''
else if (parameterRule.type === 'boolean')
defaultValue = !isNullOrUndefined(parameterRule.default) ? parameterRule.default : false
else if (parameterRule.type === 'tag')
@ -132,8 +132,6 @@ const ParameterItem: FC<ParameterItemProps> = ({
step = 1
else if (parameterRule.max < 1000)
step = 10
else if (parameterRule.max < 10000)
step = 100
}
return (

View File

@ -102,7 +102,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ updatePayload, on
})
}
}
catch (error) {
catch {
Toast.notify({
type: 'error',
message: t('plugin.error.fetchReleasesError'),

View File

@ -1,6 +1,6 @@
'use client'
import type { FC } from 'react'
import React, { useEffect } from 'react'
import React, { useEffect, useMemo } from 'react'
import { type PluginDeclaration, TaskStatus } from '../../../types'
import Card from '../../../card'
import { pluginManifestToCardPluginProps } from '../../utils'
@ -12,6 +12,8 @@ import { useInstallPackageFromLocal, usePluginTaskList } from '@/service/use-plu
import useCheckInstalled from '@/app/components/plugins/install-plugin/hooks/use-check-installed'
import { uninstallPlugin } from '@/service/plugins'
import Version from '../../base/version'
import { useAppContext } from '@/context/app-context'
import { gte } from 'semver'
const i18nPrefix = 'plugin.installModal'
@ -103,6 +105,13 @@ const Installed: FC<Props> = ({
}
}
const { langeniusVersionInfo } = useAppContext()
const isDifyVersionCompatible = useMemo(() => {
if (!langeniusVersionInfo.current_version)
return true
return gte(langeniusVersionInfo.current_version, payload.meta.minimum_dify_version ?? '0.0.0')
}, [langeniusVersionInfo.current_version, payload.meta.minimum_dify_version])
return (
<>
<div className='flex flex-col items-start justify-center gap-4 self-stretch px-6 py-3'>
@ -114,6 +123,11 @@ const Installed: FC<Props> = ({
components={{ trustSource: <span className='system-md-semibold' /> }}
/>
</p>
{!isDifyVersionCompatible && (
<p className='system-md-regular flex items-center gap-1 text-text-secondary text-text-warning'>
{t('plugin.difyVersionNotCompatible', { minimalDifyVersion: payload.meta.minimum_dify_version })}
</p>
)}
</div>
<div className='flex flex-wrap content-start items-start gap-1 self-stretch rounded-2xl bg-background-section-burn p-2'>
<Card

View File

@ -1,6 +1,6 @@
'use client'
import type { FC } from 'react'
import React, { useEffect } from 'react'
import React, { useEffect, useMemo } from 'react'
// import { RiInformation2Line } from '@remixicon/react'
import { type Plugin, type PluginManifestInMarket, TaskStatus } from '../../../types'
import Card from '../../../card'
@ -8,11 +8,13 @@ import { pluginManifestInMarketToPluginProps } from '../../utils'
import Button from '@/app/components/base/button'
import { useTranslation } from 'react-i18next'
import { RiLoader2Line } from '@remixicon/react'
import { useInstallPackageFromMarketPlace, useUpdatePackageFromMarketPlace } from '@/service/use-plugins'
import { useInstallPackageFromMarketPlace, usePluginDeclarationFromMarketPlace, useUpdatePackageFromMarketPlace } from '@/service/use-plugins'
import checkTaskStatus from '../../base/check-task-status'
import useCheckInstalled from '@/app/components/plugins/install-plugin/hooks/use-check-installed'
import Version from '../../base/version'
import { usePluginTaskList } from '@/service/use-plugins'
import { gte } from 'semver'
import { useAppContext } from '@/context/app-context'
const i18nPrefix = 'plugin.installModal'
@ -117,11 +119,23 @@ const Installed: FC<Props> = ({
}
}
const { langeniusVersionInfo } = useAppContext()
const { data: pluginDeclaration } = usePluginDeclarationFromMarketPlace(uniqueIdentifier)
const isDifyVersionCompatible = useMemo(() => {
if (!pluginDeclaration || !langeniusVersionInfo.current_version) return true
return gte(langeniusVersionInfo.current_version, pluginDeclaration?.manifest.meta.minimum_dify_version ?? '0.0.0')
}, [langeniusVersionInfo.current_version, pluginDeclaration?.manifest.meta.minimum_dify_version])
return (
<>
<div className='flex flex-col items-start justify-center gap-4 self-stretch px-6 py-3'>
<div className='system-md-regular text-text-secondary'>
<p>{t(`${i18nPrefix}.readyToInstall`)}</p>
{!isDifyVersionCompatible && (
<p className='system-md-regular text-text-secondary text-text-warning'>
{t('plugin.difyVersionNotCompatible', { minimalDifyVersion: pluginDeclaration?.manifest.meta.minimum_dify_version })}
</p>
)}
</div>
<div className='flex flex-wrap content-start items-start gap-1 self-stretch rounded-2xl bg-background-section-burn p-2'>
<Card

View File

@ -46,7 +46,6 @@ const CardWrapper = ({
}
/>
{
showInstallButton && (
<div className='absolute bottom-0 hidden w-full items-center space-x-2 rounded-b-xl bg-gradient-to-tr from-components-panel-on-panel-item-bg to-background-gradient-mask-transparent px-4 pb-4 pt-8 group-hover:flex'>
<Button
variant='primary'
@ -64,12 +63,11 @@ const CardWrapper = ({
</Button>
</a>
</div>
)
}
{
isShowInstallFromMarketplace && (
<InstallFromMarketplace
manifest={plugin as any}
manifest={plugin}
uniqueIdentifier={plugin.latest_package_identifier}
onClose={hideInstallFromMarketplace}
onSuccess={hideInstallFromMarketplace}

View File

@ -108,7 +108,7 @@ const EndpointCard = ({
Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
},
})
const handleUpdate = (state: any) => updateEndpoint({
const handleUpdate = (state: Record<string, any>) => updateEndpoint({
endpointID,
state,
})

View File

@ -55,7 +55,7 @@ const EndpointList = ({ detail }: Props) => {
},
})
const handleCreate = (state: any) => createEndpoint({
const handleCreate = (state: Record<string, any>) => createEndpoint({
pluginUniqueID,
state,
})

View File

@ -125,11 +125,12 @@ const ToolSelector: FC<Props> = ({
type: tool.provider_type,
tool_name: tool.tool_name,
tool_label: tool.tool_label,
tool_description: tool.tool_description,
settings: settingValues,
parameters: paramValues,
enabled: tool.is_team_authorization,
extra: {
description: '',
description: tool.tool_description,
},
schemas: tool.paramSchemas,
}

View File

@ -245,7 +245,7 @@ const ReasoningConfigForm: React.FC<Props> = ({
popupClassName='!w-[387px]'
isAdvancedMode
isInWorkflow
value={varInput as any}
value={varInput}
setModel={handleModelChange(variable)}
scope={scope}
/>

Some files were not shown because too many files have changed in this diff Show More