diff --git a/document/content/docs/self-host/upgrading/4-14/41411.mdx b/document/content/docs/self-host/upgrading/4-14/41411.mdx index c19b448e4c..d3790f8c55 100644 --- a/document/content/docs/self-host/upgrading/4-14/41411.mdx +++ b/document/content/docs/self-host/upgrading/4-14/41411.mdx @@ -3,15 +3,27 @@ title: 'V4.14.11(进行中)' description: 'FastGPT V4.14.11 更新说明' --- -{/* ## 升级指南 +## 升级指南 ### 1. 更新镜像 tag - 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.14.11 -- 更新 fastpgt-pro(商业版) 镜像 tag: v4.14.1011 +- 更新 fastpgt-pro(商业版) 镜像 tag: v4.14.11 - 更新 code-sandbox 镜像 tag: v4.14.11 - 更新 fastgpt-plugin 镜像 tag: v0.6.0 -- 更新 Aiproxy 镜像 tag: v0.5.3 */} +- 更新 Aiproxy 镜像 tag: v0.5.3 +### 2. 更新环境变量 + +> 以下环境变量均设置了默认值,可不填或不改 + +```dotenv +STREAM_RESUME_TTL_SECONDS=300 # Redis 流式镜像续期:生成中(秒) +STREAM_RESUME_POST_COMPLETE_TTL_SECONDS=30 # 流结束后缩短 TTL,便于回收(秒) +STREAM_RESUME_REDIS_MAXMEMORY_RATIO=0.5 # 当 Redis 已用内存 / maxmemory 达到该阈值时,停止为新请求创建流恢复镜像 +STREAM_RESUME_REDIS_MEMORY_CHECK_INTERVAL_MS=5000 # Redis 内存水位检测缓存时长(毫秒),避免每个流请求都调用 INFO MEMORY + +WORKFLOW_PARALLEL_MAX_CONCURRENCY=10 # 最大并发数的上限值,不能超过 WORKFLOW_MAX_LOOP_TIMES 变量 +``` ## 🚀 新增内容 @@ -39,4 +51,4 @@ description: 'FastGPT V4.14.11 更新说明' 8. 工作流代码运行节点,AI 生成代码后,会讲输出值的 id 全部替换,优化成相同 key 的 id 不替换。 9. 工作流中,父级节点受到辅助线自动对齐时候,其子节点位置会偏移。 10. 评估列表权限过滤未覆盖继承权限。 -11. MCP 工具和 Http 工具 raw schema 未成功保存,导致工具调用时候,schema 不准确。 \ No newline at end of file +11. MCP 工具和 Http 工具 raw schema 未成功保存,导致工具调用时候,schema 不准确。 diff --git a/document/content/docs/self-host/upgrading/4-14/41412.mdx b/document/content/docs/self-host/upgrading/4-14/41412.mdx index e141c6a58b..4fe40dcfe0 100644 --- a/document/content/docs/self-host/upgrading/4-14/41412.mdx +++ b/document/content/docs/self-host/upgrading/4-14/41412.mdx @@ -3,12 +3,17 @@ title: 'V4.14.12' description: 'FastGPT V4.14.12 更新说明' --- +## 升级指南 +### 1. 更新镜像 tag +- 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.14.12 +- 更新 fastpgt-pro(商业版) 镜像 tag: v4.14.12 ## 🐛 修复 1. 知识库三级目录 path 接口报 zod 校验出错。 2. v1/completions 接口 dataId 异常,导致 api 调用时候,对话日志里无法获取到运行详情。 +3. 对话 Agent 应用敏感信息过滤勾选框无法取消。 ## 🚀 新增内容 @@ -18,4 +23,3 @@ description: 'FastGPT V4.14.12 更新说明' ## ⚙️ 优化 1. skill 接口错误处理。 - diff --git a/document/data/doc-last-modified.json b/document/data/doc-last-modified.json index 6ac822caed..8d41fc2baa 100644 --- a/document/data/doc-last-modified.json +++ b/document/data/doc-last-modified.json @@ -225,7 +225,7 @@ "document/content/docs/self-host/upgrading/4-14/41410.en.mdx": "2026-03-31T23:15:29+08:00", "document/content/docs/self-host/upgrading/4-14/41410.mdx": "2026-04-18T20:47:39+08:00", "document/content/docs/self-host/upgrading/4-14/41411.mdx": "2026-04-18T20:47:39+08:00", - "document/content/docs/self-host/upgrading/4-14/41412.mdx": "2026-04-20T15:54:50+08:00", + "document/content/docs/self-host/upgrading/4-14/41412.mdx": "2026-04-20T16:57:11+08:00", "document/content/docs/self-host/upgrading/4-14/4142.en.mdx": "2026-03-03T17:39:47+08:00", "document/content/docs/self-host/upgrading/4-14/4142.mdx": "2026-03-03T17:39:47+08:00", "document/content/docs/self-host/upgrading/4-14/4143.en.mdx": "2026-03-03T17:39:47+08:00", diff --git a/packages/web/i18n/en/common.json b/packages/web/i18n/en/common.json index 56c38a5bf5..1503f8801e 100644 --- a/packages/web/i18n/en/common.json +++ b/packages/web/i18n/en/common.json @@ -782,6 +782,7 @@ "failed": "Failed", "field_name": "Field Name", "filter_sensitive_info": "Filter sensitive information", + "filter_sensitive_info_tip": "Sensitive information includes temporary keys used by system tools (leaks may cause unexpected charges, so export carefully) and dataset information configured in dataset search nodes.", "folder.empty": "No More Items in This Directory", "folder.open_dataset": "Open Dataset", "folder_description": "Folder Description", diff --git a/packages/web/i18n/zh-CN/common.json b/packages/web/i18n/zh-CN/common.json index be20354d6c..f10f5facf5 100644 --- a/packages/web/i18n/zh-CN/common.json +++ b/packages/web/i18n/zh-CN/common.json @@ -782,6 +782,7 @@ "failed": "失败", "field_name": "字段名", "filter_sensitive_info": "过滤敏感信息", + "filter_sensitive_info_tip": "敏感信息范围:【系统工具】使用的临时密钥(泄露可能导致意外扣费,请谨慎导出),以及【知识库搜索节点】配置的知识库信息", "folder.empty": "这个目录已经没东西可选了~", "folder.open_dataset": "打开知识库", "folder_description": "文件夹描述", diff --git a/packages/web/i18n/zh-Hant/common.json b/packages/web/i18n/zh-Hant/common.json index 2be528b13b..a53601f1c9 100644 --- a/packages/web/i18n/zh-Hant/common.json +++ b/packages/web/i18n/zh-Hant/common.json @@ -776,6 +776,7 @@ "failed": "失敗", "field_name": "欄位名稱", "filter_sensitive_info": "過濾敏感信息", + "filter_sensitive_info_tip": "敏感資訊範圍:【系統工具】使用的臨時密鑰(外洩可能導致意外扣費,請謹慎匯出),以及【知識庫搜尋節點】配置的知識庫資訊", "folder.empty": "此目錄中沒有更多項目了", "folder.open_dataset": "開啟知識庫", "folder_description": "資料夾描述", diff --git a/projects/app/src/pageComponents/app/detail/Edit/FormComponent/AppCard.tsx b/projects/app/src/pageComponents/app/detail/Edit/FormComponent/AppCard.tsx index a6e96434f5..7f942a9425 100644 --- a/projects/app/src/pageComponents/app/detail/Edit/FormComponent/AppCard.tsx +++ b/projects/app/src/pageComponents/app/detail/Edit/FormComponent/AppCard.tsx @@ -49,6 +49,7 @@ const AppCard = ({ const appId = appDetail._id; const { feConfigs } = useSystemStore(); const [TeamTagsSet, setTeamTagsSet] = useState(); + const [filterSensitiveInfo, setFilterSensitiveInfo] = useState(true); // transition to workflow const [transitionCreateNew, setTransitionCreateNew] = useState(); @@ -148,6 +149,8 @@ const AppCard = ({ appName={appDetail.name} appForm={appForm} chatConfig={appDetail.chatConfig} + filterSensitiveInfo={filterSensitiveInfo} + onFilterSensitiveInfoChange={setFilterSensitiveInfo} /> ) diff --git a/projects/app/src/pageComponents/app/detail/ExportConfigPopover.tsx b/projects/app/src/pageComponents/app/detail/ExportConfigPopover.tsx index 537a5abaff..c38e7a0c35 100644 --- a/projects/app/src/pageComponents/app/detail/ExportConfigPopover.tsx +++ b/projects/app/src/pageComponents/app/detail/ExportConfigPopover.tsx @@ -13,16 +13,13 @@ import { filterSensitiveFormData } from '@/web/core/app/utils'; import { type RequireOnlyOne } from '@fastgpt/global/common/type/utils'; import { type StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node'; import { type StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge'; +import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; -const ExportConfigPopover = ({ - appForm, - getWorkflowData, - - chatConfig, - appName -}: { +type ExportConfigPopoverProps = { appName: string; chatConfig?: AppChatConfigType; + filterSensitiveInfo?: boolean; + onFilterSensitiveInfoChange?: (value: boolean) => void; } & RequireOnlyOne<{ getWorkflowData: () => | { @@ -31,11 +28,32 @@ const ExportConfigPopover = ({ } | undefined; appForm: AppFormEditFormType; -}>) => { +}>; + +const ExportConfigPopover = ({ + appForm, + getWorkflowData, + chatConfig, + appName, + filterSensitiveInfo: filterSensitiveInfoProp, + onFilterSensitiveInfoChange +}: ExportConfigPopoverProps) => { const { t } = useTranslation(); const { copyData } = useCopyData(); - const [filterSensitiveInfo, setFilterSensitiveInfo] = useState(true); + const [localFilterSensitiveInfo, setLocalFilterSensitiveInfo] = useState(true); + const filterSensitiveInfo = filterSensitiveInfoProp ?? localFilterSensitiveInfo; + + const setFilterSensitiveInfo = useCallback( + (value: boolean) => { + onFilterSensitiveInfoChange?.(value); + + if (filterSensitiveInfoProp === undefined) { + setLocalFilterSensitiveInfo(value); + } + }, + [filterSensitiveInfoProp, onFilterSensitiveInfoChange] + ); const onExportWorkflow = useCallback( async (mode: 'copy' | 'json') => { @@ -91,7 +109,7 @@ const ExportConfigPopover = ({ offset={[0, 20]} hasArrow trigger={'hover'} - w={'8.6rem'} + w={'8.8rem'} Trigger={ e.stopPropagation()}> @@ -137,6 +155,7 @@ const ExportConfigPopover = ({ setFilterSensitiveInfo(!filterSensitiveInfo)} > {t('common:filter_sensitive_info')} + e.stopPropagation()} + onMouseDown={(e) => e.stopPropagation()} + > + + )} diff --git a/projects/app/src/web/core/app/utils.ts b/projects/app/src/web/core/app/utils.ts index 7ec792f5cb..fe8a5cb645 100644 --- a/projects/app/src/web/core/app/utils.ts +++ b/projects/app/src/web/core/app/utils.ts @@ -14,7 +14,14 @@ export function filterSensitiveFormData(appForm: AppFormEditFormType) { const defaultAppForm = getDefaultAppForm(); return { ...appForm, - dataset: defaultAppForm.dataset + dataset: defaultAppForm.dataset, + selectedTools: appForm.selectedTools.map((tool) => ({ + ...tool, + inputs: tool.inputs.map((input) => ({ + ...input, + value: input.key === NodeInputKeyEnum.systemInputConfig ? undefined : input.value + })) + })) }; } diff --git a/projects/app/test/web/core/app/utils.test.ts b/projects/app/test/web/core/app/utils.test.ts index 200233b4b8..c76fe8f96d 100644 --- a/projects/app/test/web/core/app/utils.test.ts +++ b/projects/app/test/web/core/app/utils.test.ts @@ -96,6 +96,15 @@ describe('form2AppWorkflow', () => { describe('filterSensitiveFormData', () => { it('should filter sensitive data from app form', () => { + const toolSecretValue = { + type: 'manual', + value: { + apiKey: { + secret: '', + value: 'secret-key' + } + } + }; const appForm: AppFormEditFormType = { aiSettings: { [NodeInputKeyEnum.aiModel]: 'gpt-4', @@ -123,15 +132,49 @@ describe('filterSensitiveFormData', () => { datasetSearchExtensionModel: '', datasetSearchExtensionBg: '' }, - selectedTools: [], + selectedTools: [ + { + id: 'tool-1', + pluginId: 'plugin-1', + flowNodeType: FlowNodeTypeEnum.tool, + templateType: 'other', + name: 'Weather Tool', + avatar: '', + intro: '', + inputs: [ + { + key: NodeInputKeyEnum.systemInputConfig, + value: toolSecretValue, + renderTypeList: [], + valueType: 'any' + }, + { + key: NodeInputKeyEnum.history, + value: 5, + renderTypeList: [], + valueType: 'number' + } + ], + outputs: [] + } as any + ], chatConfig: {} }; const result = filterSensitiveFormData(appForm); const defaultForm = getDefaultAppForm(); + const resultSecretInput = result.selectedTools[0].inputs.find( + (input) => input.key === NodeInputKeyEnum.systemInputConfig + ); + const resultHistoryInput = result.selectedTools[0].inputs.find( + (input) => input.key === NodeInputKeyEnum.history + ); expect(result.dataset).toEqual(defaultForm.dataset); expect(result.aiSettings).toEqual(appForm.aiSettings); + expect(resultSecretInput?.value).toBeUndefined(); + expect(resultHistoryInput?.value).toBe(5); + expect(appForm.selectedTools[0].inputs[0].value).toEqual(toolSecretValue); }); });