diff --git a/docSite/content/zh-cn/docs/development/docker.md b/docSite/content/zh-cn/docs/development/docker.md index 435d28eff838..9e777ffaed43 100644 --- a/docSite/content/zh-cn/docs/development/docker.md +++ b/docSite/content/zh-cn/docs/development/docker.md @@ -35,6 +35,8 @@ weight: 707 ### Milvus版本 +暂不推荐,部分系统存在精度丢失,等待修复。 + 对于千万级以上向量性能更优秀。 [点击查看 Milvus 官方推荐配置](https://milvus.io/docs/prerequisite-docker.md) @@ -49,6 +51,8 @@ weight: 707 ### zilliz cloud版本 +暂不推荐,部分系统存在精度丢失,等待修复。 + 亿级以上向量首选。 由于向量库使用了 Cloud,无需占用本地资源,无需太关注。 diff --git a/docSite/content/zh-cn/docs/development/upgrading/4812.md b/docSite/content/zh-cn/docs/development/upgrading/4812.md index 14510046152b..e058e011dbeb 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4812.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4812.md @@ -7,18 +7,23 @@ toc: true weight: 812 --- +## 更新指南 + + ## 更新说明 1. 新增 - 全局变量支持数字类型,支持配置默认值和部分输入框参数。 2. 新增 - 插件自定义输入,文本输入框、数字输入框、选择框、开关,默认都支持作为变量引用。 -3. 新增 - FE_DOMAIN 环境变量,配置该环境变量后,上传文件/图片会补全后缀后得到完整地址。(可解决 docx 文件图片链接,有时会无法被模型识别问题) -4. 新增 - 工具调用支持交互模式 +3. 新增 - FE_DOMAIN 环境变量,配置该环境变量后,上传文件/图片会补全后缀后得到完整地址。(可解决 docx 文件图片链接,有时模型会伪造图片域名) +4. 新增 - 工具调用支持使用交互节点 5. 新增 - Debug 模式支持输入全局变量 6. 新增 - chat OpenAPI 文档 7. 新增 - wiki 搜索插件 8. 新增 - Google 搜索插件 9. 新增 - 数据库连接和操作插件 10. 新增 - Cookie 隐私协议提示 -11. 修复 - 文件后缀判断,去除 query 影响。 -12. 修复 - AI 响应为空时,会造成 LLM 历史记录合并。 -13. 修复 - 用户交互节点未阻塞流程。 +11. 新增 - HTTP 节点支持 JSONPath 表达式 +12. 修复 - 文件后缀判断,去除 query 影响。 +13. 修复 - AI 响应为空时,会造成 LLM 历史记录合并。 +14. 修复 - 用户交互节点未阻塞流程。 +15. 修复 - 新建 APP,有时候会导致空指针报错。 diff --git a/docSite/content/zh-cn/docs/workflow/modules/http.md b/docSite/content/zh-cn/docs/workflow/modules/http.md index 9b0dc84c8a54..0285bf849dbe 100644 --- a/docSite/content/zh-cn/docs/workflow/modules/http.md +++ b/docSite/content/zh-cn/docs/workflow/modules/http.md @@ -120,10 +120,12 @@ HTTP 模块会向对应的地址发送一个 `HTTP` 请求,实际操作与 Pos ### 如何获取返回值 -从图中可以看出,FastGPT可以添加多个返回值,这个返回值并不代表接口的返回值,而是代表`如何解析接口返回值`,可以通过 key 来`提取`接口响应的值。例如: +从图中可以看出,FastGPT可以添加多个返回值,这个返回值并不代表接口的返回值,而是代表`如何解析接口返回值`,可以通过 `JSON path` 的语法,来`提取`接口响应的值。 + +语法可以参考: https://github.com/JSONPath-Plus/JSONPath?tab=readme-ov-file {{< tabs tabTotal="2" >}} -{{< tab tabName="接口响应格式" >}} +{{< tab tabName="接口响应示例" >}} {{< markdownify >}} ```json @@ -148,23 +150,23 @@ HTTP 模块会向对应的地址发送一个 `HTTP` 请求,实际操作与 Pos {{< /markdownify >}} {{< /tab >}} -{{< tab tabName="FastGPT 转化后的格式" >}} +{{< tab tabName="提取示例" >}} {{< markdownify >}} ```json { - "message": "测试", - "data.user": { "name": "xxx", "age": 12 }, - "data.user.name": "xxx", - "data.user.age": 12, - "data.list": [ { "name": "xxx", "age": 50 }, [{ "test": 22 }] ], - "data.list[0]": { "name": "xxx", "age": 50 }, - "data.list[0].name": "xxx", - "data.list[0].age": 50, - "data.list[1]": [ { "test": 22 } ], - "data.list[1][0]": { "test": 22 }, - "data.list[1][0].test": 22, - "data.psw": "xxx" + "$.message": "测试", + "$.data.user": { "name": "xxx", "age": 12 }, + "$.data.user.name": "xxx", + "$.data.user.age": 12, + "$.data.list": [ { "name": "xxx", "age": 50 }, [{ "test": 22 }] ], + "$.data.list[0]": { "name": "xxx", "age": 50 }, + "$.data.list[0].name": "xxx", + "$.data.list[0].age": 50, + "$.data.list[1]": [ { "test": 22 } ], + "$.data.list[1][0]": { "test": 22 }, + "$.data.list[1][0].test": 22, + "$.data.psw": "xxx" } ``` @@ -250,4 +252,4 @@ export default async function (ctx: FunctionContext) { - [谷歌搜索](/docs/workflow/examples/google_search/) - [发送飞书webhook](/docs/workflow/examples/feishu_webhook/) -- [实验室预约(操作数据库)](/docs/workflow/examples/lab_appointment/) \ No newline at end of file +- [实验室预约(操作数据库)](/docs/workflow/examples/lab_appointment/) diff --git a/packages/global/core/workflow/template/system/http468.ts b/packages/global/core/workflow/template/system/http468.ts index a31a9cbefbc8..18df6f9015e3 100644 --- a/packages/global/core/workflow/template/system/http468.ts +++ b/packages/global/core/workflow/template/system/http468.ts @@ -114,7 +114,9 @@ export const HttpNode468: FlowNodeTemplateType = { ], outputs: [ { - ...Output_Template_AddOutput + ...Output_Template_AddOutput, + label: i18nT('workflow:http_extract_output'), + description: i18nT('workflow:http_extract_output_description') }, { id: NodeOutputKeyEnum.error, diff --git a/packages/plugins/package.json b/packages/plugins/package.json index 353dbb8acfcf..3120ad41e1a8 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -10,6 +10,7 @@ "expr-eval": "^2.0.2", "lodash": "^4.17.21", "mysql2": "^3.11.3", + "json5": "^2.2.3", "pg": "^8.10.0", "wikijs": "^6.4.1" }, diff --git a/packages/plugins/src/drawing/baseChart/index.ts b/packages/plugins/src/drawing/baseChart/index.ts index 4cd745e53ec0..06d62ac6a5db 100644 --- a/packages/plugins/src/drawing/baseChart/index.ts +++ b/packages/plugins/src/drawing/baseChart/index.ts @@ -1,4 +1,8 @@ import * as echarts from 'echarts'; +import json5 from 'json5'; +import { getFileSavePath } from '../../../utils'; +import * as fs from 'fs'; +import { SystemPluginSpecialResponse } from '../../../type.d'; type Props = { title: string; @@ -8,7 +12,7 @@ type Props = { }; type Response = Promise<{ - result: string; + result: SystemPluginSpecialResponse; }>; type SeriesData = { @@ -37,8 +41,8 @@ const generateChart = async (title: string, xAxis: string, yAxis: string, chartT let parsedXAxis: string[] = []; let parsedYAxis: number[] = []; try { - parsedXAxis = JSON.parse(xAxis); - parsedYAxis = JSON.parse(yAxis); + parsedXAxis = json5.parse(xAxis); + parsedYAxis = json5.parse(yAxis); } catch (error: any) { console.error('解析数据时出错:', error); return Promise.reject('Data error'); @@ -78,16 +82,26 @@ const generateChart = async (title: string, xAxis: string, yAxis: string, chartT chart.setOption(option); // 生成 Base64 图像 - const base64Image = chart.getDataURL({ type: 'png' }); + const base64Image = chart.getDataURL(); + const svgData = decodeURIComponent(base64Image.split(',')[1]); + + const fileName = `chart_${Date.now()}.svg`; + const filePath = getFileSavePath(fileName); + fs.writeFileSync(filePath, svgData); // 释放图表实例 chart.dispose(); - return base64Image; + return filePath; }; const main = async ({ title, xAxis, yAxis, chartType }: Props): Response => { + const filePath = await generateChart(title, xAxis, yAxis, chartType); return { - result: await generateChart(title, xAxis, yAxis, chartType) + result: { + type: 'SYSTEM_PLUGIN_FILE', + path: filePath, + contentType: 'image/svg+xml' + } }; }; diff --git a/packages/plugins/src/drawing/baseChart/template.json b/packages/plugins/src/drawing/baseChart/template.json index 3f58be5c6883..5ff6013ea1c4 100644 --- a/packages/plugins/src/drawing/baseChart/template.json +++ b/packages/plugins/src/drawing/baseChart/template.json @@ -50,10 +50,10 @@ "canEdit": true, "key": "xAxis", "label": "xAxis", - "description": "x轴数据,例如:['A', 'B', 'C']", + "description": "x轴数据,例如:[\"A\", \"B\", \"C\"]", "defaultValue": "", "required": true, - "toolDescription": "x轴数据,例如:['A', 'B', 'C']", + "toolDescription": "x轴数据,例如:[\"A\", \"B\", \"C\"]", "list": [ { "label": "", diff --git a/packages/plugins/type.d.ts b/packages/plugins/type.d.ts index 271e8e1ca0a2..b125a9fa713f 100644 --- a/packages/plugins/type.d.ts +++ b/packages/plugins/type.d.ts @@ -1,7 +1,13 @@ import { PluginTemplateType } from '@fastgpt/global/core/plugin/type.d'; +import { systemPluginResponseEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type'; export type SystemPluginResponseType = Promise>; +export type SystemPluginSpecialResponse = { + type: 'SYSTEM_PLUGIN_FILE'; + path: string; + contentType: string; +}; declare global { var systemPlugins: SystemPluginTemplateItemType[]; diff --git a/packages/plugins/utils.ts b/packages/plugins/utils.ts new file mode 100644 index 000000000000..c86bfcc8ffc9 --- /dev/null +++ b/packages/plugins/utils.ts @@ -0,0 +1,15 @@ +import path from 'path'; +import * as fs from 'fs'; + +const isProduction = process.env.NODE_ENV === 'production'; + +export const getFileSavePath = (name: string) => { + if (isProduction) { + return `/app/plugin_file/${name}`; + } + const filePath = path.join(process.cwd(), 'local', 'plugin_file', name); + + fs.mkdirSync(path.dirname(filePath), { recursive: true }); + + return filePath; +}; diff --git a/packages/service/common/string/tiktoken/index.ts b/packages/service/common/string/tiktoken/index.ts index 391d3a2433bd..a53d11b6430b 100644 --- a/packages/service/common/string/tiktoken/index.ts +++ b/packages/service/common/string/tiktoken/index.ts @@ -25,7 +25,7 @@ export const countGptMessagesTokens = async ( number >({ name: WorkerNameEnum.countGptMessagesTokens, - maxReservedThreads: global.systemEnv?.tokenWorkers || 20 + maxReservedThreads: global.systemEnv?.tokenWorkers || 50 }); const total = await workerController.run({ messages, tools, functionCall }); diff --git a/packages/service/common/vectorStore/milvus/class.ts b/packages/service/common/vectorStore/milvus/class.ts index c56980402321..e9634b0b15b7 100644 --- a/packages/service/common/vectorStore/milvus/class.ts +++ b/packages/service/common/vectorStore/milvus/class.ts @@ -24,10 +24,7 @@ export class MilvusCtrl { global.milvusClient = new MilvusClient({ address: MILVUS_ADDRESS, - token: MILVUS_TOKEN, - loaderOptions: { - longs: Function - } + token: MILVUS_TOKEN }); addLog.info(`Milvus connected`); @@ -329,19 +326,10 @@ export class MilvusCtrl { id: string; teamId: string; datasetId: string; - int64: { - low: bigint; - high: bigint; - unsigned: boolean; - }; }[]; return rows.map((item) => ({ - id: String({ - low: BigInt(item.int64.low), - high: BigInt(item.int64.high), - unsigned: item.int64.unsigned - }), + id: String(item.id), teamId: item.teamId, datasetId: item.datasetId })); diff --git a/packages/service/core/chat/utils.ts b/packages/service/core/chat/utils.ts index 79f193b070e2..9443ccde51f6 100644 --- a/packages/service/core/chat/utils.ts +++ b/packages/service/core/chat/utils.ts @@ -222,10 +222,9 @@ export const loadRequestMessages = async ({ }; } } - // if (item.role === ChatCompletionRequestMessageRoleEnum.Assistant) { - // if (item.content === undefined && !item.tool_calls && !item.function_call) return; - // if (Array.isArray(item.content) && item.content.length === 0) return; - // } + if (item.role === ChatCompletionRequestMessageRoleEnum.Assistant) { + if (item.content === undefined && !item.tool_calls && !item.function_call) return; + } return item; }) diff --git a/packages/service/core/workflow/dispatch/tools/http468.ts b/packages/service/core/workflow/dispatch/tools/http468.ts index 6b52e384ab1a..90505930cd70 100644 --- a/packages/service/core/workflow/dispatch/tools/http468.ts +++ b/packages/service/core/workflow/dispatch/tools/http468.ts @@ -18,6 +18,11 @@ import { textAdaptGptResponse } from '@fastgpt/global/core/workflow/runtime/util import { getSystemPluginCb } from '../../../../../plugins/register'; import { ContentTypes } from '@fastgpt/global/core/workflow/constants'; import { replaceEditorVariable } from '@fastgpt/global/core/workflow/utils'; +import { uploadFile } from '../../../../common/file/gridfs/controller'; +import { ReadFileBaseUrl } from '@fastgpt/global/common/file/constants'; +import { createFileToken } from '../../../../support/permission/controller'; +import { removeFilesByPaths } from '../../../../common/file/utils'; +import { JSONPath } from 'jsonpath-plus'; type PropsArrType = { key: string; @@ -55,7 +60,7 @@ const contentTypeMap = { export const dispatchHttp468Request = async (props: HttpRequestProps): Promise => { let { - runningAppInfo: { id: appId }, + runningAppInfo: { id: appId, teamId, tmbId }, chatId, responseChatItemId, variables, @@ -204,7 +209,12 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise { const systemPluginCb = await getSystemPluginCb(); if (systemPluginCb[httpReqUrl]) { - const pluginResult = await systemPluginCb[httpReqUrl](requestBody); + const pluginResult = await replaceSystemPluginResponse({ + response: await systemPluginCb[httpReqUrl](requestBody), + teamId, + tmbId + }); + return { formatResponse: pluginResult, rawResponse: pluginResult @@ -222,11 +232,10 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise = {}; - for (const key in formatResponse) { - const output = node.outputs.find((item) => item.key === key); - if (!output) continue; - results[key] = valueTypeFormat(formatResponse[key], output.valueType); - } + node.outputs.forEach((item) => { + const key = item.key.startsWith('$') ? item.key : `$.${item.key}`; + results[item.key] = JSONPath({ path: key, json: formatResponse })[0]; + }); if (typeof formatResponse[NodeOutputKeyEnum.answerText] === 'string') { workflowStreamResponse?.({ @@ -293,80 +302,8 @@ async function fetchData({ data: ['POST', 'PUT', 'PATCH'].includes(method) ? body : undefined }); - /* - parse the json: - { - user: { - name: 'xxx', - age: 12 - }, - list: [ - { - name: 'xxx', - age: 50 - }, - [{ test: 22 }] - ], - psw: 'xxx' - } - - result: { - 'user': { name: 'xxx', age: 12 }, - 'user.name': 'xxx', - 'user.age': 12, - 'list': [ { name: 'xxx', age: 50 }, [ [Object] ] ], - 'list[0]': { name: 'xxx', age: 50 }, - 'list[0].name': 'xxx', - 'list[0].age': 50, - 'list[1]': [ { test: 22 } ], - 'list[1][0]': { test: 22 }, - 'list[1][0].test': 22, - 'psw': 'xxx' - } - */ - const parseJson = (obj: Record, prefix = '') => { - let result: Record = {}; - - if (Array.isArray(obj)) { - for (let i = 0; i < obj.length; i++) { - result[`${prefix}[${i}]`] = obj[i]; - - if (Array.isArray(obj[i])) { - result = { - ...result, - ...parseJson(obj[i], `${prefix}[${i}]`) - }; - } else if (typeof obj[i] === 'object') { - result = { - ...result, - ...parseJson(obj[i], `${prefix}[${i}].`) - }; - } - } - } else if (typeof obj == 'object') { - for (const key in obj) { - result[`${prefix}${key}`] = obj[key]; - - if (Array.isArray(obj[key])) { - result = { - ...result, - ...parseJson(obj[key], `${prefix}${key}`) - }; - } else if (typeof obj[key] === 'object') { - result = { - ...result, - ...parseJson(obj[key], `${prefix}${key}.`) - }; - } - } - } - - return result; - }; - return { - formatResponse: - typeof response === 'object' && !Array.isArray(response) ? parseJson(response) : {}, + formatResponse: typeof response === 'object' ? response : {}, rawResponse: response }; } @@ -405,3 +342,40 @@ function removeUndefinedSign(obj: Record) { } return obj; } + +// Replace some special response from system plugin +async function replaceSystemPluginResponse({ + response, + teamId, + tmbId +}: { + response: Record; + teamId: string; + tmbId: string; +}) { + for await (const key of Object.keys(response)) { + if (typeof response[key] === 'object' && response[key].type === 'SYSTEM_PLUGIN_FILE') { + const fileObj = response[key]; + const filename = fileObj.path.split('/').pop() || `${tmbId}-${Date.now()}`; + try { + const fileId = await uploadFile({ + teamId, + tmbId, + bucketName: 'chat', + path: fileObj.path, + filename, + contentType: fileObj.contentType, + metadata: {} + }); + response[key] = `${ReadFileBaseUrl}?filename=${filename}&token=${await createFileToken({ + bucketName: 'chat', + teamId, + tmbId, + fileId + })}`; + } catch (error) {} + removeFilesByPaths([fileObj.path]); + } + } + return response; +} diff --git a/packages/service/package.json b/packages/service/package.json index ee19788fffcc..870af6e150c5 100644 --- a/packages/service/package.json +++ b/packages/service/package.json @@ -20,6 +20,7 @@ "iconv-lite": "^0.6.3", "joplin-turndown-plugin-gfm": "^1.0.12", "json5": "^2.2.3", + "jsonpath-plus": "^10.1.0", "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", "mammoth": "^1.6.0", diff --git a/packages/web/hooks/useI18n.ts b/packages/web/hooks/useI18n.ts index b0cdd27789d8..780ddd4afc2d 100644 --- a/packages/web/hooks/useI18n.ts +++ b/packages/web/hooks/useI18n.ts @@ -26,12 +26,11 @@ export const useI18nLng = () => { if (!navigator || !localStorage) return; if (getCookie(LANG_KEY)) return onChangeLng(getCookie(LANG_KEY) as string); - const languageMap = { + const languageMap: Record = { zh: 'zh', 'zh-CN': 'zh' }; - // @ts-ignore const lang = languageMap[navigator.language] || 'en'; // currentLng not in userLang diff --git a/packages/web/i18n/en/app.json b/packages/web/i18n/en/app.json index 947095b43d35..efa205eadf43 100644 --- a/packages/web/i18n/en/app.json +++ b/packages/web/i18n/en/app.json @@ -41,6 +41,7 @@ "file_recover": "File will overwrite current content", "file_upload": "File Upload", "file_upload_tip": "Once enabled, documents/images can be uploaded. Documents are retained for 7 days, images for 15 days. Using this feature may incur additional costs. To ensure a good experience, please choose an AI model with a larger context length when using this feature.", + "global_variables_desc": "Variable description", "go_to_chat": "Go to Conversation", "go_to_run": "Go to Execution", "image_upload": "Image Upload", @@ -159,4 +160,4 @@ "workflow.user_file_input_desc": "Links to documents and images uploaded by users.", "workflow.user_select": "User Selection", "workflow.user_select_tip": "This module can configure multiple options for selection during the dialogue. Different options can lead to different workflow branches." -} \ No newline at end of file +} diff --git a/packages/web/i18n/en/workflow.json b/packages/web/i18n/en/workflow.json index c0297ab1f890..9d58bb9d2293 100644 --- a/packages/web/i18n/en/workflow.json +++ b/packages/web/i18n/en/workflow.json @@ -64,6 +64,8 @@ "full_response_data": "Full Response Data", "greater_than": "Greater Than", "greater_than_or_equal_to": "Greater Than or Equal To", + "http_extract_output": "Output field extraction", + "http_extract_output_description": "Specified fields in the response value can be extracted through JSONPath syntax", "http_raw_response_description": "Raw HTTP response. Only accepts string or JSON type response data.", "http_request": "HTTP Request", "http_request_error_info": "HTTP request error information, returns empty on success", diff --git a/packages/web/i18n/zh/app.json b/packages/web/i18n/zh/app.json index dbd032746624..d414214cad3b 100644 --- a/packages/web/i18n/zh/app.json +++ b/packages/web/i18n/zh/app.json @@ -5,11 +5,8 @@ "app.Version name": "版本名称", "app.modules.click to update": "点击更新", "app.modules.has new version": "有新版本", - "version_back": "回到初始状态", - "version_copy": "副本", "app.version_current": "当前版本", "app.version_initial": "初始版本", - "version_initial_copy": "副本-初始状态", "app.version_name_tips": "版本名称不能为空", "app.version_past": "发布过", "app.version_publish_tips": "该版本将被保存至团队云端,同步给整个团队,同时更新所有发布渠道的应用版本", @@ -44,6 +41,7 @@ "file_recover": "文件将覆盖当前内容", "file_upload": "文件上传", "file_upload_tip": "开启后,可以上传文档/图片。文档保留7天,图片保留15天。使用该功能可能产生较多额外费用。为保证使用体验,使用该功能时,请选择上下文长度较大的AI模型。", + "global_variables_desc": "变量描述", "go_to_chat": "去对话", "go_to_run": "去运行", "image_upload": "图片上传", @@ -132,6 +130,9 @@ "variable.select type_desc": "可以为工作流定义全局变量,常用临时缓存。赋值的方式包括:\n1. 从对话页面的 query 参数获取。\n2. 通过 API 的 variables 对象传递。\n3. 通过【变量更新】节点进行赋值。", "variable.textarea_type_desc": "允许用户最多输入4000字的对话框。", "version.Revert success": "回滚成功", + "version_back": "回到初始状态", + "version_copy": "副本", + "version_initial_copy": "副本-初始状态", "vision_model_title": "启用图片识别", "week.Friday": "星期五", "week.Monday": "星期一", @@ -159,4 +160,4 @@ "workflow.user_file_input_desc": "用户上传的文档和图片链接", "workflow.user_select": "用户选择", "workflow.user_select_tip": "该模块可配置多个选项,以供对话时选择。不同选项可导向不同工作流支线" -} \ No newline at end of file +} diff --git a/packages/web/i18n/zh/workflow.json b/packages/web/i18n/zh/workflow.json index 24d7004650b5..8a0b22116e9f 100644 --- a/packages/web/i18n/zh/workflow.json +++ b/packages/web/i18n/zh/workflow.json @@ -65,6 +65,8 @@ "full_response_data": "完整响应数据", "greater_than": "大于", "greater_than_or_equal_to": "大于等于", + "http_extract_output": "输出字段提取", + "http_extract_output_description": "可以通过 JSONPath 语法来提取响应值中的指定字段", "http_raw_response_description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", "http_request": "HTTP 请求", "http_request_error_info": "HTTP请求错误信息,成功时返回空", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3e2c1cc3516c..eb72912b388c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -81,6 +81,9 @@ importers: packages/plugins: dependencies: + '@types/pg': + specifier: ^8.6.6 + version: 8.11.6 axios: specifier: ^1.5.1 version: 1.7.2 @@ -93,9 +96,18 @@ importers: expr-eval: specifier: ^2.0.2 version: 2.0.2 + json5: + specifier: ^2.2.3 + version: 2.2.3 lodash: specifier: ^4.17.21 version: 4.17.21 + mysql2: + specifier: ^3.11.3 + version: 3.11.3 + pg: + specifier: ^8.10.0 + version: 8.12.0 wikijs: specifier: ^6.4.1 version: 6.4.1(encoding@0.1.13) @@ -169,6 +181,9 @@ importers: json5: specifier: ^2.2.3 version: 2.2.3 + jsonpath-plus: + specifier: ^10.1.0 + version: 10.1.0 jsonwebtoken: specifier: ^9.0.2 version: 9.0.2 @@ -510,6 +525,9 @@ importers: react-syntax-highlighter: specifier: ^15.5.0 version: 15.5.0(react@18.3.1) + react-textarea-autosize: + specifier: ^8.5.4 + version: 8.5.4(@types/react@18.3.1)(react@18.3.1) reactflow: specifier: ^11.7.4 version: 11.11.4(@types/react@18.3.1)(immer@9.0.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2431,6 +2449,18 @@ packages: '@jsdevtools/ono@7.1.3': resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + '@jsep-plugin/assignment@1.2.1': + resolution: {integrity: sha512-gaHqbubTi29aZpVbBlECRpmdia+L5/lh2BwtIJTmtxdbecEyyX/ejAOg7eQDGNvGOUmPY7Z2Yxdy9ioyH/VJeA==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@jsep-plugin/regex@1.0.3': + resolution: {integrity: sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + '@lexical/clipboard@0.12.6': resolution: {integrity: sha512-rJFp7tXzawCrMWWRsjCR80dZoIkLJ/EPgPmTk3xqpc+9ntlwbkm3LUOdFmgN+pshnhiZTQBwbFqg/QbsA1Pw9g==} peerDependencies: @@ -3886,6 +3916,10 @@ packages: avvio@8.3.2: resolution: {integrity: sha512-st8e519GWHa/azv8S87mcJvZs4WsgTBjOw/Ih1CP6u+8SZvcOeAYNG6JbsIrAUUJJ7JfmrnOkR8ipDS+u9SIRQ==} + aws-ssl-profiles@1.1.2: + resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} + engines: {node: '>= 6.0.0'} + axe-core@4.9.1: resolution: {integrity: sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==} engines: {node: '>=4'} @@ -4730,6 +4764,10 @@ packages: delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -5387,6 +5425,9 @@ packages: engines: {node: '>=10'} deprecated: This package is no longer supported. + generate-function@2.3.1: + resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + generic-pool@3.9.0: resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} engines: {node: '>= 4'} @@ -5872,6 +5913,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-property@1.0.2: + resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -6156,6 +6200,10 @@ packages: resolution: {integrity: sha512-Jbygqaa20I+0ImPjmMbrsY3QrMkfwfI5G/VNlb6c9nDIyyOw8msfWHzTy04/sawa4rjn0t9WYy3nahWlSjB5zw==} engines: {node: '>=0.1.90'} + jsep@1.3.9: + resolution: {integrity: sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==} + engines: {node: '>= 10.16.0'} + jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true @@ -6201,6 +6249,11 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonpath-plus@10.1.0: + resolution: {integrity: sha512-gHfV1IYqH8uJHYVTs8BJX1XKy2/rR93+f8QQi0xhx95aCiXn1ettYAd5T+7FU6wfqyDoX/wy0pm/fL3jOKJ9Lg==} + engines: {node: '>=18.0.0'} + hasBin: true + jsonwebtoken@9.0.2: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} engines: {node: '>=12', npm: '>=6'} @@ -6402,10 +6455,18 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + lru-cache@9.1.2: resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==} engines: {node: 14 || >=16.14} + lru.min@1.1.1: + resolution: {integrity: sha512-FbAj6lXil6t8z4z3j0E5mfRlPzxkySotzUHwRXjlpRh10vc6AI6WN62ehZj82VG7M20rqogJ0GLwar2Xa05a8Q==} + engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} + luxon@3.4.4: resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==} engines: {node: '>=12'} @@ -6925,6 +6986,14 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + mysql2@3.11.3: + resolution: {integrity: sha512-Qpu2ADfbKzyLdwC/5d4W7+5Yz7yBzCU05YWt5npWzACST37wJsB23wgOSo00qi043urkiRwXtEvJc9UnuLX/MQ==} + engines: {node: '>= 8.0'} + + named-placeholders@1.1.3: + resolution: {integrity: sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==} + engines: {node: '>=12.0.0'} + nan@2.20.0: resolution: {integrity: sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==} @@ -7679,6 +7748,12 @@ packages: peerDependencies: react: '>= 0.14.0' + react-textarea-autosize@8.5.4: + resolution: {integrity: sha512-eSSjVtRLcLfFwFcariT77t9hcbVJHQV76b51QjQGarQIHml2+gM2lms0n3XrhnDmgK5B+/Z7TmQk5OHNzqYm/A==} + engines: {node: '>=10'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -7941,6 +8016,9 @@ packages: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} + seq-queue@0.0.5: + resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} + serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} @@ -8072,6 +8150,10 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + sqlstring@2.3.3: + resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} + engines: {node: '>= 0.6'} + ssri@10.0.6: resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -8677,6 +8759,11 @@ packages: '@types/react': optional: true + use-composed-ref@1.3.0: + resolution: {integrity: sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + use-context-selector@1.4.4: resolution: {integrity: sha512-pS790zwGxxe59GoBha3QYOwk8AFGp4DN6DOtH+eoqVmgBBRXVx4IlPDhJmmMiNQAgUaLlP+58aqRC3A4rdaSjg==} peerDependencies: @@ -8690,6 +8777,24 @@ packages: react-native: optional: true + use-isomorphic-layout-effect@1.1.2: + resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + use-latest@1.2.1: + resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + use-memo-one@1.1.3: resolution: {integrity: sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==} peerDependencies: @@ -11301,6 +11406,14 @@ snapshots: '@jsdevtools/ono@7.1.3': {} + '@jsep-plugin/assignment@1.2.1(jsep@1.3.9)': + dependencies: + jsep: 1.3.9 + + '@jsep-plugin/regex@1.0.3(jsep@1.3.9)': + dependencies: + jsep: 1.3.9 + '@lexical/clipboard@0.12.6(lexical@0.12.6)': dependencies: '@lexical/html': 0.12.6(lexical@0.12.6) @@ -12966,6 +13079,8 @@ snapshots: '@fastify/error': 3.4.1 fastq: 1.17.1 + aws-ssl-profiles@1.1.2: {} + axe-core@4.9.1: {} axios@1.7.2: @@ -13924,6 +14039,8 @@ snapshots: delegates@1.0.0: optional: true + denque@2.1.0: {} + depd@2.0.0: {} dequal@2.0.3: {} @@ -14802,7 +14919,7 @@ snapshots: dependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.3 + tslib: 2.7.0 optionalDependencies: '@emotion/is-prop-valid': 0.8.8 @@ -14859,6 +14976,10 @@ snapshots: wide-align: 1.1.5 optional: true + generate-function@2.3.1: + dependencies: + is-property: 1.0.2 + generic-pool@3.9.0: {} gensync@1.0.0-beta.2: {} @@ -15388,6 +15509,8 @@ snapshots: is-plain-obj@4.1.0: {} + is-property@1.0.2: {} + is-regex@1.1.4: dependencies: call-bind: 1.0.7 @@ -15856,6 +15979,8 @@ snapshots: jschardet@3.1.1: {} + jsep@1.3.9: {} + jsesc@0.5.0: {} jsesc@2.5.2: {} @@ -15890,6 +16015,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonpath-plus@10.1.0: + dependencies: + '@jsep-plugin/assignment': 1.2.1(jsep@1.3.9) + '@jsep-plugin/regex': 1.0.3(jsep@1.3.9) + jsep: 1.3.9 + jsonwebtoken@9.0.2: dependencies: jws: 3.2.2 @@ -16112,8 +16243,12 @@ snapshots: dependencies: yallist: 3.1.1 + lru-cache@7.18.3: {} + lru-cache@9.1.2: {} + lru.min@1.1.1: {} + luxon@3.4.4: {} magic-string@0.30.10: @@ -16976,7 +17111,7 @@ snapshots: mquery@5.0.0: dependencies: - debug: 4.3.5 + debug: 4.3.7 transitivePeerDependencies: - supports-color @@ -17002,6 +17137,22 @@ snapshots: mute-stream@1.0.0: {} + mysql2@3.11.3: + dependencies: + aws-ssl-profiles: 1.1.2 + denque: 2.1.0 + generate-function: 2.3.1 + iconv-lite: 0.6.3 + long: 5.2.3 + lru.min: 1.1.1 + named-placeholders: 1.1.3 + seq-queue: 0.0.5 + sqlstring: 2.3.3 + + named-placeholders@1.1.3: + dependencies: + lru-cache: 7.18.3 + nan@2.20.0: optional: true @@ -17794,6 +17945,15 @@ snapshots: react: 18.3.1 refractor: 3.6.0 + react-textarea-autosize@8.5.4(@types/react@18.3.1)(react@18.3.1): + dependencies: + '@babel/runtime': 7.24.8 + react: 18.3.1 + use-composed-ref: 1.3.0(react@18.3.1) + use-latest: 1.2.1(@types/react@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -18158,6 +18318,8 @@ snapshots: transitivePeerDependencies: - supports-color + seq-queue@0.0.5: {} + serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -18296,6 +18458,8 @@ snapshots: sprintf-js@1.1.3: {} + sqlstring@2.3.3: {} + ssri@10.0.6: dependencies: minipass: 7.1.2 @@ -18936,6 +19100,10 @@ snapshots: optionalDependencies: '@types/react': 18.3.1 + use-composed-ref@1.3.0(react@18.3.1): + dependencies: + react: 18.3.1 + use-context-selector@1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2): dependencies: react: 18.3.1 @@ -18943,6 +19111,19 @@ snapshots: optionalDependencies: react-dom: 18.3.1(react@18.3.1) + use-isomorphic-layout-effect@1.1.2(@types/react@18.3.1)(react@18.3.1): + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.1 + + use-latest@1.2.1(@types/react@18.3.1)(react@18.3.1): + dependencies: + react: 18.3.1 + use-isomorphic-layout-effect: 1.1.2(@types/react@18.3.1)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.1 + use-memo-one@1.1.3(react@18.3.1): dependencies: react: 18.3.1 diff --git a/projects/app/data/config.json b/projects/app/data/config.json index 1b97164aa2dc..9a61095c385f 100644 --- a/projects/app/data/config.json +++ b/projects/app/data/config.json @@ -4,8 +4,9 @@ "lafEnv": "https://laf.dev" // laf环境。 https://laf.run (杭州阿里云) ,或者私有化的laf环境。如果使用 Laf openapi 功能,需要最新版的 laf 。 }, "systemEnv": { - "vectorMaxProcess": 15, - "qaMaxProcess": 15, + "vectorMaxProcess": 15, // 向量处理线程数量 + "qaMaxProcess": 15, // 问答拆分线程数量 + "tokenWorkers": 50, // Token 计算线程保持数,会持续占用内存,不能设置太大。 "pgHNSWEfSearch": 100 // 向量搜索参数。越大,搜索越精确,但是速度越慢。设置为100,有99%+精度。 }, "llmModels": [ diff --git a/projects/app/src/components/common/Textarea/MyTextarea/index.tsx b/projects/app/src/components/common/Textarea/MyTextarea/index.tsx index 6d1b9cd3f038..b9a552f30dc3 100644 --- a/projects/app/src/components/common/Textarea/MyTextarea/index.tsx +++ b/projects/app/src/components/common/Textarea/MyTextarea/index.tsx @@ -24,6 +24,7 @@ type Props = TextareaProps & { const MyTextarea = React.forwardRef(function MyTextarea(props, ref) { const ModalTextareaRef = useRef(null); const TextareaRef = useRef(null); + React.useImperativeHandle(ref, () => TextareaRef.current!); const { t } = useTranslation(); const { diff --git a/projects/app/src/components/core/app/DatasetParamsModal.tsx b/projects/app/src/components/core/app/DatasetParamsModal.tsx index dde5982e7bfc..f428e5f6b103 100644 --- a/projects/app/src/components/core/app/DatasetParamsModal.tsx +++ b/projects/app/src/components/core/app/DatasetParamsModal.tsx @@ -322,10 +322,7 @@ const DatasetParamsModal = ({ minH={150} maxH={300} placeholder={t('common:core.module.QueryExtension.placeholder')} - value={cfbBgDesc} - onChange={(e) => { - setValue('datasetSearchExtensionBg', e.target.value); - }} + {...register('datasetSearchExtensionBg')} /> diff --git a/projects/app/src/components/core/app/VariableEdit.tsx b/projects/app/src/components/core/app/VariableEdit.tsx index 13d6e06618a4..58630d4cabec 100644 --- a/projects/app/src/components/core/app/VariableEdit.tsx +++ b/projects/app/src/components/core/app/VariableEdit.tsx @@ -120,10 +120,8 @@ const VariableEdit = ({ if (data.type === VariableInputEnum.custom) { data.required = false; - } - - if (data.type === VariableInputEnum.numberInput) { - data.valueType = WorkflowIOValueTypeEnum.number; + } else { + data.valueType = inputTypeList.find((item) => item.value === data.type)?.defaultValueType; } const onChangeVariable = [...variables]; @@ -152,7 +150,7 @@ const VariableEdit = ({ }); } }, - [variables, toast, t, onChange, reset] + [variables, toast, t, inputTypeList, onChange, reset] ); const onSubmitError = useCallback( @@ -205,7 +203,7 @@ const VariableEdit = ({ p={0} /> {t('workflow:Variable_name')} - {t('common:core.module.variable.key')} + {t('app:global_variables_desc')} {t('common:common.Require Input')} @@ -216,9 +214,17 @@ const VariableEdit = ({ - {item.label} {item.key} - {item.required ? '✔' : ''} + + {item.description || '-'} + + {item.required ? '✔' : '-'} { setValue(item.key, e.target.value)} + {...register(item.key, { + required: item.required + })} /> )} {item.type === VariableInputEnum.textarea && ( diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useDebug.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useDebug.tsx index 1632e464cf15..31496601b778 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useDebug.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useDebug.tsx @@ -59,7 +59,7 @@ export const useDebug = () => { const filteredVar = useMemo(() => { const variables = appDetail.chatConfig?.variables; return variables?.filter((item) => item.type !== VariableInputEnum.custom) || []; - }, [appDetail.chatConfig.variables]); + }, [appDetail.chatConfig?.variables]); const [defaultGlobalVariables, setDefaultGlobalVariables] = useState>( filteredVar.reduce( @@ -272,14 +272,13 @@ export const useDebug = () => { return ( { - setValue(`nodeVariables.${input.key}`, e.target.value); - }} + {...register(`nodeVariables.${input.key}`, { + required: input.required + })} /> ); } diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderOutput/FieldEditModal.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderOutput/FieldEditModal.tsx index f29a03804f56..1e6154d1dfd2 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderOutput/FieldEditModal.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderOutput/FieldEditModal.tsx @@ -142,7 +142,7 @@ const FieldModal = ({ {/* key */} - {t('common:core.module.Field Name')} + {t('workflow:Variable_name')} - {t('common:core.workflow.Custom outputs')} + {t((addOutput.label || 'common:core.workflow.Custom outputs') as any)} {addOutput.description && } diff --git a/projects/app/src/pages/app/detail/components/context.tsx b/projects/app/src/pages/app/detail/components/context.tsx index 157fdba30e7c..71ca7c9a0ce5 100644 --- a/projects/app/src/pages/app/detail/components/context.tsx +++ b/projects/app/src/pages/app/detail/components/context.tsx @@ -176,7 +176,15 @@ const AppContextProvider = ({ children }: { children: ReactNode }) => { errorToast: t('common:common.Delete Failed') } ); - const onDelApp = useCallback(() => openConfirmDel(deleteApp)(), [deleteApp, openConfirmDel]); + const onDelApp = useCallback( + () => + openConfirmDel( + deleteApp, + undefined, + t('app:confirm_del_app_tip', { name: appDetail.name }) + )(), + [appDetail.name, deleteApp, openConfirmDel, t] + ); const contextValue: AppContextType = { appId,