diff --git a/docSite/content/zh-cn/docs/development/upgrading/4912.md b/docSite/content/zh-cn/docs/development/upgrading/4912.md index 79b0dfe43..44ccdb435 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4912.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4912.md @@ -14,6 +14,8 @@ weight: 788 3. 问题分类和内容提取,提示词中自动加入上一轮结果进行额外引导。 4. 判断器支持变量引用。 5. 商业版支持知识库分块时,LLM 进行自动分段识别。 +6. Admin 管理员数据看板。 +7. 豆包 1.6 系列模型,更新 qwen 模型配置。 ## ⚙️ 优化 @@ -25,6 +27,7 @@ weight: 788 6. MCP 工具调用,使用 Raw schema 进行工具调用,保障完整性。 7. 删除知识库文件时,如果文件不存在,不会阻断删除。 8. 升级 MCP SDK,兼容最新的 HTTPStreamable。 +9. 语雀文档库,递归获取文档类型目录下的数据。 ## 🐛 修复 diff --git a/packages/service/core/ai/config/provider/Doubao.json b/packages/service/core/ai/config/provider/Doubao.json index f28633bfb..12a2cd685 100644 --- a/packages/service/core/ai/config/provider/Doubao.json +++ b/packages/service/core/ai/config/provider/Doubao.json @@ -1,6 +1,72 @@ { "provider": "Doubao", "list": [ + { + "model": "Doubao-Seed-1.6", + "name": "Doubao-Seed-1.6", + "maxContext": 220000, + "maxResponse": 16000, + "quoteMaxToken": 220000, + "maxTemperature": 1, + "showTopP": true, + "showStopSign": true, + "vision": true, + "toolChoice": true, + "functionCall": false, + "defaultSystemChatPrompt": "", + "datasetProcess": true, + "usedInClassify": true, + "usedInExtractFields": true, + "usedInQueryExtension": true, + "usedInToolCall": true, + "defaultConfig": {}, + "fieldMap": {}, + "type": "llm" + }, + { + "model": "Doubao-Seed-1.6-thinking", + "name": "Doubao-Seed-1.6-thinking", + "maxContext": 220000, + "maxResponse": 16000, + "quoteMaxToken": 220000, + "maxTemperature": 1, + "showTopP": true, + "showStopSign": true, + "vision": true, + "toolChoice": true, + "functionCall": false, + "defaultSystemChatPrompt": "", + "datasetProcess": true, + "usedInClassify": true, + "usedInExtractFields": true, + "usedInQueryExtension": true, + "usedInToolCall": true, + "defaultConfig": {}, + "fieldMap": {}, + "type": "llm" + }, + { + "model": "Doubao-Seed-1.6-flash", + "name": "Doubao-Seed-1.6-flash", + "maxContext": 220000, + "maxResponse": 16000, + "quoteMaxToken": 220000, + "maxTemperature": 1, + "showTopP": true, + "showStopSign": true, + "vision": true, + "toolChoice": true, + "functionCall": false, + "defaultSystemChatPrompt": "", + "datasetProcess": true, + "usedInClassify": true, + "usedInExtractFields": true, + "usedInQueryExtension": true, + "usedInToolCall": true, + "defaultConfig": {}, + "fieldMap": {}, + "type": "llm" + }, { "model": "Doubao-1.5-lite-32k", "name": "Doubao-1.5-lite-32k", diff --git a/packages/service/core/ai/config/provider/Qwen.json b/packages/service/core/ai/config/provider/Qwen.json index adab15ebb..e16b76a22 100644 --- a/packages/service/core/ai/config/provider/Qwen.json +++ b/packages/service/core/ai/config/provider/Qwen.json @@ -4,9 +4,9 @@ { "model": "qwen-max", "name": "Qwen-max", - "maxContext": 32000, - "maxResponse": 4000, - "quoteMaxToken": 6000, + "maxContext": 128000, + "maxResponse": 8000, + "quoteMaxToken": 120000, "maxTemperature": 1, "vision": false, "toolChoice": true, @@ -27,10 +27,10 @@ { "model": "qwen-vl-max", "name": "qwen-vl-max", - "maxContext": 32000, - "maxResponse": 2000, - "quoteMaxToken": 20000, - "maxTemperature": 1.2, + "maxContext": 128000, + "maxResponse": 8000, + "quoteMaxToken": 120000, + "maxTemperature": 1, "vision": true, "toolChoice": false, "functionCall": false, @@ -49,9 +49,9 @@ { "model": "qwen-plus", "name": "Qwen-plus", - "maxContext": 64000, + "maxContext": 128000, "maxResponse": 8000, - "quoteMaxToken": 60000, + "quoteMaxToken": 120000, "maxTemperature": 1, "vision": false, "toolChoice": true, @@ -72,10 +72,10 @@ { "model": "qwen-vl-plus", "name": "qwen-vl-plus", - "maxContext": 32000, - "maxResponse": 2000, - "quoteMaxToken": 20000, - "maxTemperature": 1.2, + "maxContext": 128000, + "maxResponse": 8000, + "quoteMaxToken": 120000, + "maxTemperature": 1, "vision": true, "toolChoice": false, "functionCall": false, @@ -92,9 +92,9 @@ { "model": "qwen-turbo", "name": "Qwen-turbo", - "maxContext": 128000, + "maxContext": 1000000, "maxResponse": 8000, - "quoteMaxToken": 100000, + "quoteMaxToken": 1000000, "maxTemperature": 1, "vision": false, "toolChoice": true, @@ -487,9 +487,9 @@ { "model": "qwen-long", "name": "qwen-long", - "maxContext": 100000, + "maxContext": 10000000, "maxResponse": 6000, - "quoteMaxToken": 10000, + "quoteMaxToken": 10000000, "maxTemperature": 1, "vision": false, "toolChoice": false, diff --git a/packages/service/core/dataset/apiDataset/custom/api.ts b/packages/service/core/dataset/apiDataset/custom/api.ts index d0a9810a7..eb98ecebb 100644 --- a/packages/service/core/dataset/apiDataset/custom/api.ts +++ b/packages/service/core/dataset/apiDataset/custom/api.ts @@ -106,7 +106,7 @@ export const useApiDatasetRequest = ({ apiServer }: { apiServer: APIFileServer } const formattedFiles = files.map((file) => ({ ...file, - hasChild: file.type === 'folder' + hasChild: file.hasChild ?? file.type === 'folder' })); return formattedFiles; diff --git a/packages/service/core/dataset/apiDataset/yuqueDataset/api.ts b/packages/service/core/dataset/apiDataset/yuqueDataset/api.ts index c0e76de1f..9ddcaf4be 100644 --- a/packages/service/core/dataset/apiDataset/yuqueDataset/api.ts +++ b/packages/service/core/dataset/apiDataset/yuqueDataset/api.ts @@ -198,6 +198,7 @@ export const useYuqueDatasetRequest = ({ yuqueServer }: { yuqueServer: YuqueServ }: { apiFileId: string; }): Promise => { + if (typeof apiFileId !== 'string') return Promise.reject('Invalid file id'); const [parentId, fileId] = apiFileId.split(/-(.*?)-(.*)/); const data = await request<{ title: string; body: string }>( diff --git a/packages/service/core/dataset/read.ts b/packages/service/core/dataset/read.ts index bd7d43f9b..be50d9d90 100644 --- a/packages/service/core/dataset/read.ts +++ b/packages/service/core/dataset/read.ts @@ -167,7 +167,7 @@ export const readApiServerFileContent = async ({ }; export const rawText2Chunks = async ({ - rawText, + rawText = '', chunkTriggerType = ChunkTriggerConfigTypeEnum.minSize, chunkTriggerMinSize = 1000, backupParse, diff --git a/projects/app/src/pageComponents/account/model/ModelDashboard/DataTableComponent.tsx b/projects/app/src/pageComponents/account/model/ModelDashboard/DataTableComponent.tsx index 89201021f..0bc4526c2 100644 --- a/projects/app/src/pageComponents/account/model/ModelDashboard/DataTableComponent.tsx +++ b/projects/app/src/pageComponents/account/model/ModelDashboard/DataTableComponent.tsx @@ -140,7 +140,7 @@ const DataTableComponent = ({ model: item.model, totalCalls: item.totalCalls, errorCalls: item.errorCalls, - totalCost: item.totalCost, + totalCost: Math.floor(item.totalCost), avgResponseTime: successCalls > 0 ? item.totalResponseTime / successCalls / 1000 : 0, avgTtfb: successCalls > 0 ? item.totalTtfb / successCalls / 1000 : 0 }); @@ -201,7 +201,7 @@ const DataTableComponent = ({ model: modelName, totalCalls: item.totalCalls, errorCalls: item.errorCalls, - totalCost: item.totalCost, + totalCost: Math.floor(item.totalCost), avgResponseTime: successCalls > 0 ? item.totalResponseTime / successCalls / 1000 : 0, avgTtfb: successCalls > 0 ? item.totalTtfb / successCalls / 1000 : 0 }); diff --git a/projects/app/src/pageComponents/account/model/ModelDashboard/index.tsx b/projects/app/src/pageComponents/account/model/ModelDashboard/index.tsx index d5e1aa60d..f5080edf7 100644 --- a/projects/app/src/pageComponents/account/model/ModelDashboard/index.tsx +++ b/projects/app/src/pageComponents/account/model/ModelDashboard/index.tsx @@ -349,7 +349,7 @@ const ModelDashboard = ({ Tab }: { Tab: React.ReactNode }) => { inputTokens, outputTokens, totalTokens, - totalCost, + totalCost: Math.floor(totalCost), avgResponseTime: Math.round(avgResponseTime * 100) / 100, avgTtfb: Math.round(avgTtfb * 100) / 100, maxRpm, diff --git a/projects/app/src/pageComponents/dataset/detail/Import/diffSource/APIDataset.tsx b/projects/app/src/pageComponents/dataset/detail/Import/diffSource/APIDataset.tsx index 2ac688ad9..340217773 100644 --- a/projects/app/src/pageComponents/dataset/detail/Import/diffSource/APIDataset.tsx +++ b/projects/app/src/pageComponents/dataset/detail/Import/diffSource/APIDataset.tsx @@ -70,8 +70,10 @@ const CustomAPIFileInput = () => { } ); - const { data: existIdList = [] } = useRequest2( - () => getApiDatasetFileListExistId({ datasetId: datasetDetail._id }), + const { data: existIdList = new Set() } = useRequest2( + async () => { + return new Set(await getApiDatasetFileListExistId({ datasetId: datasetDetail._id })); + }, { manual: false } @@ -89,7 +91,12 @@ const CustomAPIFileInput = () => { const allFiles: APIFileItem[] = []; for (const file of files) { - if (file.type === 'folder') { + if (sources.some((item) => item.apiFileId === file.id)) { + allFiles.push(file); + continue; + } + + if (file.hasChild) { const folderFiles = await getApiDatasetFileList({ datasetId: datasetDetail._id, parentId: file?.id @@ -97,27 +104,28 @@ const CustomAPIFileInput = () => { const subFiles = await getFilesRecursively(folderFiles); allFiles.push(...subFiles); - } else { - allFiles.push(file); } + allFiles.push(file); } return allFiles; }; const allFiles = await getFilesRecursively(selectFiles); + const uniqueFiles = allFiles.filter( + (item, index, array) => + !existIdList.has(item.id) && array.findIndex((file) => file.id === item.id) === index + ); setSources( - allFiles - .filter((item) => !existIdList.includes(item.id)) - .map((item) => ({ - id: item.id, - apiFileId: item.id, - apiFile: item, - createStatus: 'waiting', - sourceName: item.name, - icon: getSourceNameIcon({ sourceName: item.name }) as any - })) + uniqueFiles.map((item) => ({ + id: item.id, + apiFileId: item.id, + apiFile: item, + createStatus: 'waiting', + sourceName: item.name, + icon: getSourceNameIcon({ sourceName: item.name }) as any + })) ); }, { @@ -147,15 +155,24 @@ const CustomAPIFileInput = () => { [selectFiles] ); - const handleSelectAll = useCallback(() => { - const isAllSelected = fileList.length === selectFiles.length; + const isAllSelected = useMemo(() => { + return fileList.every( + (item) => existIdList.has(item.id) || selectFiles.some((file) => file.id === item.id) + ); + }, [fileList, selectFiles, existIdList]); + const handleSelectAll = useCallback(() => { if (isAllSelected) { - setSelectFiles([]); + setSelectFiles((state) => + state.filter((file) => !fileList.find((item) => item.id === file.id)) + ); } else { - setSelectFiles(fileList); + setSelectFiles((state) => [ + ...state.filter((file) => !fileList.find((item) => item.id === file.id)), + ...fileList.filter((item) => !existIdList.has(item.id)) + ]); } - }, [fileList, selectFiles]); + }, [isAllSelected, fileList, existIdList]); return ( @@ -193,23 +210,22 @@ const CustomAPIFileInput = () => { fontSize={'sm'} fontWeight={'medium'} color={'myGray.900'} - onClick={(e) => { - if (!(e.target as HTMLElement).closest('.checkbox')) { - handleSelectAll(); - } - }} + // onClick={(e) => { + // if (!(e.target as HTMLElement).closest('.checkbox')) { + // handleSelectAll(); + // } + // }} > {t('common:Select_all')} {fileList.map((item) => { - const isFolder = item.type === 'folder'; - const isExists = existIdList.includes(item.id); + const isExists = existIdList.has(item.id); const isChecked = isExists || selectFiles.some((file) => file.id === item.id); return ( @@ -243,9 +259,9 @@ const CustomAPIFileInput = () => { />