From 095b75ee27746004106eddeaa4840688a61ff6eb Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Fri, 13 Jun 2025 00:42:09 +0800 Subject: [PATCH] V4.9.12 feature (#5022) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New chatinput (#4995) * feat: Change border style * refactor: Improve layout and styling of ChatInput component * style: Update ChatInput component styling and mobile layout * fix: update key detection for Enter key in ChatInput component * feat: 添加 WelcomePage 组件,支持变量输入和欢迎信息展示 * style: Updated the PC voice input interface of the VoiceInput component and optimized the layout and style * style: Optimize the layout and style of the WelcomePage component, and adjust the responsive design * feat: Dynamically load the WelcomePage component and optimize the welcome information display logic * refactor: Adjust the style and behavior of the ChatInput component and delete the WelcomePage component * style: Modify the minimum height setting of the ChatInput component to simplify responsive design * style: Optimize the layout and style of PC voice input components, and enhance the processing and drawing logic of waveform data * style: Adjust ChatInput component's margin and textarea height logic for improved layout and responsiveness; refine PCVoiceInput component's positioning and display elements * style: Enhance PCVoiceInput component's time display styling with custom font properties * feat: Change border style * refactor: Improve layout and styling of ChatInput component * style: Update ChatInput component styling and mobile layout * fix: update key detection for Enter key in ChatInput component * feat: 添加 WelcomePage 组件,支持变量输入和欢迎信息展示 * style: Updated the PC voice input interface of the VoiceInput component and optimized the layout and style * style: Optimize the layout and style of the WelcomePage component, and adjust the responsive design * feat: Dynamically load the WelcomePage component and optimize the welcome information display logic * refactor: Adjust the style and behavior of the ChatInput component and delete the WelcomePage component * style: Modify the minimum height setting of the ChatInput component to simplify responsive design * style: Optimize the layout and style of PC voice input components, and enhance the processing and drawing logic of waveform data * style: Adjust ChatInput component's margin and textarea height logic for improved layout and responsiveness; refine PCVoiceInput component's positioning and display elements * style: Enhance PCVoiceInput component's time display styling with custom font properties * style: Add new 'xxl' size to theme spacing for improved layout options * style: Update close icon fill color to use currentColor for better theming support * style: Enhance voice input functionality and UI responsiveness; improve waveform sensitivity and amplitude * style: Conditionally render file preview based on voice input state * style: 优化移动端音频波形渲染,增强清晰度和敏感度 * style: Update comments to English to enhance code readability and consistency * style: Adjust the mobile audio waveform update frequency and optimize rendering performance * style: Optimize the file preview rendering logic in voice input mode to enhance user experience * style: Optimize the file preview rendering logic in voice input mode to enhance user experience * style: Adjust the chat input box placeholder color and border color to enhance visual effects * fix: pg test * Test secret (#5011) * add http header auth config (#4982) * add http header auth config * optimize code * add mcp tools header auth * fix build * fix ui * fix * teamid * secret value encrypt (#5002) * perf: secret code * header auth ui (#5012) * header auth ui * fix i18n * doc * perf: type * header secret ui * reset ui * perf: check secret invalid --------- Co-authored-by: heheer * feat: cq and extrat AI memory (#5013) * fix: login xss * feat: Users can download the invoice by self (#5015) * Users can download the invoice by themselves * Direct file stream implementation for transmission presentation * i18n * Chatbox-fix (#5018) * feat: Change border style * refactor: Improve layout and styling of ChatInput component * style: Update ChatInput component styling and mobile layout * fix: update key detection for Enter key in ChatInput component * feat: 添加 WelcomePage 组件,支持变量输入和欢迎信息展示 * style: Updated the PC voice input interface of the VoiceInput component and optimized the layout and style * style: Optimize the layout and style of the WelcomePage component, and adjust the responsive design * feat: Dynamically load the WelcomePage component and optimize the welcome information display logic * refactor: Adjust the style and behavior of the ChatInput component and delete the WelcomePage component * style: Modify the minimum height setting of the ChatInput component to simplify responsive design * style: Optimize the layout and style of PC voice input components, and enhance the processing and drawing logic of waveform data * style: Adjust ChatInput component's margin and textarea height logic for improved layout and responsiveness; refine PCVoiceInput component's positioning and display elements * style: Enhance PCVoiceInput component's time display styling with custom font properties * feat: Change border style * refactor: Improve layout and styling of ChatInput component * style: Update ChatInput component styling and mobile layout * fix: update key detection for Enter key in ChatInput component * feat: 添加 WelcomePage 组件,支持变量输入和欢迎信息展示 * style: Updated the PC voice input interface of the VoiceInput component and optimized the layout and style * style: Optimize the layout and style of the WelcomePage component, and adjust the responsive design * feat: Dynamically load the WelcomePage component and optimize the welcome information display logic * refactor: Adjust the style and behavior of the ChatInput component and delete the WelcomePage component * style: Modify the minimum height setting of the ChatInput component to simplify responsive design * style: Optimize the layout and style of PC voice input components, and enhance the processing and drawing logic of waveform data * style: Adjust ChatInput component's margin and textarea height logic for improved layout and responsiveness; refine PCVoiceInput component's positioning and display elements * style: Enhance PCVoiceInput component's time display styling with custom font properties * style: Add new 'xxl' size to theme spacing for improved layout options * style: Update close icon fill color to use currentColor for better theming support * style: Enhance voice input functionality and UI responsiveness; improve waveform sensitivity and amplitude * style: Conditionally render file preview based on voice input state * style: 优化移动端音频波形渲染,增强清晰度和敏感度 * style: Update comments to English to enhance code readability and consistency * style: Adjust the mobile audio waveform update frequency and optimize rendering performance * style: Optimize the file preview rendering logic in voice input mode to enhance user experience * style: Optimize the file preview rendering logic in voice input mode to enhance user experience * style: Adjust the chat input box placeholder color and border color to enhance visual effects * New chatinput (#4995) * feat: Change border style * refactor: Improve layout and styling of ChatInput component * style: Update ChatInput component styling and mobile layout * fix: update key detection for Enter key in ChatInput component * feat: 添加 WelcomePage 组件,支持变量输入和欢迎信息展示 * style: Updated the PC voice input interface of the VoiceInput component and optimized the layout and style * style: Optimize the layout and style of the WelcomePage component, and adjust the responsive design * feat: Dynamically load the WelcomePage component and optimize the welcome information display logic * refactor: Adjust the style and behavior of the ChatInput component and delete the WelcomePage component * style: Modify the minimum height setting of the ChatInput component to simplify responsive design * style: Optimize the layout and style of PC voice input components, and enhance the processing and drawing logic of waveform data * style: Adjust ChatInput component's margin and textarea height logic for improved layout and responsiveness; refine PCVoiceInput component's positioning and display elements * style: Enhance PCVoiceInput component's time display styling with custom font properties * feat: Change border style * refactor: Improve layout and styling of ChatInput component * style: Update ChatInput component styling and mobile layout * fix: update key detection for Enter key in ChatInput component * feat: 添加 WelcomePage 组件,支持变量输入和欢迎信息展示 * style: Updated the PC voice input interface of the VoiceInput component and optimized the layout and style * style: Optimize the layout and style of the WelcomePage component, and adjust the responsive design * feat: Dynamically load the WelcomePage component and optimize the welcome information display logic * refactor: Adjust the style and behavior of the ChatInput component and delete the WelcomePage component * style: Modify the minimum height setting of the ChatInput component to simplify responsive design * style: Optimize the layout and style of PC voice input components, and enhance the processing and drawing logic of waveform data * style: Adjust ChatInput component's margin and textarea height logic for improved layout and responsiveness; refine PCVoiceInput component's positioning and display elements * style: Enhance PCVoiceInput component's time display styling with custom font properties * style: Add new 'xxl' size to theme spacing for improved layout options * style: Update close icon fill color to use currentColor for better theming support * style: Enhance voice input functionality and UI responsiveness; improve waveform sensitivity and amplitude * style: Conditionally render file preview based on voice input state * style: 优化移动端音频波形渲染,增强清晰度和敏感度 * style: Update comments to English to enhance code readability and consistency * style: Adjust the mobile audio waveform update frequency and optimize rendering performance * style: Optimize the file preview rendering logic in voice input mode to enhance user experience * style: Optimize the file preview rendering logic in voice input mode to enhance user experience * style: Adjust the chat input box placeholder color and border color to enhance visual effects * fix: pg test * Test secret (#5011) * add http header auth config (#4982) * add http header auth config * optimize code * add mcp tools header auth * fix build * fix ui * fix * teamid * secret value encrypt (#5002) * perf: secret code * header auth ui (#5012) * header auth ui * fix i18n * doc * perf: type * header secret ui * reset ui * perf: check secret invalid --------- Co-authored-by: heheer * feat: cq and extrat AI memory (#5013) * refactor: Refactored the ChatInput component, optimized the layout of the text area and button group, and improved the user experience * refactor: Updated ChatInput component, optimized layout and style, and enhanced user experience * feat: update docs --------- Co-authored-by: archer <545436317@qq.com> Co-authored-by: heheer * input ui * fix: chat input ux * Return in JSON format to handle checkres (#5019) * Users can download the invoice by themselves * Direct file stream implementation for transmission presentation * Return in JSON format to handle checkres * fix: invoice * fix: ui * doc * update package * fix: ts * fix: login checker * fix: team plan * perf: aiproxy ux --------- Co-authored-by: Theresa <63280168+sd0ric4@users.noreply.github.com> Co-authored-by: heheer Co-authored-by: Zhuangzai fa <143257420+ctrlz526@users.noreply.github.com> --- deploy/docker/docker-compose-pgvector.yml | 2 +- .../fastgpt/templates/configmap-config.yaml | 8 - .../development/custom-models/xinference.md | 2 - docSite/content/zh-cn/docs/development/faq.md | 7 +- .../docs/development/modelConfig/intro.md | 10 - .../zh-cn/docs/development/upgrading/4811.md | 2 - .../zh-cn/docs/development/upgrading/4816.md | 1 - .../zh-cn/docs/development/upgrading/4912.md | 10 +- docSite/static/llms-full.txt | 569 +++++++++--------- env.d.ts | 1 + packages/global/common/secret/constants.ts | 8 + packages/global/common/secret/type.d.ts | 6 + packages/global/core/ai/model.d.ts | 3 - packages/global/core/ai/model.ts | 2 - packages/global/core/ai/prompt/agent.ts | 173 ++++-- packages/global/core/app/mcpTools/utils.ts | 17 +- packages/global/core/app/utils.ts | 3 - packages/global/core/chat/type.d.ts | 1 + packages/global/core/workflow/constants.ts | 1 + .../global/core/workflow/runtime/constants.ts | 4 +- .../global/core/workflow/runtime/type.d.ts | 1 + .../template/system/classifyQuestion/index.ts | 6 +- .../core/workflow/template/system/http468.ts | 7 + .../support/wallet/bill/invoice/type.d.ts | 6 + packages/service/common/secret/aes256gcm.ts | 28 + packages/service/common/secret/constants.ts | 1 + packages/service/common/secret/utils.ts | 43 ++ .../core/ai/config/provider/ChatGLM.json | 34 +- .../core/ai/config/provider/Claude.json | 14 - .../core/ai/config/provider/DeepSeek.json | 4 - .../core/ai/config/provider/Doubao.json | 24 - .../core/ai/config/provider/Ernie.json | 10 +- .../core/ai/config/provider/Gemini.json | 20 - .../service/core/ai/config/provider/Grok.json | 8 - .../service/core/ai/config/provider/Groq.json | 6 +- .../core/ai/config/provider/Hunyuan.json | 16 +- .../core/ai/config/provider/Intern.json | 6 +- .../core/ai/config/provider/MiniMax.json | 6 +- .../core/ai/config/provider/MistralAI.json | 10 +- .../core/ai/config/provider/Moonshot.json | 12 - .../core/ai/config/provider/OpenAI.json | 26 - .../service/core/ai/config/provider/Qwen.json | 42 -- .../core/ai/config/provider/Siliconflow.json | 8 +- .../core/ai/config/provider/SparkDesk.json | 14 +- .../core/ai/config/provider/StepFun.json | 24 +- .../service/core/ai/config/provider/Yi.json | 6 +- packages/service/core/app/controller.ts | 52 +- packages/service/core/app/mcp.ts | 31 +- packages/service/core/app/utils.ts | 33 - packages/service/core/chat/chatItemSchema.ts | 13 +- packages/service/core/chat/controller.ts | 23 +- .../workflow/dispatch/abandoned/runApp.ts | 41 +- .../dispatch/agent/classifyQuestion.ts | 53 +- .../core/workflow/dispatch/agent/extract.ts | 192 +++--- .../service/core/workflow/dispatch/index.ts | 18 +- .../core/workflow/dispatch/plugin/run.ts | 52 +- .../core/workflow/dispatch/plugin/runApp.ts | 55 +- .../core/workflow/dispatch/plugin/runTool.ts | 10 +- .../core/workflow/dispatch/tools/http468.ts | 122 +--- .../service/core/workflow/dispatch/type.d.ts | 3 +- .../service/core/workflow/dispatch/utils.ts | 9 +- .../components/common/Icon/icons/close.svg | 8 +- .../common/Icon/icons/core/chat/sendFill.svg | 6 +- .../web/components/common/Icon/icons/stop.svg | 2 +- packages/web/i18n/en/account_bill.json | 2 + packages/web/i18n/en/common.json | 13 +- packages/web/i18n/zh-CN/account_bill.json | 2 + packages/web/i18n/zh-CN/common.json | 13 +- packages/web/i18n/zh-Hant/account_bill.json | 2 + packages/web/i18n/zh-Hant/common.json | 13 +- packages/web/styles/theme.ts | 4 +- projects/app/.env.template | 2 + projects/app/data/model.json | 10 +- projects/app/package.json | 2 +- .../common/secret/HeaderAuthConfig.tsx | 381 ++++++++++++ .../components/core/app/WelcomeTextConfig.tsx | 2 +- .../ChatContainer/ChatBox/Input/ChatInput.tsx | 489 ++++++++------- .../ChatBox/Input/VoiceInput.tsx | 182 ++++-- .../core/chat/ChatContainer/ChatBox/index.tsx | 1 + .../ChatContainer/components/FilePreview.tsx | 2 +- .../account/bill/InvoiceTable.tsx | 34 +- .../account/model/AddModelBox.tsx | 85 +-- .../account/model/ModelDashboard/index.tsx | 41 +- .../thirdParty/WorkflowVariableModal.tsx | 2 +- .../app/detail/MCPTools/ChatTest.tsx | 26 +- .../app/detail/MCPTools/Edit.tsx | 13 +- .../app/detail/MCPTools/EditForm.tsx | 20 +- .../app/detail/MCPTools/Header.tsx | 13 +- .../app/detail/MCPTools/index.tsx | 10 +- .../Flow/nodes/NodeHttp/index.tsx | 22 +- .../Flow/nodes/NodeVariableUpdate.tsx | 2 +- .../dashboard/apps/MCPToolsEditModal.tsx | 33 +- .../pages/api/common/system/getInitData.ts | 2 - projects/app/src/pages/api/core/app/del.ts | 2 +- .../src/pages/api/core/app/mcpTools/create.ts | 26 +- .../src/pages/api/core/app/mcpTools/update.ts | 93 ++- projects/app/src/pages/api/core/app/update.ts | 11 +- .../src/pages/api/core/app/version/publish.ts | 16 +- .../app/src/pages/api/core/chat/chatTest.ts | 73 ++- .../core/dataset/collection/create/fileId.ts | 4 +- .../pages/api/support/mcp/client/getTools.ts | 13 +- .../pages/api/support/mcp/client/runTool.ts | 12 +- .../user/team/plan/getTeamPlanStatus.ts | 1 + .../app/src/pages/api/v1/chat/completions.ts | 81 +-- .../app/src/pages/api/v2/chat/completions.ts | 87 +-- projects/app/src/pages/login/index.tsx | 5 +- projects/app/src/service/core/app/utils.ts | 10 +- projects/app/src/service/support/mcp/utils.ts | 59 +- .../app/src/web/common/hooks/useSpeech.ts | 341 +++++++++-- .../web/support/wallet/bill/invoice/api.ts | 5 + test/setupModels.ts | 4 - 111 files changed, 2516 insertions(+), 1685 deletions(-) create mode 100644 packages/global/common/secret/constants.ts create mode 100644 packages/global/common/secret/type.d.ts create mode 100644 packages/global/support/wallet/bill/invoice/type.d.ts create mode 100644 packages/service/common/secret/aes256gcm.ts create mode 100644 packages/service/common/secret/constants.ts create mode 100644 packages/service/common/secret/utils.ts create mode 100644 projects/app/src/components/common/secret/HeaderAuthConfig.tsx diff --git a/deploy/docker/docker-compose-pgvector.yml b/deploy/docker/docker-compose-pgvector.yml index d8cdf4785..ea192d2d7 100644 --- a/deploy/docker/docker-compose-pgvector.yml +++ b/deploy/docker/docker-compose-pgvector.yml @@ -23,7 +23,7 @@ services: volumes: - ./pg/data:/var/lib/postgresql/data healthcheck: - test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'postgres'] + test: ['CMD', 'pg_isready', '-U', 'username', '-d', 'postgres'] interval: 5s timeout: 5s retries: 10 diff --git a/deploy/helm/fastgpt/templates/configmap-config.yaml b/deploy/helm/fastgpt/templates/configmap-config.yaml index 07e3d3668..8f1004553 100644 --- a/deploy/helm/fastgpt/templates/configmap-config.yaml +++ b/deploy/helm/fastgpt/templates/configmap-config.yaml @@ -26,8 +26,6 @@ data: "usedInToolCall": true, "toolChoice": true, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": {} }, @@ -47,8 +45,6 @@ data: "usedInToolCall": true, "toolChoice": true, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": {} }, @@ -68,8 +64,6 @@ data: "usedInToolCall": true, "toolChoice": true, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": {} }, @@ -89,8 +83,6 @@ data: "usedInToolCall": false, "toolChoice": true, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": {} } diff --git a/docSite/content/zh-cn/docs/development/custom-models/xinference.md b/docSite/content/zh-cn/docs/development/custom-models/xinference.md index 19441dba2..fca492fc2 100644 --- a/docSite/content/zh-cn/docs/development/custom-models/xinference.md +++ b/docSite/content/zh-cn/docs/development/custom-models/xinference.md @@ -146,8 +146,6 @@ curl --location --request POST 'https:///v1/chat/completions' \ "usedInToolCall": true, // 是否用于工具调用(务必保证至少有一个为true) "toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。) "functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式) - "customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型 - "customExtractPrompt": "", // 自定义内容提取提示词 "defaultSystemChatPrompt": "", // 对话默认携带的系统提示词 "defaultConfig": {} // 请求API时,挟带一些默认配置(比如 GLM4 的 top_p) } diff --git a/docSite/content/zh-cn/docs/development/faq.md b/docSite/content/zh-cn/docs/development/faq.md index 54a927868..6648ae037 100644 --- a/docSite/content/zh-cn/docs/development/faq.md +++ b/docSite/content/zh-cn/docs/development/faq.md @@ -59,11 +59,10 @@ images: [] 可以。需要准备好向量模型和LLM模型。 -### 其他模型没法进行问题分类/内容提取 +### 其他模型没法进行内容提取 + +看日志。如果提示 JSON invalid,not support tool 之类的,说明该模型不支持工具调用或函数调用,需要设置`toolChoice=false`和`functionCall=false`,就会默认走提示词模式。目前内置提示词仅针对了商业模型API进行测试。问题分类基本可用,内容提取不太行。 -1. 看日志。如果提示 JSON invalid,not support tool 之类的,说明该模型不支持工具调用或函数调用,需要设置`toolChoice=false`和`functionCall=false`,就会默认走提示词模式。目前内置提示词仅针对了商业模型API进行测试。问题分类基本可用,内容提取不太行。 -2. 如果已经配置正常,并且没有错误日志,则说明可能提示词不太适合该模型,可以通过修改`customCQPrompt`来自定义提示词。 - ### 页面崩溃 1. 关闭翻译 diff --git a/docSite/content/zh-cn/docs/development/modelConfig/intro.md b/docSite/content/zh-cn/docs/development/modelConfig/intro.md index a86af3af8..81cec1f66 100644 --- a/docSite/content/zh-cn/docs/development/modelConfig/intro.md +++ b/docSite/content/zh-cn/docs/development/modelConfig/intro.md @@ -111,8 +111,6 @@ weight: 744 "usedInToolCall": true, // 是否用于工具调用(务必保证至少有一个为true) "toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。) "functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式) - "customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型 - "customExtractPrompt": "", // 自定义内容提取提示词 "defaultSystemChatPrompt": "", // 对话默认携带的系统提示词 "defaultConfig": {}, // 请求API时,挟带一些默认配置(比如 GLM4 的 top_p) "fieldMap": {} // 字段映射(o1 模型需要把 max_tokens 映射为 max_completion_tokens) @@ -322,8 +320,6 @@ OneAPI 的语言识别接口,无法正确的识别其他模型(会始终识 "usedInToolCall": true, // 是否用于工具调用(务必保证至少有一个为true) "toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。) "functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式) - "customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型 - "customExtractPrompt": "", // 自定义内容提取提示词 "defaultSystemChatPrompt": "", // 对话默认携带的系统提示词 "defaultConfig": {}, // 请求API时,挟带一些默认配置(比如 GLM4 的 top_p) "fieldMap": {} // 字段映射(o1 模型需要把 max_tokens 映射为 max_completion_tokens) @@ -345,8 +341,6 @@ OneAPI 的语言识别接口,无法正确的识别其他模型(会始终识 "usedInToolCall": true, "toolChoice": true, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": {}, "fieldMap": {} @@ -368,8 +362,6 @@ OneAPI 的语言识别接口,无法正确的识别其他模型(会始终识 "usedInToolCall": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": { "temperature": 1, @@ -394,8 +386,6 @@ OneAPI 的语言识别接口,无法正确的识别其他模型(会始终识 "usedInToolCall": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": { "temperature": 1, diff --git a/docSite/content/zh-cn/docs/development/upgrading/4811.md b/docSite/content/zh-cn/docs/development/upgrading/4811.md index b6d3891e0..7c822eced 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4811.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4811.md @@ -33,7 +33,6 @@ weight: 813 "usedInToolCall": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": { @@ -57,7 +56,6 @@ weight: 813 "usedInToolCall": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": { diff --git a/docSite/content/zh-cn/docs/development/upgrading/4816.md b/docSite/content/zh-cn/docs/development/upgrading/4816.md index d2f84bc35..5a2acaa88 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4816.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4816.md @@ -38,7 +38,6 @@ weight: 808 "usedInQueryExtension": true, "toolChoice": true, "functionCall": false, - "customCQPrompt": "", "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": {}, diff --git a/docSite/content/zh-cn/docs/development/upgrading/4912.md b/docSite/content/zh-cn/docs/development/upgrading/4912.md index 3ab12050c..1b96ecd1b 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4912.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4912.md @@ -10,7 +10,9 @@ weight: 788 ## 🚀 新增内容 1. AI proxy 监控完善,支持以图表/表格形式查看模型调用和性能情况。 -2. 商业版支持知识库分块时,LLM 进行自动分段识别。 +2. HTTP 节点和 MCP 支持单独“鉴权配置”,鉴权配置明文不会二次返回客户端,以保障数据安全。 +3. 问题分类和内容提取,提示词中自动加入上一轮结果进行额外引导。 +4. 商业版支持知识库分块时,LLM 进行自动分段识别。 ## ⚙️ 优化 @@ -18,8 +20,12 @@ weight: 788 2. 后端全量计算知识库 chunk 参数,避免自动模式下部分参数未正确使用默认值。 3. 将文本分块移至 worker 线程,避免阻塞。 4. 展示更多套餐用量信息。 +5. 优化输入框样式,桌面和移动端的语音输入样式更新。 ## 🐛 修复 1. 自定义问答提取提示词被覆盖。 -2. 模板导入时,存在空 indexes 时,导致数据插入失败。 \ No newline at end of file +2. 模板导入时,存在空 indexes 时,导致数据插入失败。 +3. 登录页可能存在的 XSS 攻击。 +4. 输入框语音输入时候会丢失文件列表的问题。 +5. 知识库文档中图片 TTL 字段未清除,导致图片过期。 \ No newline at end of file diff --git a/docSite/static/llms-full.txt b/docSite/static/llms-full.txt index c7dbded55..cd91ef46c 100644 --- a/docSite/static/llms-full.txt +++ b/docSite/static/llms-full.txt @@ -372,113 +372,113 @@ services: # 接入 ChatGLM2-m3e 模型 ## 将 FastGPT 接入私有化模型 ChatGLM2和m3e-large -## 前言 - -FastGPT 默认使用了 OpenAI 的 LLM 模型和向量模型,如果想要私有化部署的话,可以使用 ChatGLM2 和 m3e-large 模型。以下是由用户@不做了睡大觉 提供的接入方法。该镜像直接集成了 M3E-Large 和 ChatGLM2-6B 模型,可以直接使用。 - -## 部署镜像 - -+ 镜像名: `stawky/chatglm2-m3e:latest` -+ 国内镜像名: `registry.cn-hangzhou.aliyuncs.com/fastgpt_docker/chatglm2-m3e:latest` -+ 端口号: 6006 - -``` -# 设置安全凭证(即oneapi中的渠道密钥) -默认值:sk-aaabbbcccdddeeefffggghhhiiijjjkkk -也可以通过环境变量引入:sk-key。有关docker环境变量引入的方法请自寻教程,此处不再赘述。 -``` - -## 接入 [One API](/docs/development/modelconfig/one-api/) - -为 chatglm2 和 m3e-large 各添加一个渠道,参数如下: - -![](/imgs/model-m3e1.png) - -这里我填入 m3e 作为向量模型,chatglm2 作为语言模型 - -## 测试 - -curl 例子: - -```bash -curl --location --request POST 'https://domain/v1/embeddings' \ ---header 'Authorization: Bearer sk-aaabbbcccdddeeefffggghhhiiijjjkkk' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "model": "m3e", - "input": ["laf是什么"] -}' -``` - -```bash -curl --location --request POST 'https://domain/v1/chat/completions' \ ---header 'Authorization: Bearer sk-aaabbbcccdddeeefffggghhhiiijjjkkk' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "model": "chatglm2", - "messages": [{"role": "user", "content": "Hello!"}] -}' -``` - -Authorization 为 sk-aaabbbcccdddeeefffggghhhiiijjjkkk。model 为刚刚在 One API 填写的自定义模型。 - -## 接入 FastGPT - -修改 config.json 配置文件,在 llmModels 中加入 chatglm2, 在 vectorModels 中加入 M3E 模型: - -```json -"llmModels": [ - //其他对话模型 - { - "model": "chatglm2", - "name": "chatglm2", - "maxToken": 8000, - "price": 0, - "quoteMaxToken": 4000, - "maxTemperature": 1.2, - "defaultSystemChatPrompt": "" - } -], -"vectorModels": [ - { - "model": "text-embedding-ada-002", - "name": "Embedding-2", - "price": 0.2, - "defaultToken": 500, - "maxToken": 3000 - }, - { - "model": "m3e", - "name": "M3E(测试使用)", - "price": 0.1, - "defaultToken": 500, - "maxToken": 1800 - } -], -``` - -## 测试使用 - -M3E 模型的使用方法如下: - -1. 创建知识库时候选择 M3E 模型。 - - 注意,一旦选择后,知识库将无法修改向量模型。 - - ![](/imgs/model-m3e2.png) - -2. 导入数据 -3. 搜索测试 - - ![](/imgs/model-m3e3.png) - -4. 应用绑定知识库 - - 注意,应用只能绑定同一个向量模型的知识库,不能跨模型绑定。并且,需要注意调整相似度,不同向量模型的相似度(距离)会有所区别,需要自行测试实验。 - - ![](/imgs/model-m3e4.png) - -chatglm2 模型的使用方法如下: +## 前言 + +FastGPT 默认使用了 OpenAI 的 LLM 模型和向量模型,如果想要私有化部署的话,可以使用 ChatGLM2 和 m3e-large 模型。以下是由用户@不做了睡大觉 提供的接入方法。该镜像直接集成了 M3E-Large 和 ChatGLM2-6B 模型,可以直接使用。 + +## 部署镜像 + ++ 镜像名: `stawky/chatglm2-m3e:latest` ++ 国内镜像名: `registry.cn-hangzhou.aliyuncs.com/fastgpt_docker/chatglm2-m3e:latest` ++ 端口号: 6006 + +``` +# 设置安全凭证(即oneapi中的渠道密钥) +默认值:sk-aaabbbcccdddeeefffggghhhiiijjjkkk +也可以通过环境变量引入:sk-key。有关docker环境变量引入的方法请自寻教程,此处不再赘述。 +``` + +## 接入 [One API](/docs/development/modelconfig/one-api/) + +为 chatglm2 和 m3e-large 各添加一个渠道,参数如下: + +![](/imgs/model-m3e1.png) + +这里我填入 m3e 作为向量模型,chatglm2 作为语言模型 + +## 测试 + +curl 例子: + +```bash +curl --location --request POST 'https://domain/v1/embeddings' \ +--header 'Authorization: Bearer sk-aaabbbcccdddeeefffggghhhiiijjjkkk' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "model": "m3e", + "input": ["laf是什么"] +}' +``` + +```bash +curl --location --request POST 'https://domain/v1/chat/completions' \ +--header 'Authorization: Bearer sk-aaabbbcccdddeeefffggghhhiiijjjkkk' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "model": "chatglm2", + "messages": [{"role": "user", "content": "Hello!"}] +}' +``` + +Authorization 为 sk-aaabbbcccdddeeefffggghhhiiijjjkkk。model 为刚刚在 One API 填写的自定义模型。 + +## 接入 FastGPT + +修改 config.json 配置文件,在 llmModels 中加入 chatglm2, 在 vectorModels 中加入 M3E 模型: + +```json +"llmModels": [ + //其他对话模型 + { + "model": "chatglm2", + "name": "chatglm2", + "maxToken": 8000, + "price": 0, + "quoteMaxToken": 4000, + "maxTemperature": 1.2, + "defaultSystemChatPrompt": "" + } +], +"vectorModels": [ + { + "model": "text-embedding-ada-002", + "name": "Embedding-2", + "price": 0.2, + "defaultToken": 500, + "maxToken": 3000 + }, + { + "model": "m3e", + "name": "M3E(测试使用)", + "price": 0.1, + "defaultToken": 500, + "maxToken": 1800 + } +], +``` + +## 测试使用 + +M3E 模型的使用方法如下: + +1. 创建知识库时候选择 M3E 模型。 + + 注意,一旦选择后,知识库将无法修改向量模型。 + + ![](/imgs/model-m3e2.png) + +2. 导入数据 +3. 搜索测试 + + ![](/imgs/model-m3e3.png) + +4. 应用绑定知识库 + + 注意,应用只能绑定同一个向量模型的知识库,不能跨模型绑定。并且,需要注意调整相似度,不同向量模型的相似度(距离)会有所区别,需要自行测试实验。 + + ![](/imgs/model-m3e4.png) + +chatglm2 模型的使用方法如下: 模型选择 chatglm2 即可 # 接入 ChatGLM2-6B @@ -785,180 +785,180 @@ CUSTOM_READ_FILE_EXTENSION=pdf # 使用 Ollama 接入本地模型 ## 采用 Ollama 部署自己的模型 -[Ollama](https://ollama.com/) 是一个开源的AI大模型部署工具,专注于简化大语言模型的部署和使用,支持一键下载和运行各种大模型。 - -## 安装 Ollama - -Ollama 本身支持多种安装方式,但是推荐使用 Docker 拉取镜像部署。如果是个人设备上安装了 Ollama 后续需要解决如何让 Docker 中 FastGPT 容器访问宿主机 Ollama的问题,较为麻烦。 - -### Docker 安装(推荐) - -你可以使用 Ollama 官方的 Docker 镜像来一键安装和启动 Ollama 服务(确保你的机器上已经安装了 Docker),命令如下: - -```bash -docker pull ollama/ollama -docker run --rm -d --name ollama -p 11434:11434 ollama/ollama -``` - -如果你的 FastGPT 是在 Docker 中进行部署的,建议在拉取 Ollama 镜像时保证和 FastGPT 镜像处于同一网络,否则可能出现 FastGPT 无法访问的问题,命令如下: - -```bash -docker run --rm -d --name ollama --network (你的 Fastgpt 容器所在网络) -p 11434:11434 ollama/ollama -``` - -### 主机安装 - -如果你不想使用 Docker ,也可以采用主机安装,以下是主机安装的一些方式。 - -#### MacOS - -如果你使用的是 macOS,且系统中已经安装了 Homebrew 包管理器,可通过以下命令来安装 Ollama: - -```bash -brew install ollama -ollama serve #安装完成后,使用该命令启动服务 -``` - -#### Linux - -在 Linux 系统上,你可以借助包管理器来安装 Ollama。以 Ubuntu 为例,在终端执行以下命令: - -```bash -curl https://ollama.com/install.sh | sh #此命令会从官方网站下载并执行安装脚本。 -ollama serve #安装完成后,同样启动服务 -``` - -#### Windows - -在 Windows 系统中,你可以从 Ollama 官方网站 下载 Windows 版本的安装程序。下载完成后,运行安装程序,按照安装向导的提示完成安装。安装完成后,在命令提示符或 PowerShell 中启动服务: - -```bash -ollama serve #安装完成并启动服务后,你可以在浏览器中访问 http://localhost:11434 来验证 Ollama 是否安装成功。 -``` - -#### 补充说明 - -如果你是采用的主机应用 Ollama 而不是镜像,需要确保你的 Ollama 可以监听0.0.0.0。 - -##### 1. Linxu 系统 - -如果 Ollama 作为 systemd 服务运行,打开终端,编辑 Ollama 的 systemd 服务文件,使用命令sudo systemctl edit ollama.service,在[Service]部分添加Environment="OLLAMA_HOST=0.0.0.0"。保存并退出编辑器,然后执行sudo systemctl daemon - reload和sudo systemctl restart ollama使配置生效。 - -##### 2. MacOS 系统 - -打开终端,使用launchctl setenv ollama_host "0.0.0.0"命令设置环境变量,然后重启 Ollama 应用程序以使更改生效。 - -##### 3. Windows 系统 - -通过 “开始” 菜单或搜索栏打开 “编辑系统环境变量”,在 “系统属性” 窗口中点击 “环境变量”,在 “系统变量” 部分点击 “新建”,创建一个名为OLLAMA_HOST的变量,变量值设置为0.0.0.0,点击 “确定” 保存更改,最后从 “开始” 菜单重启 Ollama 应用程序。 - -### Ollama 拉取模型镜像 - -在安装 Ollama 后,本地是没有模型镜像的,需要自己去拉取 Ollama 中的模型镜像。命令如下: - -```bash -# Docker 部署需要先进容器,命令为: docker exec -it < Ollama 容器名 > /bin/sh -ollama pull <模型名> -``` - -![](/imgs/Ollama-pull.png) - - -### 测试通信 - -在安装完成后,需要进行检测测试,首先进入 FastGPT 所在的容器,尝试访问自己的 Ollama ,命令如下: - -```bash -docker exec -it < FastGPT 所在的容器名 > /bin/sh -curl http://XXX.XXX.XXX.XXX:11434 #容器部署地址为“http://<容器名>:<端口>”,主机安装地址为"http://<主机IP>:<端口>",主机IP不可为localhost -``` - -看到访问显示自己的 Ollama 服务以及启动,说明可以正常通信。 - -## 将 Ollama 接入 FastGPT - -### 1. 查看 Ollama 所拥有的模型 - -首先采用下述命令查看 Ollama 中所拥有的模型, - -```bash -# Docker 部署 Ollama,需要此命令 docker exec -it < Ollama 容器名 > /bin/sh -ollama ls -``` - -![](/imgs/Ollama-models1.png) - -### 2. AI Proxy 接入 - -如果你采用的是 FastGPT 中的默认配置文件部署[这里](/docs/development/docker.md),即默认采用 AI Proxy 进行启动。 - -![](/imgs/Ollama-aiproxy1.png) - -以及在确保你的 FastGPT 可以直接访问 Ollama 容器的情况下,无法访问,参考上文[点此跳转](#安装-ollama)的安装过程,检测是不是主机不能监测0.0.0.0,或者容器不在同一个网络。 - -![](/imgs/Ollama-aiproxy2.png) - -在 FastGPT 中点击账号->模型提供商->模型配置->新增模型,添加自己的模型即可,添加模型时需要保证模型ID和 OneAPI 中的模型名称一致。详细参考[这里](/docs/development/modelConfig/intro.md) - -![](/imgs/Ollama-models2.png) - -![](/imgs/Ollama-models3.png) - -运行 FastGPT ,在页面中选择账号->模型提供商->模型渠道->新增渠道。之后,在渠道选择中选择 Ollama ,然后加入自己拉取的模型,填入代理地址,如果是容器中安装 Ollama ,代理地址为http://地址:端口,补充:容器部署地址为“http://<容器名>:<端口>”,主机安装地址为"http://<主机IP>:<端口>",主机IP不可为localhost - -![](/imgs/Ollama-aiproxy3.png) - -在工作台中创建一个应用,选择自己之前添加的模型,此处模型名称为自己当时设置的别名。注:同一个模型无法多次添加,系统会采取最新添加时设置的别名。 - -![](/imgs/Ollama-models4.png) - -### 3. OneAPI 接入 - -如果你想使用 OneAPI ,首先需要拉取 OneAPI 镜像,然后将其在 FastGPT 容器的网络中运行。具体命令如下: - -```bash -# 拉取 oneAPI 镜像 -docker pull intel/oneapi-hpckit - -# 运行容器并指定自定义网络和容器名 -docker run -it --network < FastGPT 网络 > --name 容器名 intel/oneapi-hpckit /bin/bash -``` - -进入 OneAPI 页面,添加新的渠道,类型选择 Ollama ,在模型中填入自己 Ollama 中的模型,需要保证添加的模型名称和 Ollama 中一致,再在下方填入自己的 Ollama 代理地址,默认http://地址:端口,不需要填写/v1。添加成功后在 OneAPI 进行渠道测试,测试成功则说明添加成功。此处演示采用的是 Docker 部署 Ollama 的效果,主机 Ollama需要修改代理地址为http://<主机IP>:<端口> - -![](/imgs/Ollama-oneapi1.png) - -渠道添加成功后,点击令牌,点击添加令牌,填写名称,修改配置。 - -![](/imgs/Ollama-oneapi2.png) - -修改部署 FastGPT 的 docker-compose.yml 文件,在其中将 AI Proxy 的使用注释,在 OPENAI_BASE_URL 中加入自己的 OneAPI 开放地址,默认是http://地址:端口/v1,v1必须填写。KEY 中填写自己在 OneAPI 的令牌。 - -![](/imgs/Ollama-oneapi3.png) - -[直接跳转5](#5-模型添加和使用)添加模型,并使用。 - -### 4. 直接接入 - -如果你既不想使用 AI Proxy,也不想使用 OneAPI,也可以选择直接接入,修改部署 FastGPT 的 docker-compose.yml 文件,在其中将 AI Proxy 的使用注释,采用和 OneAPI 的类似配置。注释掉 AIProxy 相关代码,在OPENAI_BASE_URL中加入自己的 Ollama 开放地址,默认是http://地址:端口/v1,强调:v1必须填写。在KEY中随便填入,因为 Ollama 默认没有鉴权,如果开启鉴权,请自行填写。其他操作和在 OneAPI 中加入 Ollama 一致,只需在 FastGPT 中加入自己的模型即可使用。此处演示采用的是 Docker 部署 Ollama 的效果,主机 Ollama需要修改代理地址为http://<主机IP>:<端口> - -![](/imgs/Ollama-direct1.png) - -完成后[点击这里](#5-模型添加和使用)进行模型添加并使用。 - -### 5. 模型添加和使用 - -在 FastGPT 中点击账号->模型提供商->模型配置->新增模型,添加自己的模型即可,添加模型时需要保证模型ID和 OneAPI 中的模型名称一致。 - -![](/imgs/Ollama-models2.png) - -![](/imgs/Ollama-models3.png) - -在工作台中创建一个应用,选择自己之前添加的模型,此处模型名称为自己当时设置的别名。注:同一个模型无法多次添加,系统会采取最新添加时设置的别名。 - -![](/imgs/Ollama-models4.png) - -### 6. 补充 +[Ollama](https://ollama.com/) 是一个开源的AI大模型部署工具,专注于简化大语言模型的部署和使用,支持一键下载和运行各种大模型。 + +## 安装 Ollama + +Ollama 本身支持多种安装方式,但是推荐使用 Docker 拉取镜像部署。如果是个人设备上安装了 Ollama 后续需要解决如何让 Docker 中 FastGPT 容器访问宿主机 Ollama的问题,较为麻烦。 + +### Docker 安装(推荐) + +你可以使用 Ollama 官方的 Docker 镜像来一键安装和启动 Ollama 服务(确保你的机器上已经安装了 Docker),命令如下: + +```bash +docker pull ollama/ollama +docker run --rm -d --name ollama -p 11434:11434 ollama/ollama +``` + +如果你的 FastGPT 是在 Docker 中进行部署的,建议在拉取 Ollama 镜像时保证和 FastGPT 镜像处于同一网络,否则可能出现 FastGPT 无法访问的问题,命令如下: + +```bash +docker run --rm -d --name ollama --network (你的 Fastgpt 容器所在网络) -p 11434:11434 ollama/ollama +``` + +### 主机安装 + +如果你不想使用 Docker ,也可以采用主机安装,以下是主机安装的一些方式。 + +#### MacOS + +如果你使用的是 macOS,且系统中已经安装了 Homebrew 包管理器,可通过以下命令来安装 Ollama: + +```bash +brew install ollama +ollama serve #安装完成后,使用该命令启动服务 +``` + +#### Linux + +在 Linux 系统上,你可以借助包管理器来安装 Ollama。以 Ubuntu 为例,在终端执行以下命令: + +```bash +curl https://ollama.com/install.sh | sh #此命令会从官方网站下载并执行安装脚本。 +ollama serve #安装完成后,同样启动服务 +``` + +#### Windows + +在 Windows 系统中,你可以从 Ollama 官方网站 下载 Windows 版本的安装程序。下载完成后,运行安装程序,按照安装向导的提示完成安装。安装完成后,在命令提示符或 PowerShell 中启动服务: + +```bash +ollama serve #安装完成并启动服务后,你可以在浏览器中访问 http://localhost:11434 来验证 Ollama 是否安装成功。 +``` + +#### 补充说明 + +如果你是采用的主机应用 Ollama 而不是镜像,需要确保你的 Ollama 可以监听0.0.0.0。 + +##### 1. Linxu 系统 + +如果 Ollama 作为 systemd 服务运行,打开终端,编辑 Ollama 的 systemd 服务文件,使用命令sudo systemctl edit ollama.service,在[Service]部分添加Environment="OLLAMA_HOST=0.0.0.0"。保存并退出编辑器,然后执行sudo systemctl daemon - reload和sudo systemctl restart ollama使配置生效。 + +##### 2. MacOS 系统 + +打开终端,使用launchctl setenv ollama_host "0.0.0.0"命令设置环境变量,然后重启 Ollama 应用程序以使更改生效。 + +##### 3. Windows 系统 + +通过 “开始” 菜单或搜索栏打开 “编辑系统环境变量”,在 “系统属性” 窗口中点击 “环境变量”,在 “系统变量” 部分点击 “新建”,创建一个名为OLLAMA_HOST的变量,变量值设置为0.0.0.0,点击 “确定” 保存更改,最后从 “开始” 菜单重启 Ollama 应用程序。 + +### Ollama 拉取模型镜像 + +在安装 Ollama 后,本地是没有模型镜像的,需要自己去拉取 Ollama 中的模型镜像。命令如下: + +```bash +# Docker 部署需要先进容器,命令为: docker exec -it < Ollama 容器名 > /bin/sh +ollama pull <模型名> +``` + +![](/imgs/Ollama-pull.png) + + +### 测试通信 + +在安装完成后,需要进行检测测试,首先进入 FastGPT 所在的容器,尝试访问自己的 Ollama ,命令如下: + +```bash +docker exec -it < FastGPT 所在的容器名 > /bin/sh +curl http://XXX.XXX.XXX.XXX:11434 #容器部署地址为“http://<容器名>:<端口>”,主机安装地址为"http://<主机IP>:<端口>",主机IP不可为localhost +``` + +看到访问显示自己的 Ollama 服务以及启动,说明可以正常通信。 + +## 将 Ollama 接入 FastGPT + +### 1. 查看 Ollama 所拥有的模型 + +首先采用下述命令查看 Ollama 中所拥有的模型, + +```bash +# Docker 部署 Ollama,需要此命令 docker exec -it < Ollama 容器名 > /bin/sh +ollama ls +``` + +![](/imgs/Ollama-models1.png) + +### 2. AI Proxy 接入 + +如果你采用的是 FastGPT 中的默认配置文件部署[这里](/docs/development/docker.md),即默认采用 AI Proxy 进行启动。 + +![](/imgs/Ollama-aiproxy1.png) + +以及在确保你的 FastGPT 可以直接访问 Ollama 容器的情况下,无法访问,参考上文[点此跳转](#安装-ollama)的安装过程,检测是不是主机不能监测0.0.0.0,或者容器不在同一个网络。 + +![](/imgs/Ollama-aiproxy2.png) + +在 FastGPT 中点击账号->模型提供商->模型配置->新增模型,添加自己的模型即可,添加模型时需要保证模型ID和 OneAPI 中的模型名称一致。详细参考[这里](/docs/development/modelConfig/intro.md) + +![](/imgs/Ollama-models2.png) + +![](/imgs/Ollama-models3.png) + +运行 FastGPT ,在页面中选择账号->模型提供商->模型渠道->新增渠道。之后,在渠道选择中选择 Ollama ,然后加入自己拉取的模型,填入代理地址,如果是容器中安装 Ollama ,代理地址为http://地址:端口,补充:容器部署地址为“http://<容器名>:<端口>”,主机安装地址为"http://<主机IP>:<端口>",主机IP不可为localhost + +![](/imgs/Ollama-aiproxy3.png) + +在工作台中创建一个应用,选择自己之前添加的模型,此处模型名称为自己当时设置的别名。注:同一个模型无法多次添加,系统会采取最新添加时设置的别名。 + +![](/imgs/Ollama-models4.png) + +### 3. OneAPI 接入 + +如果你想使用 OneAPI ,首先需要拉取 OneAPI 镜像,然后将其在 FastGPT 容器的网络中运行。具体命令如下: + +```bash +# 拉取 oneAPI 镜像 +docker pull intel/oneapi-hpckit + +# 运行容器并指定自定义网络和容器名 +docker run -it --network < FastGPT 网络 > --name 容器名 intel/oneapi-hpckit /bin/bash +``` + +进入 OneAPI 页面,添加新的渠道,类型选择 Ollama ,在模型中填入自己 Ollama 中的模型,需要保证添加的模型名称和 Ollama 中一致,再在下方填入自己的 Ollama 代理地址,默认http://地址:端口,不需要填写/v1。添加成功后在 OneAPI 进行渠道测试,测试成功则说明添加成功。此处演示采用的是 Docker 部署 Ollama 的效果,主机 Ollama需要修改代理地址为http://<主机IP>:<端口> + +![](/imgs/Ollama-oneapi1.png) + +渠道添加成功后,点击令牌,点击添加令牌,填写名称,修改配置。 + +![](/imgs/Ollama-oneapi2.png) + +修改部署 FastGPT 的 docker-compose.yml 文件,在其中将 AI Proxy 的使用注释,在 OPENAI_BASE_URL 中加入自己的 OneAPI 开放地址,默认是http://地址:端口/v1,v1必须填写。KEY 中填写自己在 OneAPI 的令牌。 + +![](/imgs/Ollama-oneapi3.png) + +[直接跳转5](#5-模型添加和使用)添加模型,并使用。 + +### 4. 直接接入 + +如果你既不想使用 AI Proxy,也不想使用 OneAPI,也可以选择直接接入,修改部署 FastGPT 的 docker-compose.yml 文件,在其中将 AI Proxy 的使用注释,采用和 OneAPI 的类似配置。注释掉 AIProxy 相关代码,在OPENAI_BASE_URL中加入自己的 Ollama 开放地址,默认是http://地址:端口/v1,强调:v1必须填写。在KEY中随便填入,因为 Ollama 默认没有鉴权,如果开启鉴权,请自行填写。其他操作和在 OneAPI 中加入 Ollama 一致,只需在 FastGPT 中加入自己的模型即可使用。此处演示采用的是 Docker 部署 Ollama 的效果,主机 Ollama需要修改代理地址为http://<主机IP>:<端口> + +![](/imgs/Ollama-direct1.png) + +完成后[点击这里](#5-模型添加和使用)进行模型添加并使用。 + +### 5. 模型添加和使用 + +在 FastGPT 中点击账号->模型提供商->模型配置->新增模型,添加自己的模型即可,添加模型时需要保证模型ID和 OneAPI 中的模型名称一致。 + +![](/imgs/Ollama-models2.png) + +![](/imgs/Ollama-models3.png) + +在工作台中创建一个应用,选择自己之前添加的模型,此处模型名称为自己当时设置的别名。注:同一个模型无法多次添加,系统会采取最新添加时设置的别名。 + +![](/imgs/Ollama-models4.png) + +### 6. 补充 上述接入 Ollama 的代理地址中,主机安装 Ollama 的地址为“http://<主机IP>:<端口>”,容器部署 Ollama 地址为“http://<容器名>:<端口>” # 使用 Xinference 接入本地模型 @@ -1103,7 +1103,6 @@ curl --location --request POST 'https:///v1/chat/completions' \ "usedInToolCall": true, // 是否用于工具调用(务必保证至少有一个为true) "toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。) "functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式) - "customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型 "customExtractPrompt": "", // 自定义内容提取提示词 "defaultSystemChatPrompt": "", // 对话默认携带的系统提示词 "defaultConfig": {} // 请求API时,挟带一些默认配置(比如 GLM4 的 top_p) @@ -2815,8 +2814,6 @@ OneAPI 的语言识别接口,无法正确的识别其他模型(会始终识 "usedInToolCall": true, "toolChoice": true, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": {}, "fieldMap": {} @@ -2838,8 +2835,6 @@ OneAPI 的语言识别接口,无法正确的识别其他模型(会始终识 "usedInToolCall": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": { "temperature": 1, @@ -2864,8 +2859,6 @@ OneAPI 的语言识别接口,无法正确的识别其他模型(会始终识 "usedInToolCall": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": { "temperature": 1, diff --git a/env.d.ts b/env.d.ts index 293b1e0c7..22af25344 100644 --- a/env.d.ts +++ b/env.d.ts @@ -5,6 +5,7 @@ declare global { DEFAULT_ROOT_PSW: string; DB_MAX_LINK: string; FILE_TOKEN_KEY: string; + AES256_SECRET_KEY: string; ROOT_KEY: string; OPENAI_BASE_URL: string; CHAT_API_KEY: string; diff --git a/packages/global/common/secret/constants.ts b/packages/global/common/secret/constants.ts new file mode 100644 index 000000000..3a15aa47b --- /dev/null +++ b/packages/global/common/secret/constants.ts @@ -0,0 +1,8 @@ +import { i18nT } from '../../../web/i18n/utils'; + +export enum HeaderSecretTypeEnum { + None = 'None', + Bearer = 'Bearer', + Basic = 'Basic', + Custom = 'Custom' +} diff --git a/packages/global/common/secret/type.d.ts b/packages/global/common/secret/type.d.ts new file mode 100644 index 000000000..2a3d1ff02 --- /dev/null +++ b/packages/global/common/secret/type.d.ts @@ -0,0 +1,6 @@ +export type SecretValueType = { + value: string; + secret: string; +}; + +export type StoreSecretValueType = Record; diff --git a/packages/global/core/ai/model.d.ts b/packages/global/core/ai/model.d.ts index f1b78a554..c32c3d251 100644 --- a/packages/global/core/ai/model.d.ts +++ b/packages/global/core/ai/model.d.ts @@ -51,9 +51,6 @@ export type LLMModelItemType = PriceType & functionCall: boolean; toolChoice: boolean; - customCQPrompt: string; - customExtractPrompt: string; - defaultSystemChatPrompt?: string; defaultConfig?: Record; fieldMap?: Record; diff --git a/packages/global/core/ai/model.ts b/packages/global/core/ai/model.ts index 52ca4f895..c059b1b78 100644 --- a/packages/global/core/ai/model.ts +++ b/packages/global/core/ai/model.ts @@ -26,8 +26,6 @@ export const defaultQAModels: LLMModelItemType[] = [ datasetProcess: true, toolChoice: true, functionCall: false, - customCQPrompt: '', - customExtractPrompt: '', defaultSystemChatPrompt: '', defaultConfig: {} } diff --git a/packages/global/core/ai/prompt/agent.ts b/packages/global/core/ai/prompt/agent.ts index 08293bc3f..12f77fa59 100644 --- a/packages/global/core/ai/prompt/agent.ts +++ b/packages/global/core/ai/prompt/agent.ts @@ -1,5 +1,3 @@ -import { getPromptByVersion } from './utils'; - export const Prompt_AgentQA = { description: ` 标记中是一段文本,学习和分析它,并整理学习成果: - 提出问题并给出每个问题的答案。 @@ -27,73 +25,140 @@ A2: ` }; -export const getExtractJsonPrompt = (version?: string) => { - const promptMap: Record = { - ['4.9.2']: `你可以从 <对话记录> 中提取指定 Json 信息,你仅需返回 Json 字符串,无需回答问题。 -<提取要求> -{{description}} - +export const getExtractJsonPrompt = ({ + schema, + systemPrompt, + memory +}: { + schema?: string; + systemPrompt?: string; + memory?: string; +}) => { + const list = [ + '【历史记录】', + '【用户输入】', + systemPrompt ? '【背景知识】' : '', + memory ? '【历史提取结果】' : '' + ].filter(Boolean); + const prompt = `## 背景 +用户需要执行一个函数,该函数需要一些参数,需要你结合${list.join('、')},来生成对应的参数 -<提取规则> -- 本次需提取的 json 字符串,需符合 JsonSchema 的规则。 -- type 代表数据类型; key 代表字段名; description 代表字段的描述; enum 是枚举值,代表可选的 value。 -- 如果没有可提取的内容,忽略该字段。 - +## 基本要求 - -{{json}} - - -<对话记录> -{{text}} - - -提取的 json 字符串:` - }; - - return getPromptByVersion(version, promptMap); -}; - -export const getExtractJsonToolPrompt = (version?: string) => { - const promptMap: Record = { - ['4.9.2']: `我正在执行一个函数,需要你提供一些参数,请以 JSON 字符串格式返回这些参数,要求: -""" -- {{description}} +- 严格根据 JSON Schema 的描述来生成参数。 - 不是每个参数都是必须生成的,如果没有合适的参数值,不要生成该参数,或返回空字符串。 - 需要结合历史记录,一起生成合适的参数。 -""" -本次输入内容: """{{content}}""" - ` - }; +${ + systemPrompt + ? `## 特定要求 +${systemPrompt}` + : '' +} - return getPromptByVersion(version, promptMap); +${ + memory + ? `## 历史提取结果 +${memory}` + : '' +} + +## JSON Schema + +${schema} + +## 输出要求 + +- 严格输出 json 字符串。 +- 不要回答问题。`.replace(/\n{3,}/g, '\n\n'); + + return prompt; +}; +export const getExtractJsonToolPrompt = ({ + systemPrompt, + memory +}: { + systemPrompt?: string; + memory?: string; +}) => { + const list = [ + '【历史记录】', + '【用户输入】', + systemPrompt ? '【背景知识】' : '', + memory ? '【历史提取结果】' : '' + ].filter(Boolean); + const prompt = `## 背景 +用户需要执行一个叫 "request_function" 的函数,该函数需要你结合${list.join('、')},来生成对应的参数 + +## 基本要求 + +- 不是每个参数都是必须生成的,如果没有合适的参数值,不要生成该参数,或返回空字符串。 +- 需要结合历史记录,一起生成合适的参数。最新的记录优先级更高。 +- 即使无法调用函数,也要返回一个 JSON 字符串,而不是回答问题。 + +${ + systemPrompt + ? `## 特定要求 +${systemPrompt}` + : '' +} + +${ + memory + ? `## 历史提取结果 +${memory}` + : '' +}`.replace(/\n{3,}/g, '\n\n'); + + return prompt; }; -export const getCQPrompt = (version?: string) => { - const promptMap: Record = { - ['4.9.2']: `请帮我执行一个"问题分类"任务,将问题分类为以下几种类型之一: +export const getCQSystemPrompt = ({ + systemPrompt, + memory, + typeList +}: { + systemPrompt?: string; + memory?: string; + typeList: string; +}) => { + const list = [ + systemPrompt ? '【背景知识】' : '', + '【历史记录】', + memory ? '【上一轮分类结果】' : '' + ].filter(Boolean); + const CLASSIFY_QUESTION_SYSTEM_PROMPT = `## 角色 +你是一个"分类助手",可以结合${list.join('、')},来判断用户当前问题属于哪一个分类,并输出分类标记。 -""" -{{typeList}} -""" +${ + systemPrompt + ? `## 背景知识 +${systemPrompt}` + : '' +} -## 背景知识 -{{systemPrompt}} +${ + memory + ? `## 上一轮分类结果 +${memory}` + : '' +} -## 对话记录 -{{history}} +## 分类清单 -## 开始任务 +${typeList} -现在,我们开始分类,我会给你一个"问题",请结合背景知识和对话记录,将问题分类到对应的类型中,并返回类型ID。 +## 分类要求 -问题:"{{question}}" -类型ID= -` - }; +1. 分类结果必须从分类清单中选择。 +2. 连续对话时,如果分类不明确,且用户未变更话题,则保持上一轮分类结果不变。 +3. 存在分类冲突或模糊分类时, 主语指向的分类优先级更高。 - return getPromptByVersion(version, promptMap); +## 输出格式 + +只需要输出分类的 id 即可,无需输出额外内容。`.replace(/\n{3,}/g, '\n\n'); + + return CLASSIFY_QUESTION_SYSTEM_PROMPT; }; export const QuestionGuidePrompt = `You are an AI assistant tasked with predicting the user's next question based on the conversation history. Your goal is to generate 3 potential questions that will guide the user to continue the conversation. When generating these questions, adhere to the following rules: diff --git a/packages/global/core/app/mcpTools/utils.ts b/packages/global/core/app/mcpTools/utils.ts index f8fc0ea61..b173f9a28 100644 --- a/packages/global/core/app/mcpTools/utils.ts +++ b/packages/global/core/app/mcpTools/utils.ts @@ -8,15 +8,18 @@ import { nanoid } from 'nanoid'; import { type McpToolConfigType } from '../type'; import { i18nT } from '../../../../web/i18n/utils'; import { type RuntimeNodeItemType } from '../../workflow/runtime/type'; +import { type StoreSecretValueType } from '../../../common/secret/type'; export const getMCPToolSetRuntimeNode = ({ url, toolList, + headerSecret, name, avatar }: { url: string; toolList: McpToolConfigType[]; + headerSecret?: StoreSecretValueType; name?: string; avatar?: string; }): RuntimeNodeItemType => { @@ -31,7 +34,11 @@ export const getMCPToolSetRuntimeNode = ({ label: 'Tool Set Data', valueType: WorkflowIOValueTypeEnum.object, renderTypeList: [FlowNodeInputTypeEnum.hidden], - value: { url, toolList } + value: { + url, + toolList, + headerSecret + } } ], outputs: [], @@ -43,10 +50,12 @@ export const getMCPToolSetRuntimeNode = ({ export const getMCPToolRuntimeNode = ({ tool, url, + headerSecret, avatar = 'core/app/type/mcpToolsFill' }: { tool: McpToolConfigType; url: string; + headerSecret?: StoreSecretValueType; avatar?: string; }): RuntimeNodeItemType => { return { @@ -60,7 +69,11 @@ export const getMCPToolRuntimeNode = ({ label: 'Tool Data', valueType: WorkflowIOValueTypeEnum.object, renderTypeList: [FlowNodeInputTypeEnum.hidden], - value: { ...tool, url } + value: { + ...tool, + url, + headerSecret + } }, ...Object.entries(tool.inputSchema?.properties || {}).map(([key, value]) => ({ key, diff --git a/packages/global/core/app/utils.ts b/packages/global/core/app/utils.ts index e841941c4..adda6f73a 100644 --- a/packages/global/core/app/utils.ts +++ b/packages/global/core/app/utils.ts @@ -7,9 +7,6 @@ import { type StoreNodeItemType } from '../workflow/type/node'; import { DatasetSearchModeEnum } from '../dataset/constants'; import { type WorkflowTemplateBasicType } from '../workflow/type'; import { AppTypeEnum } from './constants'; -import { AppErrEnum } from '../../common/error/code/app'; -import { PluginErrEnum } from '../../common/error/code/plugin'; -import { i18nT } from '../../../web/i18n/utils'; import appErrList from '../../common/error/code/app'; import pluginErrList from '../../common/error/code/plugin'; diff --git a/packages/global/core/chat/type.d.ts b/packages/global/core/chat/type.d.ts index 76acc9916..817e08cd9 100644 --- a/packages/global/core/chat/type.d.ts +++ b/packages/global/core/chat/type.d.ts @@ -93,6 +93,7 @@ export type AIChatItemValueItemType = { export type AIChatItemType = { obj: ChatRoleEnum.AI; value: AIChatItemValueItemType[]; + memories?: Record; userGoodFeedback?: string; userBadFeedback?: string; customFeedbacks?: string[]; diff --git a/packages/global/core/workflow/constants.ts b/packages/global/core/workflow/constants.ts index d484f4f9f..fdcc7e74a 100644 --- a/packages/global/core/workflow/constants.ts +++ b/packages/global/core/workflow/constants.ts @@ -129,6 +129,7 @@ export enum NodeInputKeyEnum { textareaInput = 'system_textareaInput', addInputParam = 'system_addInputParam', forbidStream = 'system_forbid_stream', + headerSecret = 'system_header_secret', // history historyMaxAmount = 'maxContext', diff --git a/packages/global/core/workflow/runtime/constants.ts b/packages/global/core/workflow/runtime/constants.ts index 5c2859786..a2948b7d2 100644 --- a/packages/global/core/workflow/runtime/constants.ts +++ b/packages/global/core/workflow/runtime/constants.ts @@ -25,10 +25,10 @@ export enum DispatchNodeResponseKeyEnum { toolResponses = 'toolResponses', // The result is passed back to the tool node for use assistantResponses = 'assistantResponses', // assistant response rewriteHistories = 'rewriteHistories', // If have the response, workflow histories will be rewrite - interactive = 'INTERACTIVE', // is interactive runTimes = 'runTimes', // run times - newVariables = 'newVariables' // new variables + newVariables = 'newVariables', // new variables + memories = 'system_memories' // memories } export const needReplaceReferenceInputTypeList = [ diff --git a/packages/global/core/workflow/runtime/type.d.ts b/packages/global/core/workflow/runtime/type.d.ts index f0a8d447b..55690a30d 100644 --- a/packages/global/core/workflow/runtime/type.d.ts +++ b/packages/global/core/workflow/runtime/type.d.ts @@ -246,6 +246,7 @@ export type DispatchNodeResultType = { [DispatchNodeResponseKeyEnum.rewriteHistories]?: ChatItemType[]; [DispatchNodeResponseKeyEnum.runTimes]?: number; [DispatchNodeResponseKeyEnum.newVariables]?: Record; + [DispatchNodeResponseKeyEnum.memories]?: Record; } & T; /* Single node props */ diff --git a/packages/global/core/workflow/template/system/classifyQuestion/index.ts b/packages/global/core/workflow/template/system/classifyQuestion/index.ts index e92bcee75..454b7e2e3 100644 --- a/packages/global/core/workflow/template/system/classifyQuestion/index.ts +++ b/packages/global/core/workflow/template/system/classifyQuestion/index.ts @@ -39,9 +39,9 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = { }, { ...Input_Template_System_Prompt, - label: 'core.module.input.label.Background', - description: 'core.module.input.description.Background', - placeholder: 'core.module.input.placeholder.Classify background' + label: i18nT('common:core.module.input.label.Background'), + description: i18nT('common:core.module.input.description.Background'), + placeholder: i18nT('common:core.module.input.placeholder.Classify background') }, Input_Template_History, Input_Template_UserChatInput, diff --git a/packages/global/core/workflow/template/system/http468.ts b/packages/global/core/workflow/template/system/http468.ts index adeaec6f9..5ce5635e1 100644 --- a/packages/global/core/workflow/template/system/http468.ts +++ b/packages/global/core/workflow/template/system/http468.ts @@ -65,6 +65,13 @@ export const HttpNode468: FlowNodeTemplateType = { placeholder: 'https://api.ai.com/getInventory', required: false }, + { + key: NodeInputKeyEnum.headerSecret, + renderTypeList: [FlowNodeInputTypeEnum.hidden], + valueType: WorkflowIOValueTypeEnum.object, + label: '', + required: false + }, { key: NodeInputKeyEnum.httpHeaders, renderTypeList: [FlowNodeInputTypeEnum.custom], diff --git a/packages/global/support/wallet/bill/invoice/type.d.ts b/packages/global/support/wallet/bill/invoice/type.d.ts new file mode 100644 index 000000000..3beb6ff6d --- /dev/null +++ b/packages/global/support/wallet/bill/invoice/type.d.ts @@ -0,0 +1,6 @@ +export type InvoiceFileInfo = { + data: string; // base64 encoded file data + mimeType: string; + filename: string; + size: number; +}; diff --git a/packages/service/common/secret/aes256gcm.ts b/packages/service/common/secret/aes256gcm.ts new file mode 100644 index 000000000..33579e508 --- /dev/null +++ b/packages/service/common/secret/aes256gcm.ts @@ -0,0 +1,28 @@ +import crypto from 'crypto'; +import { AES256_SECRET_KEY } from './constants'; + +export const encryptSecret = (text: string) => { + const iv = crypto.randomBytes(16); + const key = crypto.scryptSync(AES256_SECRET_KEY, 'salt', 32); + const cipher = crypto.createCipheriv('aes-256-gcm', key, iv); + const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]); + const authTag = cipher.getAuthTag(); + return `${iv.toString('hex')}:${encrypted.toString('hex')}:${authTag.toString('hex')}`; +}; + +export const decryptSecret = (encryptedText: string) => { + const [ivHex, encryptedHex, authTagHex] = encryptedText.split(':'); + + if (!ivHex || !encryptedHex || !authTagHex) { + return ''; + } + + const iv = Buffer.from(ivHex, 'hex'); + const encrypted = Buffer.from(encryptedHex, 'hex'); + const authTag = Buffer.from(authTagHex, 'hex'); + const key = crypto.scryptSync(AES256_SECRET_KEY, 'salt', 32); + const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv); + decipher.setAuthTag(authTag); + const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]); + return decrypted.toString('utf8'); +}; diff --git a/packages/service/common/secret/constants.ts b/packages/service/common/secret/constants.ts new file mode 100644 index 000000000..5ec1f2884 --- /dev/null +++ b/packages/service/common/secret/constants.ts @@ -0,0 +1 @@ +export const AES256_SECRET_KEY = process.env.AES256_SECRET_KEY || 'fastgptkey'; diff --git a/packages/service/common/secret/utils.ts b/packages/service/common/secret/utils.ts new file mode 100644 index 000000000..9fcf1b291 --- /dev/null +++ b/packages/service/common/secret/utils.ts @@ -0,0 +1,43 @@ +import { decryptSecret, encryptSecret } from './aes256gcm'; +import type { SecretValueType } from '@fastgpt/global/common/secret/type'; +import { type StoreSecretValueType } from '@fastgpt/global/common/secret/type'; +import { HeaderSecretTypeEnum } from '@fastgpt/global/common/secret/constants'; + +export const storeSecretValue = ( + storeSecret: StoreSecretValueType +): Record => { + return Object.fromEntries( + Object.entries(storeSecret).map(([key, value]) => [ + key, + { + secret: encryptSecret(value.value), + value: '' + } + ]) + ); +}; + +export const getSecretValue = ({ + storeSecret +}: { + storeSecret?: StoreSecretValueType; +}): Record => { + if (!storeSecret) return {}; + + return Object.entries(storeSecret).reduce( + (acc: Record, [key, { secret, value }]) => { + const actualValue = value || decryptSecret(secret); + + if (key === HeaderSecretTypeEnum.Bearer) { + acc['Authorization'] = `Bearer ${actualValue}`; + } else if (key === HeaderSecretTypeEnum.Basic) { + acc['Authorization'] = `Basic ${actualValue}`; + } else { + acc[key] = actualValue; + } + + return acc; + }, + {} + ); +}; diff --git a/packages/service/core/ai/config/provider/ChatGLM.json b/packages/service/core/ai/config/provider/ChatGLM.json index d4ce948bf..a5f8a07f7 100644 --- a/packages/service/core/ai/config/provider/ChatGLM.json +++ b/packages/service/core/ai/config/provider/ChatGLM.json @@ -9,10 +9,7 @@ "quoteMaxToken": 120000, "maxTemperature": 0.99, "showTopP": true, - "responseFormatList": [ - "text", - "json_object" - ], + "responseFormatList": ["text", "json_object"], "showStopSign": true, "vision": false, "toolChoice": true, @@ -20,10 +17,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -37,10 +32,7 @@ "quoteMaxToken": 120000, "maxTemperature": 0.99, "showTopP": true, - "responseFormatList": [ - "text", - "json_object" - ], + "responseFormatList": ["text", "json_object"], "showStopSign": true, "vision": false, "toolChoice": true, @@ -48,10 +40,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -65,10 +55,7 @@ "quoteMaxToken": 900000, "maxTemperature": 0.99, "showTopP": true, - "responseFormatList": [ - "text", - "json_object" - ], + "responseFormatList": ["text", "json_object"], "showStopSign": true, "vision": false, "toolChoice": false, @@ -76,10 +63,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -93,10 +78,7 @@ "quoteMaxToken": 120000, "maxTemperature": 0.99, "showTopP": true, - "responseFormatList": [ - "text", - "json_object" - ], + "responseFormatList": ["text", "json_object"], "showStopSign": true, "vision": false, "toolChoice": true, @@ -104,10 +86,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -128,10 +108,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -152,10 +130,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -172,4 +148,4 @@ "type": "embedding" } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/Claude.json b/packages/service/core/ai/config/provider/Claude.json index 8734498cd..bde1872f3 100644 --- a/packages/service/core/ai/config/provider/Claude.json +++ b/packages/service/core/ai/config/provider/Claude.json @@ -16,10 +16,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -40,10 +38,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -64,10 +60,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -88,10 +82,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -112,10 +104,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -136,10 +126,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -160,10 +148,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, diff --git a/packages/service/core/ai/config/provider/DeepSeek.json b/packages/service/core/ai/config/provider/DeepSeek.json index 91b748e85..8c0fd1b92 100644 --- a/packages/service/core/ai/config/provider/DeepSeek.json +++ b/packages/service/core/ai/config/provider/DeepSeek.json @@ -17,10 +17,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "type": "llm" }, @@ -38,10 +36,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, diff --git a/packages/service/core/ai/config/provider/Doubao.json b/packages/service/core/ai/config/provider/Doubao.json index 1beb32ed7..f28633bfb 100644 --- a/packages/service/core/ai/config/provider/Doubao.json +++ b/packages/service/core/ai/config/provider/Doubao.json @@ -16,10 +16,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -40,10 +38,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -64,10 +60,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -88,10 +82,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -112,10 +104,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -136,10 +126,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -158,10 +146,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -182,10 +168,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -206,10 +190,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -230,10 +212,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -254,10 +234,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -278,10 +256,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, diff --git a/packages/service/core/ai/config/provider/Ernie.json b/packages/service/core/ai/config/provider/Ernie.json index 3d4062a5d..955b5c9eb 100644 --- a/packages/service/core/ai/config/provider/Ernie.json +++ b/packages/service/core/ai/config/provider/Ernie.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -38,10 +36,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -62,10 +58,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -86,10 +80,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -112,4 +104,4 @@ "type": "embedding" } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/Gemini.json b/packages/service/core/ai/config/provider/Gemini.json index 0c2431b55..b36c604ef 100644 --- a/packages/service/core/ai/config/provider/Gemini.json +++ b/packages/service/core/ai/config/provider/Gemini.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -38,10 +36,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -62,10 +58,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -86,10 +80,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -110,10 +102,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -134,10 +124,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -158,10 +146,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -182,10 +168,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -206,10 +190,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -230,10 +212,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, diff --git a/packages/service/core/ai/config/provider/Grok.json b/packages/service/core/ai/config/provider/Grok.json index 197bb3e0a..ae8e407d7 100644 --- a/packages/service/core/ai/config/provider/Grok.json +++ b/packages/service/core/ai/config/provider/Grok.json @@ -16,10 +16,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -40,10 +38,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -64,10 +60,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -88,10 +82,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, diff --git a/packages/service/core/ai/config/provider/Groq.json b/packages/service/core/ai/config/provider/Groq.json index 5e1ef48ac..1d5366c3e 100644 --- a/packages/service/core/ai/config/provider/Groq.json +++ b/packages/service/core/ai/config/provider/Groq.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "type": "llm", @@ -37,10 +35,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "type": "llm", @@ -48,4 +44,4 @@ "showStopSign": true } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/Hunyuan.json b/packages/service/core/ai/config/provider/Hunyuan.json index c85c4d344..f682da711 100644 --- a/packages/service/core/ai/config/provider/Hunyuan.json +++ b/packages/service/core/ai/config/provider/Hunyuan.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -38,10 +36,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -62,10 +58,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -86,10 +80,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -110,10 +102,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -134,10 +124,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -158,10 +146,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -177,4 +163,4 @@ "type": "embedding" } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/Intern.json b/packages/service/core/ai/config/provider/Intern.json index 64f56e3d6..8434563db 100644 --- a/packages/service/core/ai/config/provider/Intern.json +++ b/packages/service/core/ai/config/provider/Intern.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -38,10 +36,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -50,4 +46,4 @@ "showStopSign": true } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/MiniMax.json b/packages/service/core/ai/config/provider/MiniMax.json index 9cf62e4d9..0d9702f33 100644 --- a/packages/service/core/ai/config/provider/MiniMax.json +++ b/packages/service/core/ai/config/provider/MiniMax.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -38,10 +36,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -241,4 +237,4 @@ "type": "tts" } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/MistralAI.json b/packages/service/core/ai/config/provider/MistralAI.json index 3d60d8358..27c2fe6fe 100644 --- a/packages/service/core/ai/config/provider/MistralAI.json +++ b/packages/service/core/ai/config/provider/MistralAI.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -38,10 +36,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -62,10 +58,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -86,10 +80,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -98,4 +90,4 @@ "showStopSign": true } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/Moonshot.json b/packages/service/core/ai/config/provider/Moonshot.json index f33b09ebe..0cf2cbbcf 100644 --- a/packages/service/core/ai/config/provider/Moonshot.json +++ b/packages/service/core/ai/config/provider/Moonshot.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -39,10 +37,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -64,10 +60,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -89,10 +83,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -114,10 +106,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -139,10 +129,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, diff --git a/packages/service/core/ai/config/provider/OpenAI.json b/packages/service/core/ai/config/provider/OpenAI.json index 776031129..c94dadf21 100644 --- a/packages/service/core/ai/config/provider/OpenAI.json +++ b/packages/service/core/ai/config/provider/OpenAI.json @@ -17,9 +17,7 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -41,9 +39,7 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -65,9 +61,7 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -89,9 +83,7 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -113,10 +105,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -135,10 +125,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": { @@ -161,10 +149,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": { @@ -187,10 +173,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": { @@ -213,10 +197,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": { @@ -239,10 +221,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": { @@ -265,10 +245,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": false @@ -295,10 +273,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "type": "llm" }, @@ -317,10 +293,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "type": "llm" }, diff --git a/packages/service/core/ai/config/provider/Qwen.json b/packages/service/core/ai/config/provider/Qwen.json index b617f619a..adab15ebb 100644 --- a/packages/service/core/ai/config/provider/Qwen.json +++ b/packages/service/core/ai/config/provider/Qwen.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -39,10 +37,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -63,10 +59,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -88,10 +82,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "type": "llm", "showTopP": true, @@ -110,10 +102,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -136,10 +126,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -164,10 +152,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -192,10 +178,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -220,10 +204,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -248,10 +230,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -276,10 +256,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -304,10 +282,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -332,10 +308,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -360,10 +334,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": false, "usedInClassify": false, - "customCQPrompt": "", "usedInExtractFields": false, "usedInQueryExtension": false, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -387,10 +359,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": false, "usedInClassify": false, - "customCQPrompt": "", "usedInExtractFields": false, "usedInQueryExtension": false, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": { "stream": true @@ -413,10 +383,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -437,10 +405,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -462,10 +428,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -487,10 +451,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -512,10 +474,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -537,10 +497,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": false, "usedInClassify": false, - "customCQPrompt": "", "usedInExtractFields": false, "usedInQueryExtension": false, - "customExtractPrompt": "", "usedInToolCall": false, "defaultConfig": {}, "fieldMap": {}, diff --git a/packages/service/core/ai/config/provider/Siliconflow.json b/packages/service/core/ai/config/provider/Siliconflow.json index 1abaa846c..ea0aaf21a 100644 --- a/packages/service/core/ai/config/provider/Siliconflow.json +++ b/packages/service/core/ai/config/provider/Siliconflow.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -40,8 +38,6 @@ "usedInToolCall": false, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": {}, "type": "llm", @@ -61,10 +57,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -207,4 +201,4 @@ "type": "rerank" } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/SparkDesk.json b/packages/service/core/ai/config/provider/SparkDesk.json index 0ea74643b..b5a4dc33c 100644 --- a/packages/service/core/ai/config/provider/SparkDesk.json +++ b/packages/service/core/ai/config/provider/SparkDesk.json @@ -16,8 +16,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -38,8 +36,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -60,8 +56,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -82,8 +76,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -102,10 +94,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -126,10 +116,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -138,4 +126,4 @@ "showStopSign": true } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/StepFun.json b/packages/service/core/ai/config/provider/StepFun.json index bfe2f766b..69d19a2f2 100644 --- a/packages/service/core/ai/config/provider/StepFun.json +++ b/packages/service/core/ai/config/provider/StepFun.json @@ -16,8 +16,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -38,8 +36,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -60,8 +56,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -82,8 +76,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -104,8 +96,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -126,8 +116,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -148,8 +136,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -170,8 +156,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -192,8 +176,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -214,8 +196,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -236,8 +216,6 @@ "usedInQueryExtension": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "type": "llm", "showTopP": true, @@ -327,4 +305,4 @@ "type": "tts" } ] -} \ No newline at end of file +} diff --git a/packages/service/core/ai/config/provider/Yi.json b/packages/service/core/ai/config/provider/Yi.json index 36c95375e..903ef1e9b 100644 --- a/packages/service/core/ai/config/provider/Yi.json +++ b/packages/service/core/ai/config/provider/Yi.json @@ -14,10 +14,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -38,10 +36,8 @@ "defaultSystemChatPrompt": "", "datasetProcess": true, "usedInClassify": true, - "customCQPrompt": "", "usedInExtractFields": true, "usedInQueryExtension": true, - "customExtractPrompt": "", "usedInToolCall": true, "defaultConfig": {}, "fieldMap": {}, @@ -50,4 +46,4 @@ "showStopSign": true } ] -} \ No newline at end of file +} diff --git a/packages/service/core/app/controller.ts b/packages/service/core/app/controller.ts index 78e22e24b..89c5519fa 100644 --- a/packages/service/core/app/controller.ts +++ b/packages/service/core/app/controller.ts @@ -1,19 +1,49 @@ import { type AppSchema } from '@fastgpt/global/core/app/type'; import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; -import { getLLMModel } from '../ai/model'; import { MongoApp } from './schema'; +import type { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node'; +import { storeSecretValue } from '../../common/secret/utils'; -export const beforeUpdateAppFormat = ({ - nodes, - isPlugin -}: { - nodes: T; - isPlugin: boolean; -}) => { - return { - nodes - }; +export const beforeUpdateAppFormat = ({ nodes }: { nodes?: StoreNodeItemType[] }) => { + if (!nodes) return; + + nodes.forEach((node) => { + // Format header secret + node.inputs.forEach((input) => { + if (input.key === NodeInputKeyEnum.headerSecret && typeof input.value === 'object') { + input.value = storeSecretValue(input.value); + } + }); + + // Format dataset search + if (node.flowNodeType === FlowNodeTypeEnum.datasetSearchNode) { + node.inputs.forEach((input) => { + if (input.key === NodeInputKeyEnum.datasetSelectList) { + const val = input.value as undefined | { datasetId: string }[] | { datasetId: string }; + if (!val) { + input.value = []; + } else if (Array.isArray(val)) { + // Not rewrite reference value + if (val.length === 2 && val.every((item) => typeof item === 'string')) { + return; + } + input.value = val + .map((dataset: { datasetId: string }) => ({ + datasetId: dataset.datasetId + })) + .filter((item) => !!item.datasetId); + } else if (typeof val === 'object' && val !== null) { + input.value = [ + { + datasetId: val.datasetId + } + ]; + } + } + }); + } + }); }; /* Get apps */ diff --git a/packages/service/core/app/mcp.ts b/packages/service/core/app/mcp.ts index aa097a607..981cdc94a 100644 --- a/packages/service/core/app/mcp.ts +++ b/packages/service/core/app/mcp.ts @@ -8,9 +8,11 @@ import { retryFn } from '@fastgpt/global/common/system/utils'; export class MCPClient { private client: Client; private url: string; + private headers: Record = {}; - constructor(config: { url: string }) { + constructor(config: { url: string; headers: Record }) { this.url = config.url; + this.headers = config.headers; this.client = new Client({ name: 'FastGPT-MCP-client', version: '1.0.0' @@ -19,11 +21,34 @@ export class MCPClient { private async getConnection(): Promise { try { - const transport = new StreamableHTTPClientTransport(new URL(this.url)); + const transport = new StreamableHTTPClientTransport(new URL(this.url), { + requestInit: { + headers: this.headers + } + }); await this.client.connect(transport); return this.client; } catch (error) { - await this.client.connect(new SSEClientTransport(new URL(this.url))); + await this.client.connect( + new SSEClientTransport(new URL(this.url), { + requestInit: { + headers: this.headers + }, + eventSourceInit: { + fetch: (url, init) => { + const headers = new Headers({ + ...init?.headers, + ...this.headers + }); + + return fetch(url, { + ...init, + headers + }); + } + } + }) + ); return this.client; } } diff --git a/packages/service/core/app/utils.ts b/packages/service/core/app/utils.ts index faf6ea4d8..89d055e02 100644 --- a/packages/service/core/app/utils.ts +++ b/packages/service/core/app/utils.ts @@ -83,8 +83,6 @@ export async function rewriteAppWorkflowToDetail({ }) ); - /* Add node(App Type) versionlabel and latest sign ==== */ - // Get all dataset ids from nodes nodes.forEach((node) => { if (node.flowNodeType !== FlowNodeTypeEnum.datasetSearchNode) return; @@ -170,34 +168,3 @@ export async function rewriteAppWorkflowToDetail({ return nodes; } - -export async function rewriteAppWorkflowToSimple(formatNodes: StoreNodeItemType[]) { - formatNodes.forEach((node) => { - if (node.flowNodeType !== FlowNodeTypeEnum.datasetSearchNode) return; - - node.inputs.forEach((input) => { - if (input.key === NodeInputKeyEnum.datasetSelectList) { - const val = input.value as undefined | { datasetId: string }[] | { datasetId: string }; - if (!val) { - input.value = []; - } else if (Array.isArray(val)) { - // Not rewrite reference value - if (val.length === 2 && val.every((item) => typeof item === 'string')) { - return; - } - input.value = val - .map((dataset: { datasetId: string }) => ({ - datasetId: dataset.datasetId - })) - .filter((item) => !!item.datasetId); - } else if (typeof val === 'object' && val !== null) { - input.value = [ - { - datasetId: val.datasetId - } - ]; - } - } - }); - }); -} diff --git a/packages/service/core/chat/chatItemSchema.ts b/packages/service/core/chat/chatItemSchema.ts index 69bafbc00..91ecc8c42 100644 --- a/packages/service/core/chat/chatItemSchema.ts +++ b/packages/service/core/chat/chatItemSchema.ts @@ -1,5 +1,5 @@ -import { connectionMongo, getMongoModel, type Model } from '../../common/mongo'; -const { Schema, model, models } = connectionMongo; +import { connectionMongo, getMongoModel } from '../../common/mongo'; +const { Schema } = connectionMongo; import { type ChatItemSchema as ChatItemType } from '@fastgpt/global/core/chat/type'; import { ChatRoleMap } from '@fastgpt/global/core/chat/constants'; import { getNanoid } from '@fastgpt/global/common/string/tools'; @@ -61,16 +61,13 @@ const ChatItemSchema = new Schema({ type: Array, default: [] }, + memories: Object, errorMsg: String, - userGoodFeedback: { - type: String - }, + userGoodFeedback: String, userBadFeedback: { type: String }, - customFeedbacks: { - type: [String] - }, + customFeedbacks: [String], adminFeedback: { type: { datasetId: String, diff --git a/packages/service/core/chat/controller.ts b/packages/service/core/chat/controller.ts index 1c5bbaadc..52588ad8d 100644 --- a/packages/service/core/chat/controller.ts +++ b/packages/service/core/chat/controller.ts @@ -1,7 +1,6 @@ -import type { ChatItemType, ChatItemValueItemType } from '@fastgpt/global/core/chat/type'; +import type { ChatItemType } from '@fastgpt/global/core/chat/type'; import { MongoChatItem } from './chatItemSchema'; import { addLog } from '../../common/system/log'; -import { ChatItemValueTypeEnum } from '@fastgpt/global/core/chat/constants'; import { delFileByFileIdList, getGFSCollection } from '../../common/file/gridfs/controller'; import { BucketNameEnum } from '@fastgpt/global/common/file/constants'; import { MongoChat } from './chatSchema'; @@ -29,29 +28,9 @@ export async function getChatItems({ ]); histories.reverse(); - histories.forEach((item) => { - // @ts-ignore - item.value = adaptStringValue(item.value); - }); - return { histories, total }; } -/* Temporary adaptation for old conversation records */ -export const adaptStringValue = (value: any): ChatItemValueItemType[] => { - if (typeof value === 'string') { - return [ - { - type: ChatItemValueTypeEnum.text, - text: { - content: value - } - } - ]; - } - return value; -}; - export const addCustomFeedbacks = async ({ appId, chatId, diff --git a/packages/service/core/workflow/dispatch/abandoned/runApp.ts b/packages/service/core/workflow/dispatch/abandoned/runApp.ts index ee7afc40d..0f0cca9f5 100644 --- a/packages/service/core/workflow/dispatch/abandoned/runApp.ts +++ b/packages/service/core/workflow/dispatch/abandoned/runApp.ts @@ -59,25 +59,27 @@ export const dispatchAppRequest = async (props: Props): Promise => { const chatHistories = getHistories(history, histories); const { files } = chatValue2RuntimePrompt(query); - const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({ - ...props, - runningAppInfo: { - id: String(appData._id), - teamId: String(appData.teamId), - tmbId: String(appData.tmbId) - }, - runtimeNodes: storeNodes2RuntimeNodes( - appData.modules, - getWorkflowEntryNodeIds(appData.modules) - ), - runtimeEdges: storeEdges2RuntimeEdges(appData.edges), - histories: chatHistories, - query: runtimePrompt2ChatsValue({ - files, - text: userChatInput - }), - variables: props.variables - }); + const { flowResponses, flowUsages, assistantResponses, system_memories } = await dispatchWorkFlow( + { + ...props, + runningAppInfo: { + id: String(appData._id), + teamId: String(appData.teamId), + tmbId: String(appData.tmbId) + }, + runtimeNodes: storeNodes2RuntimeNodes( + appData.modules, + getWorkflowEntryNodeIds(appData.modules) + ), + runtimeEdges: storeEdges2RuntimeEdges(appData.edges), + histories: chatHistories, + query: runtimePrompt2ChatsValue({ + files, + text: userChatInput + }), + variables: props.variables + } + ); const completeMessages = chatHistories.concat([ { @@ -94,6 +96,7 @@ export const dispatchAppRequest = async (props: Props): Promise => { return { assistantResponses, + system_memories, [DispatchNodeResponseKeyEnum.nodeResponse]: { moduleLogo: appData.avatar, query: userChatInput, diff --git a/packages/service/core/workflow/dispatch/agent/classifyQuestion.ts b/packages/service/core/workflow/dispatch/agent/classifyQuestion.ts index 16245b6e8..94f7788bd 100644 --- a/packages/service/core/workflow/dispatch/agent/classifyQuestion.ts +++ b/packages/service/core/workflow/dispatch/agent/classifyQuestion.ts @@ -11,19 +11,17 @@ import type { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type'; -import { getCQPrompt } from '@fastgpt/global/core/ai/prompt/agent'; +import { getCQSystemPrompt } from '@fastgpt/global/core/ai/prompt/agent'; import { type LLMModelItemType } from '@fastgpt/global/core/ai/model.d'; import { getLLMModel } from '../../../ai/model'; import { getHistories } from '../utils'; import { formatModelChars2Points } from '../../../../support/wallet/usage/utils'; import { type DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type'; -import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt'; import { getHandleId } from '@fastgpt/global/core/workflow/utils'; import { loadRequestMessages } from '../../../chat/utils'; import { llmCompletionsBodyFormat, formatLLMResponse } from '../../../ai/utils'; import { addLog } from '../../../../common/system/log'; import { ModelTypeEnum } from '../../../../../global/core/ai/model'; -import { replaceVariable } from '@fastgpt/global/common/string/tools'; type Props = ModuleDispatchProps<{ [NodeInputKeyEnum.aiModel]: string; @@ -35,12 +33,16 @@ type Props = ModuleDispatchProps<{ type CQResponse = DispatchNodeResultType<{ [NodeOutputKeyEnum.cqResult]: string; }>; -type ActionProps = Props & { cqModel: LLMModelItemType }; +type ActionProps = Props & { + cqModel: LLMModelItemType; + lastMemory?: ClassifyQuestionAgentItemType; +}; /* request openai chat */ export const dispatchClassifyQuestion = async (props: Props): Promise => { const { externalProvider, + runningAppInfo, node: { nodeId, name }, histories, params: { model, history = 6, agents, userChatInput } @@ -52,10 +54,16 @@ export const dispatchClassifyQuestion = async (props: Props): Promise item.key !== result.key) .map((item) => getHandleId(nodeId, 'source', item.key)), + [DispatchNodeResponseKeyEnum.memories]: { + [memoryKey]: result + }, [DispatchNodeResponseKeyEnum.nodeResponse]: { totalPoints: externalProvider.openaiAccount?.key ? 0 : totalPoints, model: modelName, @@ -100,26 +111,35 @@ const completions = async ({ cqModel, externalProvider, histories, - params: { agents, systemPrompt = '', userChatInput }, - node: { version } + lastMemory, + params: { agents, systemPrompt = '', userChatInput } }: ActionProps) => { const messages: ChatItemType[] = [ + { + obj: ChatRoleEnum.System, + value: [ + { + type: ChatItemValueTypeEnum.text, + text: { + content: getCQSystemPrompt({ + systemPrompt, + memory: lastMemory ? JSON.stringify(lastMemory) : '', + typeList: JSON.stringify( + agents.map((item) => ({ id: item.key, description: item.value })) + ) + }) + } + } + ] + }, + ...histories, { obj: ChatRoleEnum.Human, value: [ { type: ChatItemValueTypeEnum.text, text: { - content: replaceVariable(cqModel.customCQPrompt || getCQPrompt(version), { - systemPrompt: systemPrompt || 'null', - typeList: agents - .map((item) => `{"类型ID":"${item.key}", "问题类型":"${item.value}"}`) - .join('\n------\n'), - history: histories - .map((item) => `${item.obj}:${chatValue2RuntimePrompt(item.value).text}`) - .join('\n------\n'), - question: userChatInput - }) + content: userChatInput } } ] @@ -145,7 +165,6 @@ const completions = async ({ const { text: answer, usage } = await formatLLMResponse(response); // console.log(JSON.stringify(chats2GPTMessages({ messages, reserveId: false }), null, 2)); - // console.log(answer, '----'); const id = agents.find((item) => answer.includes(item.key))?.key || diff --git a/packages/service/core/workflow/dispatch/agent/extract.ts b/packages/service/core/workflow/dispatch/agent/extract.ts index 6f437adb4..041c09a24 100644 --- a/packages/service/core/workflow/dispatch/agent/extract.ts +++ b/packages/service/core/workflow/dispatch/agent/extract.ts @@ -13,7 +13,7 @@ import type { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { NodeOutputKeyEnum, toolValueTypeList } from '@fastgpt/global/core/workflow/constants'; import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type'; -import { replaceVariable, sliceJsonStr } from '@fastgpt/global/common/string/tools'; +import { sliceJsonStr } from '@fastgpt/global/common/string/tools'; import { type LLMModelItemType } from '@fastgpt/global/core/ai/model.d'; import { getHistories } from '../utils'; import { getLLMModel } from '../../../ai/model'; @@ -21,12 +21,10 @@ import { formatModelChars2Points } from '../../../../support/wallet/usage/utils' import json5 from 'json5'; import { type ChatCompletionMessageParam, - type ChatCompletionTool, - type UnStreamChatType + type ChatCompletionTool } from '@fastgpt/global/core/ai/type'; import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/global/core/ai/constants'; import { type DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type'; -import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt'; import { llmCompletionsBodyFormat, formatLLMResponse } from '../../../ai/utils'; import { ModelTypeEnum } from '../../../../../global/core/ai/model'; import { @@ -46,14 +44,15 @@ type Response = DispatchNodeResultType<{ [NodeOutputKeyEnum.contextExtractFields]: string; }>; -type ActionProps = Props & { extractModel: LLMModelItemType }; +type ActionProps = Props & { extractModel: LLMModelItemType; lastMemory?: Record }; const agentFunName = 'request_function'; export async function dispatchContentExtract(props: Props): Promise { const { externalProvider, - node: { name }, + runningAppInfo, + node: { nodeId, name }, histories, params: { content, history = 6, model, description, extractKeys } } = props; @@ -65,18 +64,27 @@ export async function dispatchContentExtract(props: Props): Promise { const extractModel = getLLMModel(model); const chatHistories = getHistories(history, histories); + const memoryKey = `${runningAppInfo.id}-${nodeId}`; + // @ts-ignore + const lastMemory = chatHistories[chatHistories.length - 1]?.memories?.[memoryKey] as Record< + string, + any + >; + const { arg, inputTokens, outputTokens } = await (async () => { if (extractModel.toolChoice) { return toolChoice({ ...props, histories: chatHistories, - extractModel + extractModel, + lastMemory }); } return completions({ ...props, histories: chatHistories, - extractModel + extractModel, + lastMemory }); })(); @@ -121,6 +129,9 @@ export async function dispatchContentExtract(props: Props): Promise { return { [NodeOutputKeyEnum.success]: success, [NodeOutputKeyEnum.contextExtractFields]: JSON.stringify(arg), + [DispatchNodeResponseKeyEnum.memories]: { + [memoryKey]: arg + }, ...arg, [DispatchNodeResponseKeyEnum.nodeResponse]: { totalPoints: externalProvider.openaiAccount?.key ? 0 : totalPoints, @@ -144,39 +155,7 @@ export async function dispatchContentExtract(props: Props): Promise { }; } -const getFunctionCallSchema = async ({ - extractModel, - histories, - params: { content, extractKeys, description }, - node: { version } -}: ActionProps) => { - const messages: ChatItemType[] = [ - ...histories, - { - obj: ChatRoleEnum.Human, - value: [ - { - type: ChatItemValueTypeEnum.text, - text: { - content: replaceVariable(getExtractJsonToolPrompt(version), { - description, - content - }) - } - } - ] - } - ]; - const adaptMessages = chats2GPTMessages({ messages, reserveId: false }); - const filterMessages = await filterGPTMessageByMaxContext({ - messages: adaptMessages, - maxContext: extractModel.maxContext - }); - const requestMessages = await loadRequestMessages({ - messages: filterMessages, - useVision: false - }); - +const getJsonSchema = ({ params: { extractKeys } }: ActionProps) => { const properties: Record< string, { @@ -194,32 +173,71 @@ const getFunctionCallSchema = async ({ ...(item.enum ? { enum: item.enum.split('\n').filter(Boolean) } : {}) }; }); - // function body - const agentFunction = { - name: agentFunName, - description: '需要执行的函数', - parameters: { - type: 'object', - properties, - required: [] - } - }; - return { - filterMessages: requestMessages, - agentFunction - }; + return properties; }; const toolChoice = async (props: ActionProps) => { - const { externalProvider, extractModel } = props; + const { + externalProvider, + extractModel, + histories, + params: { content, description }, + lastMemory + } = props; - const { filterMessages, agentFunction } = await getFunctionCallSchema(props); + const messages: ChatItemType[] = [ + { + obj: ChatRoleEnum.System, + value: [ + { + type: ChatItemValueTypeEnum.text, + text: { + content: getExtractJsonToolPrompt({ + systemPrompt: description, + memory: lastMemory ? JSON.stringify(lastMemory) : undefined + }) + } + } + ] + }, + ...histories, + { + obj: ChatRoleEnum.Human, + value: [ + { + type: ChatItemValueTypeEnum.text, + text: { + content + } + } + ] + } + ]; + const adaptMessages = chats2GPTMessages({ messages, reserveId: false }); + const filterMessages = await filterGPTMessageByMaxContext({ + messages: adaptMessages, + maxContext: extractModel.maxContext + }); + const requestMessages = await loadRequestMessages({ + messages: filterMessages, + useVision: false + }); + + const schema = getJsonSchema(props); const tools: ChatCompletionTool[] = [ { type: 'function', - function: agentFunction + function: { + name: agentFunName, + description: '需要执行的函数', + parameters: { + type: 'object', + properties: schema, + required: [] + } + } } ]; @@ -228,12 +246,13 @@ const toolChoice = async (props: ActionProps) => { stream: true, model: extractModel.model, temperature: 0.01, - messages: filterMessages, + messages: requestMessages, tools, tool_choice: { type: 'function', function: { name: agentFunName } } }, extractModel ); + const { response } = await createChatCompletion({ body, userKey: externalProvider.openaiAccount @@ -242,7 +261,7 @@ const toolChoice = async (props: ActionProps) => { const arg: Record = (() => { try { - return json5.parse(toolCalls?.[0]?.function?.arguments || ''); + return json5.parse(toolCalls?.[0]?.function?.arguments || text || ''); } catch (error) { console.log('body', body); console.log('AI response', text, toolCalls?.[0]?.function); @@ -267,40 +286,39 @@ const toolChoice = async (props: ActionProps) => { }; }; -const completions = async ({ - extractModel, - externalProvider, - histories, - params: { content, extractKeys, description = 'No special requirements' }, - node: { version } -}: ActionProps) => { +const completions = async (props: ActionProps) => { + const { + extractModel, + externalProvider, + histories, + lastMemory, + params: { content, description } + } = props; + const messages: ChatItemType[] = [ + { + obj: ChatRoleEnum.System, + value: [ + { + type: ChatItemValueTypeEnum.text, + text: { + content: getExtractJsonPrompt({ + systemPrompt: description, + memory: lastMemory ? JSON.stringify(lastMemory) : undefined, + schema: JSON.stringify(getJsonSchema(props)) + }) + } + } + ] + }, + ...histories, { obj: ChatRoleEnum.Human, value: [ { type: ChatItemValueTypeEnum.text, text: { - content: replaceVariable( - extractModel.customExtractPrompt || getExtractJsonPrompt(version), - { - description, - json: extractKeys - .map((item) => { - const valueType = item.valueType || 'string'; - if (valueType !== 'string' && valueType !== 'number') { - item.enum = undefined; - } - - return `{"type":${item.valueType || 'string'}, "key":"${item.key}", "description":"${item.desc}" ${ - item.enum ? `, "enum":"[${item.enum.split('\n')}]"` : '' - }}`; - }) - .join('\n'), - text: `${histories.map((item) => `${item.obj}:${chatValue2RuntimePrompt(item.value).text}`).join('\n')} -Human: ${content}` - } - ) + content } } ] diff --git a/packages/service/core/workflow/dispatch/index.ts b/packages/service/core/workflow/dispatch/index.ts index 17c3b870d..05e892f8b 100644 --- a/packages/service/core/workflow/dispatch/index.ts +++ b/packages/service/core/workflow/dispatch/index.ts @@ -223,6 +223,7 @@ export async function dispatchWorkFlow(data: Props): Promise = {}; // Workflow node memories /* Store special response field */ function pushStore( @@ -235,7 +236,8 @@ export async function dispatchWorkFlow(data: Props): Promise 0 ? system_memories : undefined, durationSeconds }; } catch (error) { diff --git a/packages/service/core/workflow/dispatch/plugin/run.ts b/packages/service/core/workflow/dispatch/plugin/run.ts index c774200ce..518907773 100644 --- a/packages/service/core/workflow/dispatch/plugin/run.ts +++ b/packages/service/core/workflow/dispatch/plugin/run.ts @@ -80,32 +80,33 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise item.moduleType === FlowNodeTypeEnum.pluginOutput); if (output) { output.moduleLogo = plugin.avatar; @@ -119,6 +120,7 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise => { ? query : runtimePrompt2ChatsValue({ files: userInputFiles, text: userChatInput }); - const { flowResponses, flowUsages, assistantResponses, runTimes, workflowInteractiveResponse } = - await dispatchWorkFlow({ - ...props, - lastInteractive: childrenInteractive, - // Rewrite stream mode - ...(system_forbid_stream - ? { - stream: false, - workflowStreamResponse: undefined - } - : {}), - runningAppInfo: { - id: String(appData._id), - teamId: String(appData.teamId), - tmbId: String(appData.tmbId), - isChildApp: true - }, - runtimeNodes, - runtimeEdges, - histories: chatHistories, - variables: childrenRunVariables, - query: theQuery, - chatConfig - }); + const { + flowResponses, + flowUsages, + assistantResponses, + runTimes, + workflowInteractiveResponse, + system_memories + } = await dispatchWorkFlow({ + ...props, + lastInteractive: childrenInteractive, + // Rewrite stream mode + ...(system_forbid_stream + ? { + stream: false, + workflowStreamResponse: undefined + } + : {}), + runningAppInfo: { + id: String(appData._id), + teamId: String(appData.teamId), + tmbId: String(appData.tmbId), + isChildApp: true + }, + runtimeNodes, + runtimeEdges, + histories: chatHistories, + variables: childrenRunVariables, + query: theQuery, + chatConfig + }); const completeMessages = chatHistories.concat([ { @@ -165,6 +171,7 @@ export const dispatchRunAppNode = async (props: Props): Promise => { const usagePoints = flowUsages.reduce((sum, item) => sum + (item.totalPoints || 0), 0); return { + system_memories, [DispatchNodeResponseKeyEnum.interactive]: workflowInteractiveResponse ? { type: 'childrenInteractive', diff --git a/packages/service/core/workflow/dispatch/plugin/runTool.ts b/packages/service/core/workflow/dispatch/plugin/runTool.ts index 891ae3719..4f6801ee3 100644 --- a/packages/service/core/workflow/dispatch/plugin/runTool.ts +++ b/packages/service/core/workflow/dispatch/plugin/runTool.ts @@ -6,11 +6,14 @@ import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runti import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { MCPClient } from '../../../app/mcp'; import { getErrText } from '@fastgpt/global/common/error/utils'; +import { type StoreSecretValueType } from '@fastgpt/global/common/secret/type'; +import { getSecretValue } from '../../../../common/secret/utils'; type RunToolProps = ModuleDispatchProps<{ toolData: { name: string; url: string; + headerSecret: StoreSecretValueType; }; }>; @@ -27,7 +30,12 @@ export const dispatchRunTool = async (props: RunToolProps): Promise { - // const testData = [ - // // 基本字符串替换 - // { - // body: `{"name":"{{name}}","age":"18"}`, - // variables: [{ key: '{{name}}', value: '测试' }], - // result: `{"name":"测试","age":"18"}` - // }, - // // 特殊字符处理 - // { - // body: `{"text":"{{text}}"}`, - // variables: [{ key: '{{text}}', value: '包含"引号"和\\反斜杠' }], - // result: `{"text":"包含\\"引号\\"和\\反斜杠"}` - // }, - // // 数字类型处理 - // { - // body: `{"count":{{count}},"price":{{price}}}`, - // variables: [ - // { key: '{{count}}', value: '42' }, - // { key: '{{price}}', value: '99.99' } - // ], - // result: `{"count":42,"price":99.99}` - // }, - // // 布尔值处理 - // { - // body: `{"isActive":{{isActive}},"hasData":{{hasData}}}`, - // variables: [ - // { key: '{{isActive}}', value: 'true' }, - // { key: '{{hasData}}', value: 'false' } - // ], - // result: `{"isActive":true,"hasData":false}` - // }, - // // 对象类型处理 - // { - // body: `{"user":{{user}},"user2":"{{user2}}"}`, - // variables: [ - // { key: '{{user}}', value: `{"id":1,"name":"张三"}` }, - // { key: '{{user2}}', value: `{"id":1,"name":"张三"}` } - // ], - // result: `{"user":{"id":1,"name":"张三"},"user2":"{\\"id\\":1,\\"name\\":\\"张三\\"}"}` - // }, - // // 数组类型处理 - // { - // body: `{"items":{{items}}}`, - // variables: [{ key: '{{items}}', value: '[1, 2, 3]' }], - // result: `{"items":[1,2,3]}` - // }, - // // null 和 undefined 处理 - // { - // body: `{"nullValue":{{nullValue}},"undefinedValue":{{undefinedValue}}}`, - // variables: [ - // { key: '{{nullValue}}', value: 'null' }, - // { key: '{{undefinedValue}}', value: 'undefined' } - // ], - // result: `{"nullValue":null,"undefinedValue":null}` - // }, - // // 嵌套JSON结构 - // { - // body: `{"data":{"nested":{"value":"{{nestedValue}}"}}}`, - // variables: [{ key: '{{nestedValue}}', value: '嵌套值' }], - // result: `{"data":{"nested":{"value":"嵌套值"}}}` - // }, - // // 多变量替换 - // { - // body: `{"first":"{{first}}","second":"{{second}}","third":{{third}}}`, - // variables: [ - // { key: '{{first}}', value: '第一' }, - // { key: '{{second}}', value: '第二' }, - // { key: '{{third}}', value: '3' } - // ], - // result: `{"first":"第一","second":"第二","third":3}` - // }, - // // JSON字符串作为变量值 - // { - // body: `{"config":{{config}}}`, - // variables: [{ key: '{{config}}', value: '{"setting":"enabled","mode":"advanced"}' }], - // result: `{"config":{"setting":"enabled","mode":"advanced"}}` - // } - // ]; - - // for (let i = 0; i < testData.length; i++) { - // const item = testData[i]; - // let bodyStr = item.body; - // for (const variable of item.variables) { - // const isQuote = isVariableInQuotes(bodyStr, variable.key); - // bodyStr = bodyStr.replace(variable.key, valToStr(variable.value, isQuote)); - // } - // bodyStr = bodyStr.replace(/(".*?")\s*:\s*undefined\b/g, '$1:null'); - - // console.log(bodyStr === item.result, i); - // if (bodyStr !== item.result) { - // console.log(bodyStr); - // console.log(item.result); - // } else { - // try { - // JSON.parse(item.result); - // } catch (error) { - // console.log('反序列化异常', i, item.result); - // } - // } - // } - // }; - // bodyTest(); // 1. Replace {{key.key}} variables const regex1 = /\{\{\$([^.]+)\.([^$]+)\$\}\}/g; @@ -313,16 +213,13 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise { + const publicHeaders = await (async () => { try { const contentType = contentTypeMap[httpContentType]; if (contentType) { httpHeader = [{ key: 'Content-Type', value: contentType, type: 'string' }, ...httpHeader]; } - if (!httpHeader || httpHeader.length === 0) return {}; - // array return httpHeader.reduce((acc: Record, item) => { const key = replaceStringVariables(item.key); const value = replaceStringVariables(item.value); @@ -333,6 +230,9 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise, item) => { const key = replaceStringVariables(item.key); @@ -418,7 +318,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise 0 ? params : undefined, body: Object.keys(formattedRequestBody).length > 0 ? formattedRequestBody : undefined, - headers: Object.keys(headers).length > 0 ? headers : undefined, + headers: Object.keys(publicHeaders).length > 0 ? publicHeaders : undefined, httpResult: rawResponse }, [DispatchNodeResponseKeyEnum.toolResponses]: @@ -486,7 +386,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise 0 ? params : undefined, body: Object.keys(formattedRequestBody).length > 0 ? formattedRequestBody : undefined, - headers: Object.keys(headers).length > 0 ? headers : undefined, + headers: Object.keys(publicHeaders).length > 0 ? publicHeaders : undefined, httpResult: { error: formatHttpError(error) } }, [NodeOutputKeyEnum.httpRawResponse]: getErrText(error) diff --git a/packages/service/core/workflow/dispatch/type.d.ts b/packages/service/core/workflow/dispatch/type.d.ts index eca03516d..1fabdb5e8 100644 --- a/packages/service/core/workflow/dispatch/type.d.ts +++ b/packages/service/core/workflow/dispatch/type.d.ts @@ -25,7 +25,8 @@ export type DispatchFlowResponse = { [DispatchNodeResponseKeyEnum.toolResponses]: ToolRunResponseItemType; [DispatchNodeResponseKeyEnum.assistantResponses]: AIChatItemValueItemType[]; [DispatchNodeResponseKeyEnum.runTimes]: number; - newVariables: Record; + [DispatchNodeResponseKeyEnum.memories]?: Record; + [DispatchNodeResponseKeyEnum.newVariables]: Record; durationSeconds: number; }; diff --git a/packages/service/core/workflow/dispatch/utils.ts b/packages/service/core/workflow/dispatch/utils.ts index 2f387c9d9..296e51bfa 100644 --- a/packages/service/core/workflow/dispatch/utils.ts +++ b/packages/service/core/workflow/dispatch/utils.ts @@ -164,11 +164,18 @@ export const rewriteRuntimeWorkFlow = ( const toolList = toolSetNode.inputs.find((input) => input.key === 'toolSetData')?.value?.toolList || []; const url = toolSetNode.inputs.find((input) => input.key === 'toolSetData')?.value?.url; + const headerSecret = toolSetNode.inputs.find((input) => input.key === 'toolSetData')?.value + ?.headerSecret; const incomingEdges = edges.filter((edge) => edge.target === toolSetNode.nodeId); for (const tool of toolList) { - const newToolNode = getMCPToolRuntimeNode({ avatar: toolSetNode.avatar, tool, url }); + const newToolNode = getMCPToolRuntimeNode({ + avatar: toolSetNode.avatar, + tool, + url, + headerSecret + }); nodes.push({ ...newToolNode, name: `${toolSetNode.name} / ${tool.name}` }); diff --git a/packages/web/components/common/Icon/icons/close.svg b/packages/web/components/common/Icon/icons/close.svg index 8beb0440a..0518ad681 100644 --- a/packages/web/components/common/Icon/icons/close.svg +++ b/packages/web/components/common/Icon/icons/close.svg @@ -1,3 +1,5 @@ - - - + + + \ No newline at end of file diff --git a/packages/web/components/common/Icon/icons/core/chat/sendFill.svg b/packages/web/components/common/Icon/icons/core/chat/sendFill.svg index 5fb488bd9..938dbf715 100644 --- a/packages/web/components/common/Icon/icons/core/chat/sendFill.svg +++ b/packages/web/components/common/Icon/icons/core/chat/sendFill.svg @@ -1,5 +1,3 @@ - - + + \ No newline at end of file diff --git a/packages/web/components/common/Icon/icons/stop.svg b/packages/web/components/common/Icon/icons/stop.svg index 915cfbef8..2c57ba147 100644 --- a/packages/web/components/common/Icon/icons/stop.svg +++ b/packages/web/components/common/Icon/icons/stop.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/packages/web/i18n/en/account_bill.json b/packages/web/i18n/en/account_bill.json index 20b4af4c8..f90e6b9c9 100644 --- a/packages/web/i18n/en/account_bill.json +++ b/packages/web/i18n/en/account_bill.json @@ -1,10 +1,12 @@ { + "Invoice_document": "Invoice documents", "all": "all", "back": "return", "bank_account": "Account opening account", "bank_name": "Bank of deposit", "bill_detail": "Bill details", "bill_record": "billing records", + "click_to_download": "Click to download", "company_address": "Company address", "company_phone": "Company phone number", "completed": "Completed", diff --git a/packages/web/i18n/en/common.json b/packages/web/i18n/en/common.json index 89a0273bd..374176b41 100644 --- a/packages/web/i18n/en/common.json +++ b/packages/web/i18n/en/common.json @@ -96,6 +96,10 @@ "all_quotes": "All quotes", "all_result": "Full Results", "app_not_version": "This application has not been published, please publish it first", + "auth_config": "Authentication", + "auth_type": "Authentication type", + "auth_type.Custom": "Customize", + "auth_type.None": "None", "back": "Back", "base_config": "Basic Configuration", "bill_already_processed": "Order has been processed", @@ -260,7 +264,7 @@ "core.app.have_saved": "Saved", "core.app.logs.Source And Time": "Source & Time", "core.app.more": "View More", - "core.app.name": "name", + "name": "name", "core.app.no_app": "No Apps Yet, Create One Now!", "core.app.not_saved": "Not Saved", "core.app.outLink.Can Drag": "Icon Can Be Dragged", @@ -728,6 +732,7 @@ "core.workflow.inputType.switch": "Switch", "core.workflow.inputType.textInput": "Text Input box", "core.workflow.inputType.textarea": "Multi-line Input Box", + "key": "key", "core.workflow.publish.OnRevert version": "Click to Revert to This Version", "core.workflow.publish.OnRevert version confirm": "Confirm to Revert to This Version? The configuration of the editing version will be saved, and a new release version will be created for the reverted version.", "core.workflow.publish.histories": "Release Records", @@ -736,7 +741,7 @@ "core.workflow.template.Search": "Search", "core.workflow.tool.Handle": "Tool Connector", "core.workflow.tool.Select Tool": "Select Tool", - "core.workflow.value": "Value", + "value": "Value", "core.workflow.variable": "Variable", "create": "Create", "create_failed": "Create failed", @@ -797,6 +802,8 @@ "delete_success": "Deleted Successfully", "delete_warning": "Deletion Warning", "embedding_model_not_config": "No index model is detected", + "enable_auth": "Enable authentication", + "error.Create failed": "Create failed", "error.code_error": "Verification code error", "error.fileNotFound": "File not found~", "error.inheritPermissionError": "Inherit permission Error", @@ -827,6 +834,7 @@ "get_QR_failed": "Failed to Get QR Code", "get_app_failed": "Failed to Retrieve App", "get_laf_failed": "Failed to Retrieve Laf Function List", + "had_auth_value": "Filled in", "has_verification": "Verified, Click to Unbind", "have_done": "Completed", "import_failed": "Import Failed", @@ -1001,6 +1009,7 @@ "save_failed": "save_failed", "save_success": "Saved Successfully", "scan_code": "Scan the QR code to pay", + "secret_tips": "The value will not return plaintext again after saving", "select_file_failed": "File Selection Failed", "select_reference_variable": "Select Reference Variable", "select_template": "Select Template", diff --git a/packages/web/i18n/zh-CN/account_bill.json b/packages/web/i18n/zh-CN/account_bill.json index 76bac1668..f067e2ae3 100644 --- a/packages/web/i18n/zh-CN/account_bill.json +++ b/packages/web/i18n/zh-CN/account_bill.json @@ -1,10 +1,12 @@ { + "Invoice_document": "发票文件", "all": "全部", "back": "返回", "bank_account": "开户账号", "bank_name": "开户银行", "bill_detail": "账单详情", "bill_record": "账单记录", + "click_to_download": "点击下载", "company_address": "公司地址", "company_phone": "公司电话", "completed": "已完成", diff --git a/packages/web/i18n/zh-CN/common.json b/packages/web/i18n/zh-CN/common.json index 22577be6c..3d7ddf154 100644 --- a/packages/web/i18n/zh-CN/common.json +++ b/packages/web/i18n/zh-CN/common.json @@ -96,6 +96,10 @@ "all_quotes": "全部引用", "all_result": "完整结果", "app_not_version": " 该应用未发布过,请先发布应用", + "auth_config": "鉴权配置", + "auth_type": "鉴权类型", + "auth_type.Custom": "自定义", + "auth_type.None": "无", "back": "返回", "base_config": "基础配置", "bill_already_processed": "订单已处理", @@ -215,7 +219,6 @@ "core.app.Interval timer run": "定时执行", "core.app.Interval timer tip": "可定时执行应用", "core.app.Make a brief introduction of your app": "给你的 AI 应用一个介绍", - "core.app.name": "名称", "core.app.Name and avatar": "头像 & 名称", "core.app.Publish": "发布", "core.app.Publish Confirm": "确认发布应用?会立即更新所有发布渠道的应用状态。", @@ -261,6 +264,7 @@ "core.app.have_saved": "已保存", "core.app.logs.Source And Time": "来源 & 时间", "core.app.more": "查看更多", + "name": "名称", "core.app.no_app": "还没有应用,快去创建一个吧!", "core.app.not_saved": "未保存", "core.app.outLink.Can Drag": "图标可拖拽", @@ -728,6 +732,7 @@ "core.workflow.inputType.switch": "开关", "core.workflow.inputType.textInput": "文本输入框", "core.workflow.inputType.textarea": "多行输入框", + "key": "键", "core.workflow.publish.OnRevert version": "点击回退到该版本", "core.workflow.publish.OnRevert version confirm": "确认回退至该版本?会为您保存编辑中版本的配置,并为回退版本创建一个新的发布版本。", "core.workflow.publish.histories": "发布记录", @@ -736,7 +741,7 @@ "core.workflow.template.Search": "搜索", "core.workflow.tool.Handle": "工具连接器", "core.workflow.tool.Select Tool": "选择工具", - "core.workflow.value": "值", + "value": "值", "core.workflow.variable": "变量", "create": "去创建", "create_failed": "创建失败", @@ -797,6 +802,8 @@ "delete_success": "删除成功", "delete_warning": "删除警告", "embedding_model_not_config": "检测到没有可用的索引模型", + "enable_auth": "启用鉴权", + "error.Create failed": "创建失败", "error.code_error": "验证码错误", "error.fileNotFound": "文件找不到了~", "error.inheritPermissionError": "权限继承错误", @@ -827,6 +834,7 @@ "get_QR_failed": "获取二维码失败", "get_app_failed": "获取应用失败", "get_laf_failed": "获取Laf函数列表失败", + "had_auth_value": "已填写", "has_verification": "已验证,点击取消绑定", "have_done": "已完成", "import_failed": "导入失败", @@ -1001,6 +1009,7 @@ "save_failed": "保存异常", "save_success": "保存成功", "scan_code": "扫码支付", + "secret_tips": "值保存后不会再次明文返回", "select_file_failed": "选择文件异常", "select_reference_variable": "选择引用变量", "select_template": "选择模板", diff --git a/packages/web/i18n/zh-Hant/account_bill.json b/packages/web/i18n/zh-Hant/account_bill.json index 4f96960ad..aa3a92d61 100644 --- a/packages/web/i18n/zh-Hant/account_bill.json +++ b/packages/web/i18n/zh-Hant/account_bill.json @@ -1,10 +1,12 @@ { + "Invoice_document": "發票文件", "all": "全部", "back": "返回", "bank_account": "開戶帳號", "bank_name": "開戶銀行", "bill_detail": "帳單詳細資訊", "bill_record": "帳單記錄", + "click_to_download": "點擊下載", "company_address": "公司地址", "company_phone": "公司電話", "completed": "已完成", diff --git a/packages/web/i18n/zh-Hant/common.json b/packages/web/i18n/zh-Hant/common.json index e2b120b6f..55264c703 100644 --- a/packages/web/i18n/zh-Hant/common.json +++ b/packages/web/i18n/zh-Hant/common.json @@ -96,6 +96,10 @@ "all_quotes": "全部引用", "all_result": "完整結果", "app_not_version": "該應用未發布過,請先發布應用", + "auth_config": "鑑權配置", + "auth_type": "鑑權類型", + "auth_type.Custom": "自定義", + "auth_type.None": "無", "back": "返回", "base_config": "基本設定", "bill_already_processed": "訂單已處理", @@ -260,7 +264,7 @@ "core.app.have_saved": "已儲存", "core.app.logs.Source And Time": "來源與時間", "core.app.more": "檢視更多", - "core.app.name": "名稱", + "name": "名稱", "core.app.no_app": "還沒有應用程式,快來建立一個吧!", "core.app.not_saved": "未儲存", "core.app.outLink.Can Drag": "圖示可拖曳", @@ -728,6 +732,7 @@ "core.workflow.inputType.switch": "開關", "core.workflow.inputType.textInput": "文字輸入框", "core.workflow.inputType.textarea": "多行輸入框", + "key": "鍵", "core.workflow.publish.OnRevert version": "點選回復至此版本", "core.workflow.publish.OnRevert version confirm": "確認回復至此版本?將為您儲存編輯中版本的設定,並為回復版本建立一個新的發布版本。", "core.workflow.publish.histories": "發布記錄", @@ -736,7 +741,7 @@ "core.workflow.template.Search": "搜尋", "core.workflow.tool.Handle": "工具聯結器", "core.workflow.tool.Select Tool": "選擇工具", - "core.workflow.value": "值", + "value": "值", "core.workflow.variable": "變數", "create": "建立", "create_failed": "建立失敗", @@ -797,6 +802,8 @@ "delete_success": "刪除成功", "delete_warning": "刪除警告", "embedding_model_not_config": "偵測到沒有可用的索引模型", + "enable_auth": "啟用鑑權", + "error.Create failed": "建立失敗", "error.code_error": "驗證碼錯誤", "error.fileNotFound": "找不到檔案", "error.inheritPermissionError": "繼承權限錯誤", @@ -827,6 +834,7 @@ "get_QR_failed": "取得 QR Code 失敗", "get_app_failed": "取得應用程式失敗", "get_laf_failed": "取得 LAF 函式清單失敗", + "had_auth_value": "已填寫", "has_verification": "已驗證,點選解除綁定", "have_done": "已完成", "import_failed": "匯入失敗", @@ -1001,6 +1009,7 @@ "save_failed": "儲存失敗", "save_success": "儲存成功", "scan_code": "掃碼支付", + "secret_tips": "值保存後不會再次明文返回", "select_file_failed": "選擇檔案失敗", "select_reference_variable": "選擇引用變數", "select_template": "選擇範本", diff --git a/packages/web/styles/theme.ts b/packages/web/styles/theme.ts index ac7dd2292..53b96f12c 100644 --- a/packages/web/styles/theme.ts +++ b/packages/web/styles/theme.ts @@ -255,7 +255,6 @@ const Button = defineStyleConfig({ grayGhost: { color: 'myGray.500', fontWeight: '500', - p: 0, bg: 'transparent', transition: 'background 0.1s', _hover: { @@ -816,7 +815,8 @@ export const theme = extendTheme({ md: '0.5rem', semilg: '0.625rem', lg: '0.75rem', - xl: '1rem' + xl: '1rem', + xxl: '1.25rem' }, shadows: { 1: '0px 1px 2px 0px rgba(19, 51, 107, 0.05), 0px 0px 1px 0px rgba(19, 51, 107, 0.08)', diff --git a/projects/app/.env.template b/projects/app/.env.template index b577c1ad9..cfe77df89 100644 --- a/projects/app/.env.template +++ b/projects/app/.env.template @@ -5,6 +5,8 @@ DEFAULT_ROOT_PSW=123456 DB_MAX_LINK=5 # 文件阅读时的密钥 FILE_TOKEN_KEY=filetokenkey +# 密钥加密key +AES256_SECRET_KEY=fastgptsecret # root key, 最高权限 ROOT_KEY=fdafasd # openai 基本地址,可用作中转。 diff --git a/projects/app/data/model.json b/projects/app/data/model.json index 774ba60c5..1e29974a8 100644 --- a/projects/app/data/model.json +++ b/projects/app/data/model.json @@ -26,9 +26,7 @@ "usedInExtractFields": true, // 是否用于内容提取(务必保证至少有一个为true) "usedInToolCall": true, // 是否用于工具调用(务必保证至少有一个为true) "toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。) - "functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式) - "customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型 - "customExtractPrompt": "", // 自定义内容提取提示词 + "functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式) // 自定义文本分类提示词(不支持工具和函数调用的模型 // 自定义内容提取提示词 "defaultSystemChatPrompt": "", // 对话默认携带的系统提示词 "defaultConfig": {}, // 请求API时,挟带一些默认配置(比如 GLM4 的 top_p) "fieldMap": {} // 字段映射(o1 模型需要把 max_tokens 映射为 max_completion_tokens) @@ -50,8 +48,6 @@ "usedInToolCall": true, "toolChoice": true, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": {}, "fieldMap": {} @@ -73,8 +69,6 @@ "usedInToolCall": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": { "temperature": 1, @@ -99,8 +93,6 @@ "usedInToolCall": true, "toolChoice": false, "functionCall": false, - "customCQPrompt": "", - "customExtractPrompt": "", "defaultSystemChatPrompt": "", "defaultConfig": { "temperature": 1, diff --git a/projects/app/package.json b/projects/app/package.json index b66ad1e12..abc17b82c 100644 --- a/projects/app/package.json +++ b/projects/app/package.json @@ -1,6 +1,6 @@ { "name": "app", - "version": "4.9.11", + "version": "4.9.12", "private": false, "scripts": { "dev": "next dev", diff --git a/projects/app/src/components/common/secret/HeaderAuthConfig.tsx b/projects/app/src/components/common/secret/HeaderAuthConfig.tsx new file mode 100644 index 000000000..aa2043634 --- /dev/null +++ b/projects/app/src/components/common/secret/HeaderAuthConfig.tsx @@ -0,0 +1,381 @@ +import type { ButtonProps } from '@chakra-ui/react'; +import { + Box, + Button, + Flex, + FormControl, + IconButton, + Input, + ModalBody, + ModalFooter, + Slider, + useDisclosure +} from '@chakra-ui/react'; +import { HeaderSecretTypeEnum } from '@fastgpt/global/common/secret/constants'; +import type { SecretValueType, StoreSecretValueType } from '@fastgpt/global/common/secret/type'; +import React, { useEffect, useMemo, useState } from 'react'; +import { useFieldArray, useForm, type UseFormRegister } from 'react-hook-form'; +import { useTranslation } from 'next-i18next'; +import MyIcon from '@fastgpt/web/components/common/Icon'; +import MyModal from '@fastgpt/web/components/common/MyModal'; +import MySelect from '@fastgpt/web/components/common/MySelect'; + +type HeaderSecretConfigType = { + Bearer?: SecretValueType; + Basic?: SecretValueType; + customs?: { + key: string; + value: SecretValueType; + }[]; +}; + +const getShowInput = ({ + secretValue, + editingIndex, + index +}: { + secretValue?: SecretValueType; + editingIndex?: number; + index: number; +}) => { + const hasSecret = !!secretValue?.secret; + const hasValue = !!secretValue?.value; + const isEditing = editingIndex === index; + + return !hasSecret || hasValue || isEditing; +}; + +const AuthValueDisplay = ({ + showInput, + fieldName, + index = 0, + onEdit, + register +}: { + showInput: boolean; + fieldName: string; + index?: number; + onEdit: (index?: number) => void; + register: UseFormRegister; +}) => { + const { t } = useTranslation(); + + return ( + + {showInput ? ( + + + ) : ( + + + + {t('common:had_auth_value')} + + + )} + {!showInput && ( + } + size="sm" + variant="ghost" + color={'myGray.500'} + _hover={{ color: 'primary.600' }} + onClick={() => onEdit(index)} + /> + )} + + ); +}; + +const getSecretType = (config: HeaderSecretConfigType): HeaderSecretTypeEnum => { + if (config.Bearer) { + return HeaderSecretTypeEnum.Bearer; + } else if (config.Basic) { + return HeaderSecretTypeEnum.Basic; + } else if (config.customs && config.customs.length > 0) { + return HeaderSecretTypeEnum.Custom; + } + return HeaderSecretTypeEnum.None; +}; + +const HeaderAuthConfig = ({ + storeHeaderSecretConfig, + onUpdate, + buttonProps +}: { + storeHeaderSecretConfig?: StoreSecretValueType; + onUpdate: (data: StoreSecretValueType) => void; + buttonProps?: ButtonProps; +}) => { + const { t } = useTranslation(); + const headerSecretList = [ + { + label: t('common:auth_type.None'), + value: HeaderSecretTypeEnum.None + }, + { + label: 'Bearer', + value: HeaderSecretTypeEnum.Bearer + }, + { + label: 'Basic', + value: HeaderSecretTypeEnum.Basic + }, + { + label: t('common:auth_type.Custom'), + value: HeaderSecretTypeEnum.Custom + } + ]; + + const { isOpen, onOpen, onClose } = useDisclosure(); + + const headerSecretValue: HeaderSecretConfigType = useMemo(() => { + if (!storeHeaderSecretConfig || Object.keys(storeHeaderSecretConfig).length === 0) { + return {}; + } + + const entries = Object.entries(storeHeaderSecretConfig); + const [key, value] = entries[0]; + + if ( + entries.length === 1 && + (key === HeaderSecretTypeEnum.Bearer || key === HeaderSecretTypeEnum.Basic) + ) { + return { + [key]: { + secret: value.secret, + value: value.value + } + }; + } + + return { + customs: entries.map(([key, value]) => ({ + key, + value: { + secret: value.secret, + value: value.value + } + })) + }; + }, [storeHeaderSecretConfig]); + + const [currentAuthType, setCurrentAuthType] = useState( + getSecretType(headerSecretValue) + ); + + const [editingIndex, setEditingIndex] = useState(); + const { control, register, watch, handleSubmit, reset } = useForm({ + defaultValues: { + Basic: headerSecretValue?.Basic || { secret: '', value: '' }, + Bearer: headerSecretValue?.Bearer || { secret: '', value: '' }, + customs: headerSecretValue?.customs || [] + } + }); + const { + fields: customHeaders, + append: appendHeader, + remove: removeHeader + } = useFieldArray({ + control, + name: 'customs' + }); + const BearerValue = watch('Bearer'); + const BasicValue = watch('Basic'); + + // Add default custom + useEffect(() => { + if (currentAuthType === HeaderSecretTypeEnum.Custom && customHeaders.length === 0) { + appendHeader({ key: '', value: { secret: '', value: '' } }); + } + }, [currentAuthType, customHeaders.length, appendHeader]); + + const onSubmit = async (data: HeaderSecretConfigType) => { + if (!headerSecretValue) return; + + const storeData: StoreSecretValueType = {}; + + if (currentAuthType === HeaderSecretTypeEnum.Bearer) { + storeData.Bearer = { + value: data.Bearer?.value || '', + secret: data.Bearer?.secret || '' + }; + } else if (currentAuthType === HeaderSecretTypeEnum.Basic) { + storeData.Basic = { + value: data.Basic?.value || '', + secret: data.Basic?.secret || '' + }; + } else if (currentAuthType === HeaderSecretTypeEnum.Custom) { + data.customs?.forEach((item) => { + storeData[item.key] = item.value; + }); + } + + onUpdate(storeData); + onClose(); + }; + + return ( + <> + } + onClick={onOpen} + > + {t('common:auth_config')} + + + {isOpen && ( + + + + + {t('common:auth_type')} + + + + + {currentAuthType !== HeaderSecretTypeEnum.None && ( + + {currentAuthType === HeaderSecretTypeEnum.Custom && ( + {t('common:key')} + )} + {t('common:value')} + + )} + + {currentAuthType !== HeaderSecretTypeEnum.None && ( + <> + {currentAuthType === HeaderSecretTypeEnum.Bearer || + currentAuthType === HeaderSecretTypeEnum.Basic ? ( + + ) : ( + + {customHeaders.map((item, index) => { + const headerValue = watch(`customs.${index}.value`); + + return ( + + + + + + {customHeaders.length > 1 && ( + } + size="sm" + variant="ghost" + color={'myGray.500'} + _hover={{ color: 'red.500' }} + isDisabled={customHeaders.length <= 1} + onClick={() => removeHeader(index)} + /> + )} + + ); + })} + + } + variant="whiteBase" + minH={8} + h={8} + onClick={() => appendHeader({ key: '', value: { secret: '', value: '' } })} + > + {t('common:add_new')} + + + )} + + )} + + + + + + + + {t('common:secret_tips')} + + + )} + + ); +}; + +export default React.memo(HeaderAuthConfig); diff --git a/projects/app/src/components/core/app/WelcomeTextConfig.tsx b/projects/app/src/components/core/app/WelcomeTextConfig.tsx index 13bbdf42f..5140dd281 100644 --- a/projects/app/src/components/core/app/WelcomeTextConfig.tsx +++ b/projects/app/src/components/core/app/WelcomeTextConfig.tsx @@ -26,7 +26,7 @@ const WelcomeTextConfig = (props: TextareaProps) => { rows={6} fontSize={'sm'} bg={'myGray.50'} - minW={'384px'} + minW={['auto', '384px']} placeholder={t('common:core.app.tip.welcomeTextTip')} autoHeight minH={100} diff --git a/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx b/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx index 5bdd38225..3b6f3b97a 100644 --- a/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx +++ b/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx @@ -1,6 +1,5 @@ -import { useSystemStore } from '@/web/common/system/useSystemStore'; -import { Box, Flex, Spinner, Textarea } from '@chakra-ui/react'; -import React, { useRef, useEffect, useCallback, useMemo, useState } from 'react'; +import { Box, Flex, Textarea } from '@chakra-ui/react'; +import React, { useRef, useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'next-i18next'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import MyIcon from '@fastgpt/web/components/common/Icon'; @@ -49,6 +48,9 @@ const ChatInput = ({ const { setValue, watch, control } = chatForm; const inputValue = watch('input'); + // Check voice input state + const [mobilePreSpeak, setMobilePreSpeak] = useState(false); + const outLinkAuthData = useContextSelector(ChatBoxContext, (v) => v.outLinkAuthData); const appId = useContextSelector(ChatBoxContext, (v) => v.appId); const chatId = useContextSelector(ChatBoxContext, (v) => v.chatId); @@ -108,146 +110,203 @@ const ChatInput = ({ const RenderTextarea = useMemo( () => ( - 0 ? 1 : 0} pl={[2, 4]}> - {/* file selector */} - {(showSelectFile || showSelectImg) && ( - { - onOpenSelectFile(); + 0 ? 1 : 0}> + {/* Textarea */} + + {/* Prompt Container */} + - )} - {/* input area */} - + ), + [ + TextareaDom, + fileList.length, + handleSend, + inputValue, + isPc, + onSelectFile, + setValue, + showSelectFile, + showSelectImg, + t + ] + ); + + const RenderButtonGroup = useMemo(() => { + const iconSize = { + w: isPc ? '20px' : '16px', + h: isPc ? '20px' : '16px' + }; + + return ( + + {/* Attachment and Voice Group */} + + {/* file selector button */} + {(showSelectFile || showSelectImg) && ( + { + onOpenSelectFile(); + }} + > + + + + onSelectFile({ files })} /> + )} - {/* send and stop icon */} + {/* Voice input button */} + {whisperConfig?.open && !inputValue && ( + { + VoiceInputRef.current?.onSpeak?.(); + }} + > + + + + + )} + + + {/* Divider Container */} + {((whisperConfig?.open && !inputValue) || showSelectFile || showSelectImg) && ( + + + + )} + + {/* Send Button Container */} + { if (isChatting) { return onStop(); @@ -256,56 +315,40 @@ const ChatInput = ({ }} > {isChatting ? ( - + ) : ( - + )} - ), - [ - File, - TextareaDom, - fileList, - handleSend, - hasFileUploading, - havInput, - inputValue, - isChatting, - isPc, - onOpenSelectFile, - onSelectFile, - onStop, - selectFileIcon, - selectFileLabel, - setValue, - showSelectFile, - showSelectImg, - t - ] - ); + ); + }, [ + isPc, + showSelectFile, + showSelectImg, + selectFileLabel, + selectFileIcon, + File, + whisperConfig?.open, + inputValue, + t, + isChatting, + canSendMessage, + onOpenSelectFile, + onSelectFile, + handleSend, + onStop + ]); return ( e.preventDefault()} onDrop={(e) => { e.preventDefault(); @@ -331,53 +374,71 @@ const ChatInput = ({ } }} > - 0 ? '0' : ['14px', '18px']} - pb={['14px', '18px']} + {/* Real Chat Input */} + 0 ? '0' : mobilePreSpeak ? [0, 4] : [3, 4]} + pb={[2, 4]} position={'relative'} - boxShadow={`0 0 10px rgba(0,0,0,0.2)`} - borderRadius={['none', 'md']} + boxShadow={`0px 5px 16px -4px rgba(19, 51, 107, 0.08)`} + borderRadius={['xl', 'xxl']} bg={'white'} overflow={'display'} - {...(isPc - ? { - border: '1px solid', - borderColor: 'rgba(0,0,0,0.12)' - } - : { - borderTop: '1px solid', - borderTopColor: 'rgba(0,0,0,0.15)' - })} + border={'0.5px solid rgba(0, 0, 0, 0.15)'} + borderColor={'rgba(0,0,0,0.12)'} > - {/* Chat input guide box */} - {chatInputGuide.open && ( - { - setValue('input', e); - }} - onSend={(e) => { - handleSend(e); - }} - /> - )} - {/* file preview */} - - + + {/* Chat input guide box */} + {chatInputGuide.open && ( + { + setValue('input', e); + }} + onSend={(e) => { + handleSend(e); + }} + /> + )} + {/* file preview */} + {(!mobilePreSpeak || isPc || inputValue) && ( + + + + )} + + {/* loading spinner */} + + {/* voice input and loading container */} + {!inputValue && ( + { + onSendMessage({ + text: text.trim(), + files: fileList + }); + replaceFiles([]); + }} + resetInputVal={(val) => { + setMobilePreSpeak(false); + resetInputVal({ + text: val, + files: fileList + }); + }} + mobilePreSpeak={mobilePreSpeak} + setMobilePreSpeak={setMobilePreSpeak} + /> + )} + + {RenderTextarea} - {/* voice input and loading container */} - {!inputValue && ( - - )} - - {RenderTextarea} - + {!mobilePreSpeak && {RenderButtonGroup}} + ); diff --git a/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/VoiceInput.tsx b/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/VoiceInput.tsx index 284f3cbf3..68b964477 100644 --- a/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/VoiceInput.tsx +++ b/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/VoiceInput.tsx @@ -6,8 +6,7 @@ import React, { useCallback, useState, forwardRef, - useImperativeHandle, - useMemo + useImperativeHandle } from 'react'; import { useTranslation } from 'next-i18next'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; @@ -20,11 +19,14 @@ import { isMobile } from '@fastgpt/web/common/system/utils'; export interface VoiceInputComponentRef { onSpeak: () => void; + getVoiceInputState: () => { isSpeaking: boolean; isTransCription: boolean }; } type VoiceInputProps = { - onSendMessage: (params: { text: string; files?: any[]; autoTTSResponse?: boolean }) => void; - resetInputVal: (val: { text: string }) => void; + handleSend: (val: string) => void; + resetInputVal: (val: string) => void; + mobilePreSpeak: boolean; + setMobilePreSpeak: React.Dispatch>; }; // PC voice input @@ -40,38 +42,104 @@ const PCVoiceInput = ({ const { t } = useTranslation(); return ( - - - {t('common:core.chat.Speaking')} - - - - {speakingTimeString} - - - stopSpeak(true)} + + {/* Center Waveform Area */} + + + {t('common:core.chat.Speaking')} + + - - - stopSpeak(false)} - /> - - + + + {/* Action Buttons - Bottom */} + + {/* Time Display */} + + {speakingTimeString} + + + {/* Cancel Button */} + + stopSpeak(true)} + > + + + + + {/* Confirm Button */} + + stopSpeak(false)} + > + + + + + ); }; @@ -120,9 +188,9 @@ const MobileVoiceInput = ({ const currentY = touch.pageY; const deltaY = startYRef.current - currentY; - if (deltaY > 90) { + if (deltaY > 60) { setIsCancel(true); - } else if (deltaY <= 90) { + } else if (deltaY <= 60) { setIsCancel(false); } }, @@ -157,8 +225,8 @@ const MobileVoiceInput = ({ transform={'translateY(-50%)'} zIndex={5} name={'core/chat/backText'} - h={'22px'} - w={'22px'} + h={6} + w={6} onClick={onCloseSpeak} /> @@ -166,9 +234,10 @@ const MobileVoiceInput = ({ - + {isCancel ? t('chat:release_cancel') : t('chat:release_send')} @@ -212,7 +281,7 @@ const MobileVoiceInput = ({ }; const VoiceInput = forwardRef( - ({ onSendMessage, resetInputVal }, ref) => { + ({ handleSend, resetInputVal, mobilePreSpeak, setMobilePreSpeak }, ref) => { const { t } = useTranslation(); const isMobileDevice = isMobile(); const { isPc } = useSystem(); @@ -220,7 +289,6 @@ const VoiceInput = forwardRef( const outLinkAuthData = useContextSelector(ChatBoxContext, (v) => v.outLinkAuthData); const appId = useContextSelector(ChatBoxContext, (v) => v.appId); const whisperConfig = useContextSelector(ChatBoxContext, (v) => v.whisperConfig); - const autoTTSResponse = useContextSelector(ChatBoxContext, (v) => v.autoTTSResponse); const canvasRef = useRef(null); const { @@ -234,8 +302,6 @@ const VoiceInput = forwardRef( stream } = useSpeech({ appId, ...outLinkAuthData }); - const [mobilePreSpeak, setMobilePreSpeak] = useState(false); - // Canvas render useEffect(() => { if (!stream) { @@ -290,16 +356,13 @@ const VoiceInput = forwardRef( const finishWhisperTranscription = (text: string) => { if (!text) return; if (whisperConfig?.autoSend) { - onSendMessage({ - text, - autoTTSResponse - }); + handleSend(text); } else { - resetInputVal({ text }); + resetInputVal(text); } }; startSpeak(finishWhisperTranscription); - }, [autoTTSResponse, onSendMessage, resetInputVal, startSpeak, whisperConfig?.autoSend]); + }, [handleSend, resetInputVal, startSpeak, whisperConfig?.autoSend]); const onSpeach = useCallback(() => { if (isMobileDevice) { @@ -307,9 +370,10 @@ const VoiceInput = forwardRef( } else { onStartSpeak(); } - }, [isMobileDevice, onStartSpeak]); + }, [isMobileDevice, onStartSpeak, setMobilePreSpeak]); useImperativeHandle(ref, () => ({ - onSpeak: onSpeach + onSpeak: onSpeach, + getVoiceInputState: () => ({ isSpeaking: isSpeaking || mobilePreSpeak, isTransCription }) })); if (!whisperConfig?.open) return null; @@ -324,7 +388,7 @@ const VoiceInput = forwardRef( left={0} right={0} bottom={0} - bg="white" + bg="transparent" zIndex={5} borderRadius={isPc ? 'md' : ''} onContextMenu={(e) => e.preventDefault()} @@ -348,15 +412,17 @@ const VoiceInput = forwardRef( {isTransCription && ( {t('common:core.chat.Converting to text')} diff --git a/projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx b/projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx index 9a6ae1b92..9a10194f1 100644 --- a/projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx +++ b/projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx @@ -959,6 +959,7 @@ const ChatBox = ({ pb={3} > + {/* chat header */} {showEmpty && } {!!welcomeText && } {/* variable input */} diff --git a/projects/app/src/components/core/chat/ChatContainer/components/FilePreview.tsx b/projects/app/src/components/core/chat/ChatContainer/components/FilePreview.tsx index 8539e561c..cdd318262 100644 --- a/projects/app/src/components/core/chat/ChatContainer/components/FilePreview.tsx +++ b/projects/app/src/components/core/chat/ChatContainer/components/FilePreview.tsx @@ -22,7 +22,7 @@ const RenderFilePreview = ({ 0 ? 2 : 0} gap={'6px'} diff --git a/projects/app/src/pageComponents/account/bill/InvoiceTable.tsx b/projects/app/src/pageComponents/account/bill/InvoiceTable.tsx index 26e8fa651..5ac60bce0 100644 --- a/projects/app/src/pageComponents/account/bill/InvoiceTable.tsx +++ b/projects/app/src/pageComponents/account/bill/InvoiceTable.tsx @@ -1,4 +1,4 @@ -import { getInvoiceRecords } from '@/web/support/wallet/bill/invoice/api'; +import { getInvoiceRecords, readInvoiceFile } from '@/web/support/wallet/bill/invoice/api'; import MyBox from '@fastgpt/web/components/common/MyBox'; import { useTranslation } from 'next-i18next'; import { useState } from 'react'; @@ -22,6 +22,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon'; import dayjs from 'dayjs'; import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/usage/tools'; import MyModal from '@fastgpt/web/components/common/MyModal'; +import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; const InvoiceTable = () => { const { t } = useTranslation(); @@ -135,6 +136,29 @@ function InvoiceDetailModal({ onClose: () => void; }) { const { t } = useTranslation(); + + const { runAsync: handleDownloadInvoice } = useRequest2(async (id: string) => { + const fileInfo = await readInvoiceFile(id); + + // Blob + const byteCharacters = atob(fileInfo.data); + const byteNumbers = new Array(byteCharacters.length); + for (let i = 0; i < byteCharacters.length; i++) { + byteNumbers[i] = byteCharacters.charCodeAt(i); + } + const byteArray = new Uint8Array(byteNumbers); + const blob = new Blob([byteArray], { type: fileInfo.mimeType }); + const fileUrl = URL.createObjectURL(blob); + + // preview + window.open(fileUrl, '_blank'); + + // clean + setTimeout(() => { + URL.revokeObjectURL(fileUrl); + }, 1000); + }); + return ( + {invoice.status === 2 && ( + + {t('account_bill:Invoice_document')} + handleDownloadInvoice(invoice._id)}> + {t('account_bill:click_to_download')} + + + )} diff --git a/projects/app/src/pageComponents/account/model/AddModelBox.tsx b/projects/app/src/pageComponents/account/model/AddModelBox.tsx index 96b2129f9..40cd9e4c5 100644 --- a/projects/app/src/pageComponents/account/model/AddModelBox.tsx +++ b/projects/app/src/pageComponents/account/model/AddModelBox.tsx @@ -38,7 +38,6 @@ import { useSystemStore } from '@/web/common/system/useSystemStore'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import MyModal from '@fastgpt/web/components/common/MyModal'; import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; -import { getCQPrompt, getExtractJsonPrompt } from '@fastgpt/global/core/ai/prompt/agent'; export const AddModelButton = ({ onCreate, @@ -173,6 +172,36 @@ export const ModelEditModal = ({ } ); + const CustomApi = useMemo( + () => ( + <> +
+ + + {t('account:model.request_url')} + + + + + + +
+
+ + + {t('account:model.request_auth')} + + + + + + +
+ + ), + [] + ); + return ( )} -
- - - {t('account:model.request_url')} - - - - - - -
-
- - - {t('account:model.request_auth')} - - - - - - -
+ {!isLLMModel && CustomApi} @@ -666,36 +674,6 @@ export const ModelEditModal = ({ -
- - - {t('account:model.custom_cq_prompt')} - - - - - - -
-
- - - {t('account:model.custom_extract_prompt')} - - - - - - -
@@ -723,6 +701,7 @@ export const ModelEditModal = ({ />
+ {CustomApi} diff --git a/projects/app/src/pageComponents/account/model/ModelDashboard/index.tsx b/projects/app/src/pageComponents/account/model/ModelDashboard/index.tsx index 725f9fab9..bd7aaebb5 100644 --- a/projects/app/src/pageComponents/account/model/ModelDashboard/index.tsx +++ b/projects/app/src/pageComponents/account/model/ModelDashboard/index.tsx @@ -4,7 +4,7 @@ import { Box, Grid, HStack, useTheme } from '@chakra-ui/react'; import MyBox from '@fastgpt/web/components/common/MyBox'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useTranslation } from 'next-i18next'; -import { addDays } from 'date-fns'; +import { addDays, addHours } from 'date-fns'; import dayjs from 'dayjs'; import DateRangePicker, { type DateRangeType @@ -47,24 +47,15 @@ const ChartsBoxStyles: BoxProps = { // Default date range: Past 7 days const getDefaultDateRange = (): DateRangeType => { - const from = addDays(new Date(), -7); - from.setHours(0, 0, 0, 0); + const from = addHours(new Date(), -24); + from.setMinutes(0, 0, 0); // Set minutes to 0 - const to = new Date(); - to.setHours(23, 59, 59, 999); + const to = addHours(new Date(), 1); + to.setMinutes(0, 0, 0); // Set minutes to 0 return { from, to }; }; -const calculateTimeDiffs = (from: Date, to: Date) => { - const startDate = dayjs(from); - const endDate = dayjs(to); - return { - daysDiff: endDate.diff(startDate, 'day'), - hoursDiff: endDate.diff(startDate, 'hour') - }; -}; - const ModelDashboard = ({ Tab }: { Tab: React.ReactNode }) => { const { t } = useTranslation(); const theme = useTheme(); @@ -89,7 +80,7 @@ const ModelDashboard = ({ Tab }: { Tab: React.ReactNode }) => { }>({ channelId: undefined, model: undefined, - timespan: 'day', + timespan: 'hour', dateRange: getDefaultDateRange() }); @@ -159,22 +150,22 @@ const ModelDashboard = ({ Tab }: { Tab: React.ReactNode }) => { return map; }, [systemModelList]); - const computeTimespan = (daysDiff: number, hoursDiff: number) => { + const computeTimespan = (hoursDiff: number) => { const options: { label: string; value: 'minute' | 'hour' | 'day' }[] = []; - if (daysDiff <= 1) { + if (hoursDiff <= 1 * 24) { options.push({ label: t('account_model:timespan_minute'), value: 'minute' }); } - if (daysDiff < 7) { + if (hoursDiff < 7 * 24) { options.push({ label: t('account_model:timespan_hour'), value: 'hour' }); } - if (daysDiff >= 1) { + if (hoursDiff >= 1 * 24) { options.push({ label: t('account_model:timespan_day'), value: 'day' }); } const defaultTimespan: 'minute' | 'hour' | 'day' = (() => { if (hoursDiff < 1) { return 'minute'; - } else if (daysDiff < 2) { + } else if (hoursDiff < 2 * 24) { return 'hour'; } else { return 'day'; @@ -183,7 +174,7 @@ const ModelDashboard = ({ Tab }: { Tab: React.ReactNode }) => { return { options, defaultTimespan }; }; - const [timespanOptions, setTimespanOptions] = useState(computeTimespan(30, 60).options); + const [timespanOptions, setTimespanOptions] = useState(computeTimespan(48).options); // Handle date range change with automatic timespan adjustment const handleDateRangeChange = (dateRange: DateRangeType) => { @@ -191,11 +182,9 @@ const ModelDashboard = ({ Tab }: { Tab: React.ReactNode }) => { // Computed timespan if (dateRange.from && dateRange.to) { - const { daysDiff, hoursDiff } = calculateTimeDiffs(dateRange.from, dateRange.to); - const { options: newTimespanOptions, defaultTimespan: newDefaultTimespan } = computeTimespan( - daysDiff, - hoursDiff - ); + const hoursDiff = dayjs(dateRange.to).diff(dayjs(dateRange.from), 'hour'); + const { options: newTimespanOptions, defaultTimespan: newDefaultTimespan } = + computeTimespan(hoursDiff); setTimespanOptions(newTimespanOptions); newFilterProps.timespan = newDefaultTimespan; diff --git a/projects/app/src/pageComponents/account/thirdParty/WorkflowVariableModal.tsx b/projects/app/src/pageComponents/account/thirdParty/WorkflowVariableModal.tsx index c1b4ff21d..0387072e3 100644 --- a/projects/app/src/pageComponents/account/thirdParty/WorkflowVariableModal.tsx +++ b/projects/app/src/pageComponents/account/thirdParty/WorkflowVariableModal.tsx @@ -52,7 +52,7 @@ const WorkflowVariableModal = ({ - {t('common:core.workflow.value')} + {t('common:value')}
{isPc && ( - + )} diff --git a/projects/app/src/pageComponents/app/detail/MCPTools/EditForm.tsx b/projects/app/src/pageComponents/app/detail/MCPTools/EditForm.tsx index 1824ea401..8fe41de43 100644 --- a/projects/app/src/pageComponents/app/detail/MCPTools/EditForm.tsx +++ b/projects/app/src/pageComponents/app/detail/MCPTools/EditForm.tsx @@ -13,6 +13,8 @@ import Avatar from '@fastgpt/web/components/common/Avatar'; import MyBox from '@fastgpt/web/components/common/MyBox'; import type { getMCPToolsBody } from '@/pages/api/support/mcp/client/getTools'; import { getMCPTools } from '@/web/core/app/api/plugin'; +import HeaderAuthConfig from '@/components/common/secret/HeaderAuthConfig'; +import { type StoreSecretValueType } from '@fastgpt/global/common/secret/type'; const EditForm = ({ url, @@ -20,14 +22,18 @@ const EditForm = ({ toolList, setToolList, currentTool, - setCurrentTool + setCurrentTool, + headerSecret, + setHeaderSecret }: { url: string; setUrl: (url: string) => void; toolList: McpToolConfigType[]; setToolList: (toolList: McpToolConfigType[]) => void; - currentTool: McpToolConfigType | null; + currentTool?: McpToolConfigType; setCurrentTool: (tool: McpToolConfigType) => void; + headerSecret: StoreSecretValueType; + setHeaderSecret: (headerSecret: StoreSecretValueType) => void; }) => { const { t } = useTranslation(); @@ -52,6 +58,14 @@ const EditForm = ({ {t('app:MCP_tools_url')} +
width={'100%'} @@ -403,7 +421,9 @@ export function RenderHttpProps({ contentType, formBody, headersLength, + headerSecret, nodeId, + onChangeNode, paramsLength, requestMethods, selectedTab, diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeVariableUpdate.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeVariableUpdate.tsx index 340ceec6f..32a2f06ff 100644 --- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeVariableUpdate.tsx +++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeVariableUpdate.tsx @@ -182,7 +182,7 @@ const NodeVariableUpdate = ({ data, selected }: NodeProps) => - {t('common:core.workflow.value')} + {t('common:value')} item.renderType === updateItem.renderType)?.label diff --git a/projects/app/src/pageComponents/dashboard/apps/MCPToolsEditModal.tsx b/projects/app/src/pageComponents/dashboard/apps/MCPToolsEditModal.tsx index 872a24c09..a0eb77b95 100644 --- a/projects/app/src/pageComponents/dashboard/apps/MCPToolsEditModal.tsx +++ b/projects/app/src/pageComponents/dashboard/apps/MCPToolsEditModal.tsx @@ -26,10 +26,13 @@ import { AppListContext } from './context'; import { useContextSelector } from 'use-context-selector'; import { type McpToolConfigType } from '@fastgpt/global/core/app/type'; import type { getMCPToolsBody } from '@/pages/api/support/mcp/client/getTools'; +import HeaderAuthConfig from '@/components/common/secret/HeaderAuthConfig'; +import { type StoreSecretValueType } from '@fastgpt/global/common/secret/type'; export type MCPToolSetData = { url: string; toolList: McpToolConfigType[]; + headerSecret: StoreSecretValueType; }; export type EditMCPToolsProps = { @@ -49,6 +52,7 @@ const MCPToolsEditModal = ({ onClose }: { onClose: () => void }) => { name: '', mcpData: { url: '', + headerSecret: {}, toolList: [] } } @@ -63,6 +67,7 @@ const MCPToolsEditModal = ({ onClose }: { onClose: () => void }) => { avatar: data.avatar, toolList: data.mcpData.toolList, url: data.mcpData.url, + headerSecret: data.mcpData.headerSecret, parentId }); }, @@ -131,9 +136,26 @@ const MCPToolsEditModal = ({ onClose }: { onClose: () => void }) => { /> - - {t('app:MCP_tools_url')} - + + {t('app:MCP_tools_url')} + + { + setValue('mcpData.headerSecret', data); + }} + buttonProps={{ + size: 'sm', + variant: 'grayGhost' + }} + /> +