Plugin support select file (#2756)

* feat: plugin support upload files (#2716)

* feat: plugin support file upload

* file history

* fix history & chattest

* chore: code

* plugin config icon & file preview padding

* perf: undefined fn

* fix: plugin file numbers & plugin template add config (#2743)

* perf: run plugin without human message (#2749)

* perf: run plugin without human message

* fix build

* fix build

* rename node

* perf: ui

* perf: plugin rerun with last params & plugin log add file (#2755)

* perf: plugin run with last params & plugin log add file

* delete console

* perf: plugin refresh code

* fix: ts

---------

Co-authored-by: heheer <heheer@sealos.io>
This commit is contained in:
Archer 2024-09-20 14:12:58 +08:00 committed by GitHub
parent 5e7c97b7b8
commit 75af549c7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
59 changed files with 2032 additions and 854 deletions

View File

@ -332,7 +332,7 @@ curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"moduleName": "自定义插件输出", "moduleName": "插件输出",
"moduleType": "pluginOutput", "moduleType": "pluginOutput",
"totalPoints": 0, "totalPoints": 0,
"pluginOutput": { "pluginOutput": {
@ -430,7 +430,7 @@ event: answer
data: [DONE] data: [DONE]
event: flowResponses event: flowResponses
data: [{"nodeId":"fdDgXQ6SYn8v","moduleName":"AI 对话","moduleType":"chatNode","totalPoints":0.033,"model":"FastAI-3.5","tokens":33,"query":"你好","maxToken":2000,"historyPreview":[{"obj":"Human","value":"你好"},{"obj":"AI","value":"你好!有什么可以帮助你的吗?"}],"contextTotalLen":2,"runningTime":1.42},{"nodeId":"pluginOutput","moduleName":"自定义插件输出","moduleType":"pluginOutput","totalPoints":0,"pluginOutput":{"result":"你好!有什么可以帮助你的吗?"},"runningTime":0}] data: [{"nodeId":"fdDgXQ6SYn8v","moduleName":"AI 对话","moduleType":"chatNode","totalPoints":0.033,"model":"FastAI-3.5","tokens":33,"query":"你好","maxToken":2000,"historyPreview":[{"obj":"Human","value":"你好"},{"obj":"AI","value":"你好!有什么可以帮助你的吗?"}],"contextTotalLen":2,"runningTime":1.42},{"nodeId":"pluginOutput","moduleName":"插件输出","moduleType":"pluginOutput","totalPoints":0,"pluginOutput":{"result":"你好!有什么可以帮助你的吗?"},"runningTime":0}]
``` ```
{{< /markdownify >}} {{< /markdownify >}}

View File

@ -91,11 +91,12 @@ weight: 813
5. 新增 - 沙盒增加字符串转 base64 全局方法。 5. 新增 - 沙盒增加字符串转 base64 全局方法。
6. 新增 - 支持 Openai o1 模型,需增加模型的 `defaultConfig` 配置,覆盖 `temperature``max_tokens``stream`配置o1 不支持 stream 模式, 详细可重新拉取 `config.json` 配置文件查看。 6. 新增 - 支持 Openai o1 模型,需增加模型的 `defaultConfig` 配置,覆盖 `temperature``max_tokens``stream`配置o1 不支持 stream 模式, 详细可重新拉取 `config.json` 配置文件查看。
7. 新增 - AI 对话节点知识库引用,支持配置 role=system 和 role=user已配置的过自定义提示词的节点将会保持 user 模式,其余用户将转成 system 模式。 7. 新增 - AI 对话节点知识库引用,支持配置 role=system 和 role=user已配置的过自定义提示词的节点将会保持 user 模式,其余用户将转成 system 模式。
8. 优化 - 工作流嵌套层级限制 20 层,避免因编排不合理导致的无限死循环。 8. 新增 - 插件支持上传系统文件。
9. 优化 - 工作流 handler 性能优化。 9. 优化 - 工作流嵌套层级限制 20 层,避免因编排不合理导致的无限死循环。
10. 优化 - 工作流快捷键,避免调试测试时也会触发。 10. 优化 - 工作流 handler 性能优化。
11. 优化 - 流输出,切换 tab 时仍可以继续输出。 11. 优化 - 工作流快捷键,避免调试测试时也会触发。
12. 优化 - 完善外部文件知识库相关 API 12. 优化 - 流输出,切换 tab 时仍可以继续输出。
13. 修复 - 知识库选择权限问题。 13. 优化 - 完善外部文件知识库相关 API
14. 修复 - 空 chatId 发起对话,首轮携带用户选择时会异常。 14. 修复 - 知识库选择权限问题。
15. 修复 - createDataset 接口intro 为赋值。 15. 修复 - 空 chatId 发起对话,首轮携带用户选择时会异常。
16. 修复 - createDataset 接口intro 为赋值。

View File

@ -13,7 +13,7 @@ export const PluginOutputModule: FlowNodeTemplateType = {
unique: true, unique: true,
forbidDelete: true, forbidDelete: true,
avatar: 'core/workflow/template/pluginOutput', avatar: 'core/workflow/template/pluginOutput',
name: i18nT('workflow:custom_plugin_output'), name: i18nT('workflow:template.plugin_output'),
intro: i18nT('workflow:intro_custom_plugin_output'), intro: i18nT('workflow:intro_custom_plugin_output'),
showStatus: false, showStatus: false,
version: '481', version: '481',

View File

@ -33,6 +33,11 @@ import { RuntimeNodeItemType } from './runtime/type';
import { getReferenceVariableValue } from './runtime/utils'; import { getReferenceVariableValue } from './runtime/utils';
import { Input_Template_History, Input_Template_UserChatInput } from './template/input'; import { Input_Template_History, Input_Template_UserChatInput } from './template/input';
import { i18nT } from '../../../web/i18n/utils'; import { i18nT } from '../../../web/i18n/utils';
import { RuntimeUserPromptType, UserChatItemType } from '../../core/chat/type';
import { getNanoid } from '../../common/string/tools';
import { ChatRoleEnum } from '../../core/chat/constants';
import { runtimePrompt2ChatsValue } from '../../core/chat/adapt';
import { getPluginRunContent } from '../../core/app/plugin/utils';
export const getHandleId = (nodeId: string, type: 'source' | 'target', key: string) => { export const getHandleId = (nodeId: string, type: 'source' | 'target', key: string) => {
return `${nodeId}-${type}-${key}`; return `${nodeId}-${type}-${key}`;
@ -395,3 +400,26 @@ export function replaceEditorVariable({
} }
return text || ''; return text || '';
} }
/* Get plugin runtime input user query */
export const getPluginRunUserQuery = ({
pluginInputs,
variables,
files = []
}: {
pluginInputs: FlowNodeInputItemType[];
variables: Record<string, any>;
files?: RuntimeUserPromptType['files'];
}): UserChatItemType & { dataId: string } => {
return {
dataId: getNanoid(24),
obj: ChatRoleEnum.Human,
value: runtimePrompt2ChatsValue({
text: getPluginRunContent({
pluginInputs: pluginInputs,
variables
}),
files
})
};
};

View File

@ -13,16 +13,30 @@
"workflow": { "workflow": {
"nodes": [ "nodes": [
{
"nodeId": "pluginConfig",
"name": "common:core.module.template.system_config",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -90.53591960393504,
"y": -17.580286776561252
},
"version": "4811",
"inputs": [],
"outputs": []
},
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "core/workflow/template/workflowStart", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 362.9862638626885, "x": 368.6800424053505,
"y": 6.16353826540589 "y": -17.580286776561252
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -107,14 +121,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "core/workflow/template/pluginOutput", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1661.4708279314577, "x": 1796.2235867744578,
"y": 23.877720915480012 "y": 6.419713223438748
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -167,7 +181,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -178,6 +192,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -187,7 +202,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -195,17 +212,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "Doc2X/FileImg2text" "value": "Doc2X/FileImg2text",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -213,9 +246,11 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -223,7 +258,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -231,7 +268,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"apikey\": \"{{apikey}}\",\n \"files\": {{files}},\n \"img_correction\": {{img_correction}},\n \"formula\": {{formula}}\n}", "value": "{\n \"apikey\": \"{{apikey}}\",\n \"files\": {{files}},\n \"img_correction\": {{img_correction}},\n \"formula\": {{formula}}\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -249,6 +308,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -278,6 +338,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -307,6 +368,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -336,6 +398,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -354,7 +417,7 @@
{ {
"id": "error", "id": "error",
"key": "error", "key": "error",
"label": "请求错误", "label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空", "description": "HTTP请求错误信息成功时返回空",
"valueType": "object", "valueType": "object",
"type": "static" "type": "static"
@ -362,8 +425,8 @@
{ {
"id": "httpRawResponse", "id": "httpRawResponse",
"key": "httpRawResponse", "key": "httpRawResponse",
"label": "原始响应",
"required": true, "required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", "description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any", "valueType": "any",
"type": "static" "type": "static"

View File

@ -13,16 +13,30 @@
"workflow": { "workflow": {
"nodes": [ "nodes": [
{
"nodeId": "pluginConfig",
"name": "common:core.module.template.system_config",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -30.474351356537454,
"y": -101.45216221730038
},
"version": "4811",
"inputs": [],
"outputs": []
},
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "core/workflow/template/workflowStart", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 388.243055058894, "x": 407.2817920483865,
"y": -75.09744210499466 "y": -101.45216221730038
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -88,14 +102,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "core/workflow/template/pluginOutput", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1649.7796447278438, "x": 1842.070888321717,
"y": -96.05331527115042 "y": -101.45216221730038
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -148,7 +162,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -159,6 +173,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -168,7 +183,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -176,17 +193,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "Doc2X/FilePDF2text" "value": "Doc2X/FilePDF2text",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -194,9 +227,11 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -204,7 +239,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -212,7 +249,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"apikey\": \"{{apikey}}\",\n \"files\": {{files}},\n \"ocr\": {{ocr}}\n}", "value": "{\n \"apikey\": \"{{apikey}}\",\n \"files\": {{files}},\n \"ocr\": {{ocr}}\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -230,6 +289,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -259,6 +319,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -288,6 +349,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -306,7 +368,7 @@
{ {
"id": "error", "id": "error",
"key": "error", "key": "error",
"label": "请求错误", "label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空", "description": "HTTP请求错误信息成功时返回空",
"valueType": "object", "valueType": "object",
"type": "static" "type": "static"
@ -314,8 +376,8 @@
{ {
"id": "httpRawResponse", "id": "httpRawResponse",
"key": "httpRawResponse", "key": "httpRawResponse",
"label": "原始响应",
"required": true, "required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", "description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any", "valueType": "any",
"type": "static" "type": "static"

View File

@ -15,13 +15,13 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "core/workflow/template/workflowStart", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 388.243055058894, "x": 353.91678143999377,
"y": -75.09744210499466 "y": -75.09744210499466
}, },
"version": "481", "version": "481",
@ -107,14 +107,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "core/workflow/template/pluginOutput", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1654.8021754314786, "x": 1703.581616889916,
"y": -22.243376051504086 "y": -14.097442104994656
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -147,8 +147,8 @@
"flowNodeType": "httpRequest468", "flowNodeType": "httpRequest468",
"showStatus": true, "showStatus": true,
"position": { "position": {
"x": 1081.967607938733, "x": 1000.6685388413375,
"y": -426.08028677656125 "y": -457.0974421049947
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -158,7 +158,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -169,6 +169,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -178,7 +179,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -186,17 +189,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "Doc2X/URLImg2text" "value": "Doc2X/URLImg2text",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -204,9 +223,11 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -214,7 +235,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -222,7 +245,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"apikey\": \"{{apikey}}\",\n \"url\": \"{{url}}\",\n \"img_correction\": {{img_correction}},\n \"formula\": {{formula}}\n}", "value": "{\n \"apikey\": \"{{apikey}}\",\n \"url\": \"{{url}}\",\n \"img_correction\": {{img_correction}},\n \"formula\": {{formula}}\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -240,6 +285,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -269,6 +315,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -298,6 +345,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -327,6 +375,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -345,7 +394,7 @@
{ {
"id": "error", "id": "error",
"key": "error", "key": "error",
"label": "请求错误", "label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空", "description": "HTTP请求错误信息成功时返回空",
"valueType": "object", "valueType": "object",
"type": "static" "type": "static"
@ -353,8 +402,8 @@
{ {
"id": "httpRawResponse", "id": "httpRawResponse",
"key": "httpRawResponse", "key": "httpRawResponse",
"label": "原始响应",
"required": true, "required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", "description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any", "valueType": "any",
"type": "static" "type": "static"
@ -401,6 +450,20 @@
"label": "success" "label": "success"
} }
] ]
},
{
"nodeId": "sWEDDSeuI9ar",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -117.03701176267538,
"y": -75.09744210499466
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -15,7 +15,7 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "core/workflow/template/workflowStart", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
@ -88,14 +88,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "core/workflow/template/pluginOutput", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1654.8021754314786, "x": 1665.6420513111314,
"y": -22.243376051504086 "y": -40.597442104994656
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -128,8 +128,8 @@
"flowNodeType": "httpRequest468", "flowNodeType": "httpRequest468",
"showStatus": true, "showStatus": true,
"position": { "position": {
"x": 1081.967607938733, "x": 966.3422652224374,
"y": -426.08028677656125 "y": -446.5974421049947
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -139,7 +139,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -150,6 +150,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -159,7 +160,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -167,17 +170,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "Doc2X/URLPDF2text" "value": "Doc2X/URLPDF2text",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -185,9 +204,11 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -195,7 +216,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -203,7 +226,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"apikey\": \"{{apikey}}\",\n \"url\": \"{{url}}\",\n \"ocr\": {{ocr}}\n}", "value": "{\n \"apikey\": \"{{apikey}}\",\n \"url\": \"{{url}}\",\n \"ocr\": {{ocr}}\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -221,6 +266,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -250,6 +296,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -279,6 +326,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -297,7 +345,7 @@
{ {
"id": "error", "id": "error",
"key": "error", "key": "error",
"label": "请求错误", "label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空", "description": "HTTP请求错误信息成功时返回空",
"valueType": "object", "valueType": "object",
"type": "static" "type": "static"
@ -305,8 +353,8 @@
{ {
"id": "httpRawResponse", "id": "httpRawResponse",
"key": "httpRawResponse", "key": "httpRawResponse",
"label": "原始响应",
"required": true, "required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", "description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any", "valueType": "any",
"type": "static" "type": "static"
@ -353,6 +401,20 @@
"label": "success" "label": "success"
} }
] ]
},
{
"nodeId": "rZmLfANEyyJe",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -93.55061402342784,
"y": -55.907069101622824
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -14,14 +14,14 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "/imgs/workflow/input.png", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 393.68844551739926, "x": 484.02074451450517,
"y": -58.80666875994541 "y": -79.06127656499825
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -49,14 +49,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1795.6509902691012, "x": 1759.5180706702588,
"y": -47.04550785550961 "y": -60.56127656499825
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -76,7 +76,7 @@
"nodeId": "hjnVuJAOwyXV", "nodeId": "hjnVuJAOwyXV",
"name": "HTTP 请求", "name": "HTTP 请求",
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)", "intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
"avatar": "/imgs/workflow/http.png", "avatar": "core/workflow/template/httpRequest",
"flowNodeType": "httpRequest468", "flowNodeType": "httpRequest468",
"showStatus": true, "showStatus": true,
"position": { "position": {
@ -91,7 +91,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -102,6 +102,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -111,7 +112,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -119,17 +122,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "duckduckgo/search" "value": "duckduckgo/search",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -137,9 +156,11 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -147,7 +168,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -155,7 +178,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"query\": \"{{query}}\"\n}", "value": "{\n \"query\": \"{{query}}\"\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -173,6 +218,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -188,6 +234,23 @@
} }
], ],
"outputs": [ "outputs": [
{
"id": "error",
"key": "error",
"label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{ {
"id": "system_addOutputParam", "id": "system_addOutputParam",
"key": "system_addOutputParam", "key": "system_addOutputParam",
@ -215,23 +278,6 @@
"showDefaultValue": false "showDefaultValue": false
} }
}, },
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{ {
"id": "lEyy5QqyIBrK", "id": "lEyy5QqyIBrK",
"valueType": "string", "valueType": "string",
@ -240,6 +286,20 @@
"label": "result" "label": "result"
} }
] ]
},
{
"nodeId": "f1mRh1D85H2D",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -28.511358745511643,
"y": -103.56127656499825
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -14,14 +14,14 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "/imgs/workflow/input.png", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 393.68844551739926, "x": 422.59478119647315,
"y": -58.80666875994541 "y": -79.06127656499825
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -49,14 +49,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1795.6509902691012, "x": 1777.58453046968,
"y": -47.04550785550961 "y": -60.56127656499825
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -76,7 +76,7 @@
"nodeId": "hjnVuJAOwyXV", "nodeId": "hjnVuJAOwyXV",
"name": "HTTP 请求", "name": "HTTP 请求",
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)", "intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
"avatar": "/imgs/workflow/http.png", "avatar": "core/workflow/template/httpRequest",
"flowNodeType": "httpRequest468", "flowNodeType": "httpRequest468",
"showStatus": true, "showStatus": true,
"position": { "position": {
@ -91,7 +91,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -102,6 +102,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -111,7 +112,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -119,17 +122,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "duckduckgo/searchImg" "value": "duckduckgo/searchImg",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -137,9 +156,11 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -147,7 +168,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -155,7 +178,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"query\": \"{{query}}\"\n}", "value": "{\n \"query\": \"{{query}}\"\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -173,6 +218,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -188,6 +234,23 @@
} }
], ],
"outputs": [ "outputs": [
{
"id": "error",
"key": "error",
"label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{ {
"id": "system_addOutputParam", "id": "system_addOutputParam",
"key": "system_addOutputParam", "key": "system_addOutputParam",
@ -215,23 +278,6 @@
"showDefaultValue": false "showDefaultValue": false
} }
}, },
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{ {
"id": "lEyy5QqyIBrK", "id": "lEyy5QqyIBrK",
"valueType": "string", "valueType": "string",
@ -240,6 +286,20 @@
"label": "result" "label": "result"
} }
] ]
},
{
"nodeId": "y3A7CnUp4VOH",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -35.73794266528006,
"y": -103.56127656499825
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -14,14 +14,14 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "/imgs/workflow/input.png", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 393.68844551739926, "x": 476.7941605947366,
"y": -58.80666875994541 "y": -79.06127656499825
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -49,14 +49,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1795.6509902691012, "x": 1761.324716650201,
"y": -47.04550785550961 "y": -60.56127656499825
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -76,7 +76,7 @@
"nodeId": "hjnVuJAOwyXV", "nodeId": "hjnVuJAOwyXV",
"name": "HTTP 请求", "name": "HTTP 请求",
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)", "intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
"avatar": "/imgs/workflow/http.png", "avatar": "core/workflow/template/httpRequest",
"flowNodeType": "httpRequest468", "flowNodeType": "httpRequest468",
"showStatus": true, "showStatus": true,
"position": { "position": {
@ -91,7 +91,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -102,6 +102,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -111,7 +112,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -119,17 +122,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "duckduckgo/searchNews" "value": "duckduckgo/searchNews",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -137,9 +156,11 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -147,7 +168,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -155,7 +178,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"query\": \"{{query}}\"\n}", "value": "{\n \"query\": \"{{query}}\"\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -173,6 +218,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -188,6 +234,23 @@
} }
], ],
"outputs": [ "outputs": [
{
"id": "error",
"key": "error",
"label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{ {
"id": "system_addOutputParam", "id": "system_addOutputParam",
"key": "system_addOutputParam", "key": "system_addOutputParam",
@ -215,23 +278,6 @@
"showDefaultValue": false "showDefaultValue": false
} }
}, },
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{ {
"id": "lEyy5QqyIBrK", "id": "lEyy5QqyIBrK",
"valueType": "string", "valueType": "string",
@ -240,6 +286,20 @@
"label": "result" "label": "result"
} }
] ]
},
{
"nodeId": "dG0Prv5FaR8e",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -32.12465070539588,
"y": -103.56127656499825
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -14,14 +14,14 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "/imgs/workflow/input.png", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 393.68844551739926, "x": 429.8213651162415,
"y": -58.80666875994541 "y": -79.06127656499825
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -49,14 +49,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1795.6509902691012, "x": 1781.1978224295642,
"y": -47.04550785550961 "y": -60.56127656499825
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -76,7 +76,7 @@
"nodeId": "hjnVuJAOwyXV", "nodeId": "hjnVuJAOwyXV",
"name": "HTTP 请求", "name": "HTTP 请求",
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)", "intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
"avatar": "/imgs/workflow/http.png", "avatar": "core/workflow/template/httpRequest",
"flowNodeType": "httpRequest468", "flowNodeType": "httpRequest468",
"showStatus": true, "showStatus": true,
"position": { "position": {
@ -91,7 +91,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -102,6 +102,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -111,7 +112,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -119,17 +122,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "duckduckgo/searchVideo" "value": "duckduckgo/searchVideo",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -137,9 +156,11 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -147,7 +168,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -155,7 +178,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"query\": \"{{query}}\"\n}", "value": "{\n \"query\": \"{{query}}\"\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -173,6 +218,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -188,6 +234,23 @@
} }
], ],
"outputs": [ "outputs": [
{
"id": "error",
"key": "error",
"label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{ {
"id": "system_addOutputParam", "id": "system_addOutputParam",
"key": "system_addOutputParam", "key": "system_addOutputParam",
@ -215,23 +278,6 @@
"showDefaultValue": false "showDefaultValue": false
} }
}, },
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{ {
"id": "lEyy5QqyIBrK", "id": "lEyy5QqyIBrK",
"valueType": "string", "valueType": "string",
@ -240,6 +286,20 @@
"label": "result" "label": "result"
} }
] ]
},
{
"nodeId": "iyF6yGGXuyWn",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -8.638252966148258,
"y": -103.56127656499825
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -15,14 +15,14 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "core/workflow/template/workflowStart", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 156.37657136084977, "x": 194.3171058153904,
"y": 90.73380846709256 "y": 125.65095361549629
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -68,14 +68,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "core/workflow/template/pluginOutput", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 2110.7223589692912, "x": 2128.4279417147436,
"y": 120.17602722162474 "y": 170.6509536154963
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -110,7 +110,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -121,6 +121,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -130,7 +131,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -138,17 +141,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "{{url}}" "value": "{{url}}",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -156,9 +175,11 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -166,7 +187,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -174,7 +197,29 @@
"valueType": "any", "valueType": "any",
"value": "{{content}}", "value": "{{content}}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -192,6 +237,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -221,6 +267,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -239,7 +286,7 @@
{ {
"id": "error", "id": "error",
"key": "error", "key": "error",
"label": "请求错误", "label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空", "description": "HTTP请求错误信息成功时返回空",
"valueType": "object", "valueType": "object",
"type": "static" "type": "static"
@ -247,8 +294,8 @@
{ {
"id": "httpRawResponse", "id": "httpRawResponse",
"key": "httpRawResponse", "key": "httpRawResponse",
"label": "原始响应",
"required": true, "required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", "description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any", "valueType": "any",
"type": "static" "type": "static"
@ -290,8 +337,8 @@
"flowNodeType": "code", "flowNodeType": "code",
"showStatus": true, "showStatus": true,
"position": { "position": {
"x": 805.8169457909617, "x": 833.6400043909581,
"y": -159.52218926716316 "y": -127.34904638450371
}, },
"version": "482", "version": "482",
"inputs": [ "inputs": [
@ -301,7 +348,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "这些变量会作为代码的运行的输入参数", "description": "workflow:these_variables_will_be_input_parameters_for_code_execution",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -312,6 +359,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -321,19 +369,25 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "codeType", "key": "codeType",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"label": "", "label": "",
"value": "js" "value": "js",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "code", "key": "code",
"renderTypeList": ["custom"], "renderTypeList": ["custom"],
"label": "", "label": "",
"value": "function main({data1}){\n try{\n const parseData = JSON.parse(data1)\n if(typeof parseData === 'object') {\n return parseData\n }\n return {\n \"msg_type\": \"text\",\n content: {\n \"text\": data1\n }\n }\n } catch(err) {\n return {\n \"msg_type\": \"text\",\n content: {\n \"text\": data1\n }\n }\n }\n}" "value": "function main({data1}){\n try{\n const parseData = JSON.parse(data1)\n if(typeof parseData === 'object') {\n return parseData\n }\n return {\n \"msg_type\": \"text\",\n content: {\n \"text\": data1\n }\n }\n } catch(err) {\n return {\n \"msg_type\": \"text\",\n content: {\n \"text\": data1\n }\n }\n }\n}",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -351,6 +405,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -369,14 +424,15 @@
{ {
"id": "system_rawResponse", "id": "system_rawResponse",
"key": "system_rawResponse", "key": "system_rawResponse",
"label": "完整响应数据", "label": "workflow:full_response_data",
"valueType": "object", "valueType": "object",
"type": "static" "type": "static",
"description": ""
}, },
{ {
"id": "error", "id": "error",
"key": "error", "key": "error",
"label": "运行错误", "label": "workflow:execution_error",
"description": "代码运行错误信息,成功时返回空", "description": "代码运行错误信息,成功时返回空",
"valueType": "object", "valueType": "object",
"type": "static" "type": "static"
@ -417,6 +473,20 @@
"label": "content" "label": "content"
} }
] ]
},
{
"nodeId": "xDvVyZbQIrPg",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -272.2181157945658,
"y": 125.65095361549629
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -14,7 +14,7 @@
"nodes": [ "nodes": [
{ {
"nodeId": "lmpb9v2lo2lk", "nodeId": "lmpb9v2lo2lk",
"name": "自定义插件输入", "name": "插件开始",
"intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入",
"avatar": "/imgs/workflow/input.png", "avatar": "/imgs/workflow/input.png",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
@ -48,7 +48,7 @@
}, },
{ {
"nodeId": "i7uow4wj2wdp", "nodeId": "i7uow4wj2wdp",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",

View File

@ -12,7 +12,7 @@
"nodes": [ "nodes": [
{ {
"nodeId": "lmpb9v2lo2lk", "nodeId": "lmpb9v2lo2lk",
"name": "自定义插件输入", "name": "插件开始",
"intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入",
"avatar": "/imgs/workflow/input.png", "avatar": "/imgs/workflow/input.png",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
@ -27,7 +27,7 @@
}, },
{ {
"nodeId": "i7uow4wj2wdp", "nodeId": "i7uow4wj2wdp",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",

View File

@ -48,7 +48,7 @@
}, },
{ {
"nodeId": "sowtxkCPjvb7", "nodeId": "sowtxkCPjvb7",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",

View File

@ -13,8 +13,9 @@ import { authPluginByTmbId } from '../../../../support/permission/app/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { computedPluginUsage } from '../../../app/plugin/utils'; import { computedPluginUsage } from '../../../app/plugin/utils';
import { filterSystemVariables } from '../utils'; import { filterSystemVariables } from '../utils';
import { getPluginRunUserQuery } from '../../utils';
import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt'; import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
import { getPluginRunUserQuery } from '@fastgpt/global/core/workflow/utils';
import { getPluginInputsFromStoreNodes } from '@fastgpt/global/core/app/plugin/utils';
type RunPluginProps = ModuleDispatchProps<{ type RunPluginProps = ModuleDispatchProps<{
[key: string]: any; [key: string]: any;
@ -79,7 +80,7 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
}, },
variables: runtimeVariables, variables: runtimeVariables,
query: getPluginRunUserQuery({ query: getPluginRunUserQuery({
nodes: plugin.nodes, pluginInputs: getPluginInputsFromStoreNodes(plugin.nodes),
variables: runtimeVariables, variables: runtimeVariables,
files files
}).value, }).value,

View File

@ -1,3 +1,6 @@
import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
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 type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
export type PluginInputProps = ModuleDispatchProps<{ export type PluginInputProps = ModuleDispatchProps<{
@ -5,7 +8,16 @@ export type PluginInputProps = ModuleDispatchProps<{
}>; }>;
export const dispatchPluginInput = (props: PluginInputProps) => { export const dispatchPluginInput = (props: PluginInputProps) => {
const { params } = props; const { params, query } = props;
const { files } = chatValue2RuntimePrompt(query);
return params; return {
...params,
[DispatchNodeResponseKeyEnum.nodeResponse]: {},
[NodeOutputKeyEnum.userFiles]: files
.map((item) => {
return item?.url ?? '';
})
.filter(Boolean)
};
}; };

View File

@ -32,26 +32,3 @@ export const filterSearchResultsByMaxChars = async (
return results.length === 0 ? list.slice(0, 1) : results; return results.length === 0 ? list.slice(0, 1) : results;
}; };
/* Get plugin runtime input user query */
export const getPluginRunUserQuery = ({
nodes,
variables,
files = []
}: {
nodes: StoreNodeItemType[];
variables: Record<string, any>;
files?: RuntimeUserPromptType['files'];
}): UserChatItemType & { dataId: string } => {
return {
dataId: getNanoid(24),
obj: ChatRoleEnum.Human,
value: runtimePrompt2ChatsValue({
text: getPluginRunContent({
pluginInputs: getPluginInputsFromStoreNodes(nodes),
variables
}),
files
})
};
};

View File

@ -129,6 +129,7 @@ export const iconPaths = {
'core/chat/feedback/goodLight': () => import('./icons/core/chat/feedback/goodLight.svg'), 'core/chat/feedback/goodLight': () => import('./icons/core/chat/feedback/goodLight.svg'),
'core/chat/fileSelect': () => import('./icons/core/chat/fileSelect.svg'), 'core/chat/fileSelect': () => import('./icons/core/chat/fileSelect.svg'),
'core/chat/finishSpeak': () => import('./icons/core/chat/finishSpeak.svg'), 'core/chat/finishSpeak': () => import('./icons/core/chat/finishSpeak.svg'),
'core/chat/imgSelect': () => import('./icons/core/chat/imgSelect.svg'),
'core/chat/quoteFill': () => import('./icons/core/chat/quoteFill.svg'), 'core/chat/quoteFill': () => import('./icons/core/chat/quoteFill.svg'),
'core/chat/quoteSign': () => import('./icons/core/chat/quoteSign.svg'), 'core/chat/quoteSign': () => import('./icons/core/chat/quoteSign.svg'),
'core/chat/recordFill': () => import('./icons/core/chat/recordFill.svg'), 'core/chat/recordFill': () => import('./icons/core/chat/recordFill.svg'),

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
<path d="M5.95235 7.67193C6.57367 7.67193 7.07735 7.16825 7.07735 6.54693C7.07735 5.92561 6.57367 5.42193 5.95235 5.42193C5.33103 5.42193 4.82735 5.92561 4.82735 6.54693C4.82735 7.16825 5.33103 7.67193 5.95235 7.67193Z"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 6.58335C1.5 5.07121 1.5 4.31514 1.79428 3.73758C2.05314 3.22954 2.46619 2.81649 2.97423 2.55763C3.55179 2.26335 4.30786 2.26335 5.82 2.26335H12.18C13.6921 2.26335 14.4482 2.26335 15.0258 2.55763C15.5338 2.81649 15.9469 3.22954 16.2057 3.73758C16.5 4.31514 16.5 5.07121 16.5 6.58335V11.4166C16.5 12.9288 16.5 13.6848 16.2057 14.2624C15.9469 14.7704 15.5338 15.1835 15.0258 15.4424C14.4482 15.7366 13.6921 15.7366 12.18 15.7366H5.82C4.30786 15.7366 3.55179 15.7366 2.97423 15.4424C2.46619 15.1835 2.05314 14.7704 1.79428 14.2624C1.5 13.6848 1.5 12.9288 1.5 11.4166V6.58335ZM5.82 3.76335H12.18C12.9608 3.76335 13.4562 3.76452 13.8312 3.79516C14.1887 3.82436 14.3027 3.8727 14.3448 3.89414C14.5706 4.00919 14.7542 4.19277 14.8692 4.41856C14.8906 4.46064 14.939 4.57468 14.9682 4.93214C14.9988 5.30712 15 5.80253 15 6.58335V11.4166C15 11.4257 15 11.4347 15 11.4436L11.3619 7.80557C11.069 7.51268 10.5942 7.51268 10.3013 7.80557L3.92897 14.1779C3.75496 14.1515 3.68592 14.1215 3.65521 14.1058C3.42942 13.9908 3.24584 13.8072 3.13079 13.5814C3.10935 13.5393 3.06101 13.4253 3.0318 13.0678C3.00117 12.6929 3 12.1975 3 11.4166V6.58335C3 5.80253 3.00117 5.30713 3.0318 4.93214C3.06101 4.57468 3.10935 4.46064 3.13079 4.41856C3.24584 4.19277 3.42942 4.00919 3.65521 3.89414C3.69729 3.8727 3.81132 3.82436 4.16879 3.79516C4.54377 3.76452 5.03918 3.76335 5.82 3.76335ZM10.8316 9.39656L5.99153 14.2366H12.18C12.9608 14.2366 13.4562 14.2355 13.8312 14.2048C14.1887 14.1756 14.3027 14.1273 14.3448 14.1058C14.5706 13.9908 14.7542 13.8072 14.8692 13.5814C14.8784 13.5633 14.8927 13.5318 14.9082 13.4732L10.8316 9.39656Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -15,6 +15,8 @@
"delete_all_input_guide_confirm": "Are you sure you want to clear the input guide lexicon?", "delete_all_input_guide_confirm": "Are you sure you want to clear the input guide lexicon?",
"empty_directory": "This directory is empty~", "empty_directory": "This directory is empty~",
"file_amount_over": "Exceeded maximum file quantity {{max}}", "file_amount_over": "Exceeded maximum file quantity {{max}}",
"file_input": "File input",
"file_input_tip": "You can obtain the link to the corresponding file through the \"File Link\" of the [Plug-in Start] node",
"in_progress": "In Progress", "in_progress": "In Progress",
"input_guide": "Input Guide", "input_guide": "Input Guide",
"input_guide_lexicon": "Lexicon", "input_guide_lexicon": "Lexicon",
@ -32,9 +34,12 @@
"response": { "response": {
"node_inputs": "Node Inputs" "node_inputs": "Node Inputs"
}, },
"select_file": "Select File", "select": "Select",
"select_img": "Select Image", "select_file": "Upload File",
"select_file_img": "Upload file / image",
"select_img": "Upload Image",
"stream_output": "Stream Output", "stream_output": "Stream Output",
"upload": "Upload",
"view_citations": "View References", "view_citations": "View References",
"web_site_sync": "Web Site Sync" "web_site_sync": "Web Site Sync"
} }

View File

@ -810,7 +810,6 @@
"QueryExtension": { "QueryExtension": {
"placeholder": "For example:\nQuestions about the introduction and use of Python.\nThe current conversation is related to the game 'GTA5'." "placeholder": "For example:\nQuestions about the introduction and use of Python.\nThe current conversation is related to the game 'GTA5'."
}, },
"Quote prompt setting": "Quote Prompt Configuration",
"Select app": "Select App", "Select app": "Select App",
"Setting quote prompt": "Configure Quote Prompt", "Setting quote prompt": "Configure Quote Prompt",
"Variable": "Global Variable", "Variable": "Global Variable",
@ -899,7 +898,6 @@
"empty_plugin": "Blank plugin", "empty_plugin": "Blank plugin",
"empty_workflow": "Blank workflow", "empty_workflow": "Blank workflow",
"http body placeholder": "Same syntax as Apifox", "http body placeholder": "Same syntax as Apifox",
"self_input": "Custom plug-in input",
"self_output": "Custom plug-in output", "self_output": "Custom plug-in output",
"system_config": "System configuration", "system_config": "System configuration",
"system_config_info": "Can configure application system parameters", "system_config_info": "Can configure application system parameters",
@ -1384,10 +1382,6 @@
}, },
"tag_list": "Tag List", "tag_list": "Tag List",
"team_tag": "Team Tag", "team_tag": "Team Tag",
"template": {
"Quote Content Tip": "You can customize the structure of the quoted content to better adapt to different scenarios. You can use some variables to configure the template:\n{{q}} - Search content, {{a}} - Expected content, {{source}} - Source, {{sourceId}} - Source file name, {{index}} - The nth quote, they are all optional. Below is the default value:\n{{default}}",
"Quote Prompt Tip": "You can use {{quote}} to insert the quote content template, and use {{question}} to insert the question. Below is the default value:\n{{default}}"
},
"textarea_variable_picker_tip": "Enter \"/\" to select a variable", "textarea_variable_picker_tip": "Enter \"/\" to select a variable",
"tool_field": "Tool Field Parameter Configuration", "tool_field": "Tool Field Parameter Configuration",
"undefined_var": "Referenced an undefined variable, add it automatically?", "undefined_var": "Referenced an undefined variable, add it automatically?",

View File

@ -2,7 +2,6 @@
"Array_element": "Array element", "Array_element": "Array element",
"Code": "Code", "Code": "Code",
"Quote_prompt_setting": "Quote prompt", "Quote_prompt_setting": "Quote prompt",
"about_xxx_question": "Question regarding xxx",
"add_new_input": "Add New Input", "add_new_input": "Add New Input",
"append_application_reply_to_history_as_new_context": "Append the application's reply to the history as new context", "append_application_reply_to_history_as_new_context": "Append the application's reply to the history as new context",
"application_call": "Application Call", "application_call": "Application Call",
@ -28,7 +27,6 @@
"create_link_error": "Error creating link", "create_link_error": "Error creating link",
"custom_feedback": "Custom Feedback", "custom_feedback": "Custom Feedback",
"custom_input": "Custom Input", "custom_input": "Custom Input",
"custom_plugin_output": "Custom Plugin Output",
"dataset_quote_role": "Role", "dataset_quote_role": "Role",
"dataset_quote_role_system_option_desc": "Historical records should be consistent first (recommended)", "dataset_quote_role_system_option_desc": "Historical records should be consistent first (recommended)",
"dataset_quote_role_tip": "When set to System, the knowledge base reference content will be placed in the system message, which can ensure the continuity of the history record, but the constraint effect may not be good.\n\nWhen set to User, the knowledge base reference content will be placed in the user message, and the {{question}} variable location needs to be specified. \nIt will have a certain impact on the consistency of historical records, but usually the constraint effect is better.", "dataset_quote_role_tip": "When set to System, the knowledge base reference content will be placed in the system message, which can ensure the continuity of the history record, but the constraint effect may not be good.\n\nWhen set to User, the knowledge base reference content will be placed in the user message, and the {{question}} variable location needs to be specified. \nIt will have a certain impact on the consistency of historical records, but usually the constraint effect is better.",
@ -57,7 +55,6 @@
"full_response_data": "Full Response Data", "full_response_data": "Full Response Data",
"greater_than": "Greater Than", "greater_than": "Greater Than",
"greater_than_or_equal_to": "Greater Than or Equal To", "greater_than_or_equal_to": "Greater Than or Equal To",
"greeting": "Greeting",
"http_raw_response_description": "Raw HTTP response. Only accepts string or JSON type response data.", "http_raw_response_description": "Raw HTTP response. Only accepts string or JSON type response data.",
"http_request": "HTTP Request", "http_request": "HTTP Request",
"http_request_error_info": "HTTP request error information, returns empty on success", "http_request_error_info": "HTTP request error information, returns empty on success",
@ -105,7 +102,6 @@
"only_the_reference_type_is_supported": "Only reference type is supported", "only_the_reference_type_is_supported": "Only reference type is supported",
"optional_value_type": "Optional Value Type", "optional_value_type": "Optional Value Type",
"optional_value_type_tip": "You can specify one or more data types. When dynamically adding fields, users can only select the configured types.", "optional_value_type_tip": "You can specify one or more data types. When dynamically adding fields, users can only select the configured types.",
"other_questions": "Other Questions",
"pan_priority": "Touchpad first", "pan_priority": "Touchpad first",
"pass_returned_object_as_output_to_next_nodes": "Pass the object returned in the code as output to the next nodes. The variable name needs to correspond to the return key.", "pass_returned_object_as_output_to_next_nodes": "Pass the object returned in the code as output to the next nodes. The variable name needs to correspond to the return key.",
"plugin": { "plugin": {
@ -148,6 +144,8 @@
"tool_call_intro": "Automatically select one or more functional blocks for calling through the AI model, or call plugins.", "tool_call_intro": "Automatically select one or more functional blocks for calling through the AI model, or call plugins.",
"workflow_start": "Workflow Start" "workflow_start": "Workflow Start"
}, },
"template.plugin_output": "Plugin output",
"template.plugin_start": "Plugin start",
"text_concatenation": "Text Concatenation", "text_concatenation": "Text Concatenation",
"text_content_extraction": "Text Content Extraction", "text_content_extraction": "Text Content Extraction",
"text_to_extract": "Text to Extract", "text_to_extract": "Text to Extract",

View File

@ -15,6 +15,8 @@
"delete_all_input_guide_confirm": "确定要清空输入引导词库吗?", "delete_all_input_guide_confirm": "确定要清空输入引导词库吗?",
"empty_directory": "这个目录已经没东西可选了~", "empty_directory": "这个目录已经没东西可选了~",
"file_amount_over": "超出最大文件数量 {{max}}", "file_amount_over": "超出最大文件数量 {{max}}",
"file_input": "系统文件",
"file_input_tip": "可通过【插件开始】节点的“文件链接”获取对应文件的链接",
"in_progress": "进行中", "in_progress": "进行中",
"input_guide": "输入引导", "input_guide": "输入引导",
"input_guide_lexicon": "词库", "input_guide_lexicon": "词库",
@ -32,9 +34,12 @@
"response": { "response": {
"node_inputs": "节点输入" "node_inputs": "节点输入"
}, },
"select_file": "选择文件", "select": "选择",
"select_img": "选择图片", "select_file": "上传文件",
"select_file_img": "上传文件/图片",
"select_img": "上传图片",
"stream_output": "流输出", "stream_output": "流输出",
"upload": "上传",
"view_citations": "查看引用", "view_citations": "查看引用",
"web_site_sync": "Web站点同步" "web_site_sync": "Web站点同步"
} }

View File

@ -810,7 +810,6 @@
"QueryExtension": { "QueryExtension": {
"placeholder": "例如:\n关于 Python 的介绍和使用等问题。\n当前对话与游戏《GTA5》有关。" "placeholder": "例如:\n关于 Python 的介绍和使用等问题。\n当前对话与游戏《GTA5》有关。"
}, },
"Quote prompt setting": "引用提示词配置",
"Select app": "选择应用", "Select app": "选择应用",
"Setting quote prompt": "配置引用提示词", "Setting quote prompt": "配置引用提示词",
"Variable": "全局变量", "Variable": "全局变量",
@ -899,8 +898,7 @@
"empty_plugin": "空白插件", "empty_plugin": "空白插件",
"empty_workflow": "空白工作流", "empty_workflow": "空白工作流",
"http body placeholder": "与 Apifox 相同的语法", "http body placeholder": "与 Apifox 相同的语法",
"self_input": "自定义插件输入", "self_output": "插件输出",
"self_output": "自定义插件输出",
"system_config": "系统配置", "system_config": "系统配置",
"system_config_info": "可以配置应用的系统参数", "system_config_info": "可以配置应用的系统参数",
"work_start": "流程开始" "work_start": "流程开始"
@ -1384,10 +1382,6 @@
}, },
"tag_list": "标签列表", "tag_list": "标签列表",
"team_tag": "团队标签", "team_tag": "团队标签",
"template": {
"Quote Content Tip": "可以自定义引用内容的结构,以更好的适配不同场景。可以使用一些变量来进行模板配置:\n{{q}} - 检索内容,{{a}} - 预期内容,{{source}} - 来源,{{sourceId}} - 来源文件名,{{index}} - 第 n 个引用,他们都是可选的,下面是默认值:\n{{default}}",
"Quote Prompt Tip": "可以用 {{quote}} 来插入引用内容模板,使用 {{question}} 来插入问题。下面是默认值:\n{{default}}"
},
"textarea_variable_picker_tip": "输入\"/\"可选择变量", "textarea_variable_picker_tip": "输入\"/\"可选择变量",
"tool_field": "工具字段参数配置", "tool_field": "工具字段参数配置",
"undefined_var": "引用了未定义的变量,是否自动添加?", "undefined_var": "引用了未定义的变量,是否自动添加?",

View File

@ -2,7 +2,6 @@
"Array_element": "数组元素", "Array_element": "数组元素",
"Code": "代码", "Code": "代码",
"Quote_prompt_setting": "引用提示词配置", "Quote_prompt_setting": "引用提示词配置",
"about_xxx_question": "关于 xxx 的问题",
"add_new_input": "新增输入", "add_new_input": "新增输入",
"append_application_reply_to_history_as_new_context": "将该应用回复内容拼接到历史记录中,作为新的上下文返回", "append_application_reply_to_history_as_new_context": "将该应用回复内容拼接到历史记录中,作为新的上下文返回",
"application_call": "应用调用", "application_call": "应用调用",
@ -28,7 +27,6 @@
"create_link_error": "创建链接异常", "create_link_error": "创建链接异常",
"custom_feedback": "自定义反馈", "custom_feedback": "自定义反馈",
"custom_input": "自定义输入", "custom_input": "自定义输入",
"custom_plugin_output": "自定义插件输出",
"dataset_quote_role": "角色", "dataset_quote_role": "角色",
"dataset_quote_role_system_option_desc": "历史记录连贯优先(推荐)", "dataset_quote_role_system_option_desc": "历史记录连贯优先(推荐)",
"dataset_quote_role_tip": "设置为 System 时,将会把知识库引用内容放置到 system 消息中,可以确保历史记录的连贯性,但约束效果可能不佳,需要多调试。\n设置为 User 时,将会把知识库引用内容放置到 user 消息中,并且需要指定 {{question}} 变量位置。会对历史记录连贯性有一定影响,但通常约束效果更优。", "dataset_quote_role_tip": "设置为 System 时,将会把知识库引用内容放置到 system 消息中,可以确保历史记录的连贯性,但约束效果可能不佳,需要多调试。\n设置为 User 时,将会把知识库引用内容放置到 user 消息中,并且需要指定 {{question}} 变量位置。会对历史记录连贯性有一定影响,但通常约束效果更优。",
@ -57,7 +55,6 @@
"full_response_data": "完整响应数据", "full_response_data": "完整响应数据",
"greater_than": "大于", "greater_than": "大于",
"greater_than_or_equal_to": "大于等于", "greater_than_or_equal_to": "大于等于",
"greeting": "打招呼",
"http_raw_response_description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", "http_raw_response_description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"http_request": "HTTP 请求", "http_request": "HTTP 请求",
"http_request_error_info": "HTTP请求错误信息成功时返回空", "http_request_error_info": "HTTP请求错误信息成功时返回空",
@ -111,7 +108,6 @@
"only_the_reference_type_is_supported": "仅支持引用类型", "only_the_reference_type_is_supported": "仅支持引用类型",
"optional_value_type": "可选的数据类型", "optional_value_type": "可选的数据类型",
"optional_value_type_tip": "可以指定 1 个或多个数据类型,用户在动态添加字段时,仅可选择配置的类型", "optional_value_type_tip": "可以指定 1 个或多个数据类型,用户在动态添加字段时,仅可选择配置的类型",
"other_questions": "其他问题",
"pan_priority": "触摸板优先", "pan_priority": "触摸板优先",
"pass_returned_object_as_output_to_next_nodes": "将代码中 return 的对象作为输出,传递给后续的节点。变量名需要对应 return 的 key", "pass_returned_object_as_output_to_next_nodes": "将代码中 return 的对象作为输出,传递给后续的节点。变量名需要对应 return 的 key",
"plugin": { "plugin": {
@ -154,6 +150,8 @@
"tool_call_intro": "通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。", "tool_call_intro": "通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。",
"workflow_start": "流程开始" "workflow_start": "流程开始"
}, },
"template.plugin_output": "插件输出",
"template.plugin_start": "插件开始",
"text_concatenation": "文本拼接", "text_concatenation": "文本拼接",
"text_content_extraction": "文本内容提取", "text_content_extraction": "文本内容提取",
"text_to_extract": "需要提取的文本", "text_to_extract": "需要提取的文本",

View File

@ -12,7 +12,7 @@
"nodes": [ "nodes": [
{ {
"nodeId": "lmpb9v2lo2lk", "nodeId": "lmpb9v2lo2lk",
"name": "自定义插件输入", "name": "插件开始",
"intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入",
"avatar": "/imgs/workflow/input.png", "avatar": "/imgs/workflow/input.png",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
@ -68,7 +68,7 @@
}, },
{ {
"nodeId": "i7uow4wj2wdp", "nodeId": "i7uow4wj2wdp",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",

View File

@ -12,7 +12,7 @@
"nodes": [ "nodes": [
{ {
"nodeId": "lmpb9v2lo2lk", "nodeId": "lmpb9v2lo2lk",
"name": "自定义插件输入", "name": "插件开始",
"intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入",
"avatar": "/imgs/workflow/input.png", "avatar": "/imgs/workflow/input.png",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
@ -26,7 +26,7 @@
}, },
{ {
"nodeId": "i7uow4wj2wdp", "nodeId": "i7uow4wj2wdp",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",

View File

@ -14,7 +14,7 @@
"nodes": [ "nodes": [
{ {
"nodeId": "lmpb9v2lo2lk", "nodeId": "lmpb9v2lo2lk",
"name": "自定义插件输入", "name": "插件开始",
"intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入",
"avatar": "/imgs/workflow/input.png", "avatar": "/imgs/workflow/input.png",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
@ -71,7 +71,7 @@
}, },
{ {
"nodeId": "i7uow4wj2wdp", "nodeId": "i7uow4wj2wdp",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "/imgs/workflow/output.png",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",

View File

@ -10,7 +10,7 @@
"modules": [ "modules": [
{ {
"moduleId": "w90mfp", "moduleId": "w90mfp",
"name": "自定义插件输入", "name": "插件开始",
"flowType": "pluginInput", "flowType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {

View File

@ -10,7 +10,7 @@
"modules": [ "modules": [
{ {
"moduleId": "m8dupj", "moduleId": "m8dupj",
"name": "自定义插件输入", "name": "插件开始",
"intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入",
"avatar": "/imgs/module/input.png", "avatar": "/imgs/module/input.png",
"flowType": "pluginInput", "flowType": "pluginInput",
@ -48,7 +48,7 @@
}, },
{ {
"moduleId": "bjsa7r", "moduleId": "bjsa7r",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/module/output.png", "avatar": "/imgs/module/output.png",
"flowType": "pluginOutput", "flowType": "pluginOutput",

View File

@ -10,7 +10,7 @@
"modules": [ "modules": [
{ {
"moduleId": "w90mfp", "moduleId": "w90mfp",
"name": "自定义插件输入", "name": "插件开始",
"flowType": "pluginInput", "flowType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
@ -94,7 +94,7 @@
}, },
{ {
"moduleId": "tze1ju", "moduleId": "tze1ju",
"name": "自定义插件输出", "name": "插件输出",
"flowType": "pluginOutput", "flowType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {

View File

@ -11,7 +11,7 @@
"modules": [ "modules": [
{ {
"moduleId": "w90mfp", "moduleId": "w90mfp",
"name": "自定义插件输入", "name": "插件开始",
"flowType": "pluginInput", "flowType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
@ -78,7 +78,7 @@
}, },
{ {
"moduleId": "tze1ju", "moduleId": "tze1ju",
"name": "自定义插件输出", "name": "插件输出",
"flowType": "pluginOutput", "flowType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {

View File

@ -9,14 +9,14 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "core/workflow/template/workflowStart", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 351.2046235980429, "x": 503.3030871469042,
"y": -77.41739975794749 "y": -91.64434154072819
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -44,14 +44,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "core/workflow/template/pluginOutput", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1983.6911708285384, "x": 1876.2082565873427,
"y": -95.86447885674228 "y": -110.14434154072819
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -95,7 +95,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -106,6 +106,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -115,7 +116,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -123,17 +126,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "https://fal.run/fal-ai/flux-pro" "value": "https://fal.run/fal-ai/flux-pro",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -147,9 +166,11 @@
} }
], ],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -157,7 +178,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -165,7 +188,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"prompt\": \"{{prompt}}\",\n \"image_size\": \"landscape_4_3\",\n \"num_inference_steps\": 28,\n \"guidance_scale\": 3.5\n}", "value": "{\n \"prompt\": \"{{prompt}}\",\n \"image_size\": \"landscape_4_3\",\n \"num_inference_steps\": 28,\n \"guidance_scale\": 3.5\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -183,6 +228,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -201,7 +247,7 @@
{ {
"id": "error", "id": "error",
"key": "error", "key": "error",
"label": "请求错误", "label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空", "description": "HTTP请求错误信息成功时返回空",
"valueType": "object", "valueType": "object",
"type": "static" "type": "static"
@ -209,8 +255,8 @@
{ {
"id": "httpRawResponse", "id": "httpRawResponse",
"key": "httpRawResponse", "key": "httpRawResponse",
"label": "原始响应",
"required": true, "required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", "description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any", "valueType": "any",
"type": "static" "type": "static"
@ -250,6 +296,20 @@
"label": "images[0].url" "label": "images[0].url"
} }
] ]
},
{
"nodeId": "lSYsc889IXDr",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": 45.52914573588026,
"y": -110.14434154072819
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -9,14 +9,14 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "可以配置插件需要哪些输入,利用这些输入来运行插件", "intro": "可以配置插件需要哪些输入,利用这些输入来运行插件",
"avatar": "core/workflow/template/workflowStart", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 412.7756423516722, "x": 421.97302886868476,
"y": -99.80686112290361 "y": -89.7785530936485
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -44,14 +44,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "core/workflow/template/pluginOutput", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1822.7195641525896, "x": 1785.9300180845394,
"y": -193.54601587659562 "y": -108.2785530936485
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -95,7 +95,7 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input", "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": { "customInputConfig": {
"selectValueTypeList": [ "selectValueTypeList": [
"string", "string",
@ -106,6 +106,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -115,7 +116,9 @@
], ],
"showDescription": false, "showDescription": false,
"showDefaultValue": true "showDefaultValue": true
} },
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpMethod", "key": "system_httpMethod",
@ -123,17 +126,33 @@
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"value": "POST", "value": "POST",
"required": true "required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpReqUrl", "key": "system_httpReqUrl",
"renderTypeList": ["hidden"], "renderTypeList": ["hidden"],
"valueType": "string", "valueType": "string",
"label": "", "label": "",
"description": "core.module.input.description.Http Request Url", "description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory", "placeholder": "https://api.ai.com/getInventory",
"required": false, "required": false,
"value": "https://api.openai.com/v1/images/generations" "value": "https://api.openai.com/v1/images/generations",
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpHeader", "key": "system_httpHeader",
@ -147,9 +166,11 @@
} }
], ],
"label": "", "label": "",
"description": "core.module.input.description.Http Request Header", "description": "common:core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header", "placeholder": "common:core.module.input.description.Http Request Header",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpParams", "key": "system_httpParams",
@ -157,7 +178,9 @@
"valueType": "any", "valueType": "any",
"value": [], "value": [],
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "system_httpJsonBody", "key": "system_httpJsonBody",
@ -165,7 +188,29 @@
"valueType": "any", "valueType": "any",
"value": "{\n \"model\": \"dall-e-3\",\n \"prompt\": \"{{prompt}}\",\n \"n\": 1,\n \"size\": \"1024x1024\"\n}", "value": "{\n \"model\": \"dall-e-3\",\n \"prompt\": \"{{prompt}}\",\n \"n\": 1,\n \"size\": \"1024x1024\"\n}",
"label": "", "label": "",
"required": false "required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"renderTypeList": ["reference"], "renderTypeList": ["reference"],
@ -183,6 +228,7 @@
"arrayNumber", "arrayNumber",
"arrayBoolean", "arrayBoolean",
"arrayObject", "arrayObject",
"arrayAny",
"any", "any",
"chatHistory", "chatHistory",
"datasetQuote", "datasetQuote",
@ -201,7 +247,7 @@
{ {
"id": "error", "id": "error",
"key": "error", "key": "error",
"label": "请求错误", "label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空", "description": "HTTP请求错误信息成功时返回空",
"valueType": "object", "valueType": "object",
"type": "static" "type": "static"
@ -209,8 +255,8 @@
{ {
"id": "httpRawResponse", "id": "httpRawResponse",
"key": "httpRawResponse", "key": "httpRawResponse",
"label": "原始响应",
"required": true, "required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。", "description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any", "valueType": "any",
"type": "static" "type": "static"
@ -250,6 +296,20 @@
"label": "data[0].url" "label": "data[0].url"
} }
] ]
},
{
"nodeId": "c7tRU2qAQoAf",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": -46.476647046261974,
"y": -89.7785530936485
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -9,14 +9,14 @@
"nodes": [ "nodes": [
{ {
"nodeId": "pluginInput", "nodeId": "pluginInput",
"name": "自定义插件输入", "name": "插件开始",
"intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入", "intro": "自定义配置外部输入,使用插件时,仅暴露自定义配置的输入",
"avatar": "core/workflow/template/workflowStart", "avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput", "flowNodeType": "pluginInput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 517.5620777851774, "x": 535.7465806305546,
"y": -173.55711888178655 "y": -201.26482361861054
}, },
"version": "481", "version": "481",
"inputs": [ "inputs": [
@ -79,14 +79,14 @@
}, },
{ {
"nodeId": "pluginOutput", "nodeId": "pluginOutput",
"name": "自定义插件输出", "name": "插件输出",
"intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出", "intro": "自定义配置外部输出,使用插件时,仅暴露自定义配置的输出",
"avatar": "/imgs/workflow/output.png", "avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput", "flowNodeType": "pluginOutput",
"showStatus": false, "showStatus": false,
"position": { "position": {
"x": 1668.9410524554828, "x": 1776.027569211593,
"y": -153.47815316221283 "y": -58.264823618610535
}, },
"version": "481", "version": "481",
"inputs": [], "inputs": [],
@ -111,7 +111,116 @@
"valueType": "dynamic", "valueType": "dynamic",
"label": "", "label": "",
"required": false, "required": false,
"description": "core.module.input.description.HTTP Dynamic Input" "description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"arrayAny",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
},
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpMethod",
"renderTypeList": ["custom"],
"valueType": "string",
"label": "",
"value": "POST",
"required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpReqUrl",
"renderTypeList": ["hidden"],
"valueType": "string",
"label": "",
"description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory",
"required": false,
"value": "{{url}}",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpHeader",
"renderTypeList": ["custom"],
"valueType": "any",
"value": [],
"label": "",
"description": "common:core.module.input.description.Http Request Header",
"placeholder": "common:core.module.input.description.Http Request Header",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpParams",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpJsonBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": "{\r\n \"msg_type\": \"text\",\r\n \"content\": {\r\n \"text\": \"{{text}}\"\r\n }\r\n}",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"debugLabel": "",
"toolDescription": ""
}, },
{ {
"key": "text", "key": "text",
@ -124,7 +233,28 @@
"key": true, "key": true,
"valueType": true "valueType": true
}, },
"value": ["pluginInput", "p0m68Dv5KaIp"] "value": ["pluginInput", "p0m68Dv5KaIp"],
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"arrayAny",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
}
}, },
{ {
"key": "url", "key": "url",
@ -137,54 +267,48 @@
"key": true, "key": true,
"valueType": true "valueType": true
}, },
"value": ["pluginInput", "mv52BrPVE6bm"] "value": ["pluginInput", "mv52BrPVE6bm"],
}, "customInputConfig": {
{ "selectValueTypeList": [
"key": "system_httpMethod", "string",
"renderTypeList": ["custom"], "number",
"valueType": "string", "boolean",
"label": "", "object",
"value": "POST", "arrayString",
"required": true "arrayNumber",
}, "arrayBoolean",
{ "arrayObject",
"key": "system_httpReqUrl", "arrayAny",
"renderTypeList": ["hidden"], "any",
"valueType": "string", "chatHistory",
"label": "", "datasetQuote",
"description": "core.module.input.description.Http Request Url", "dynamic",
"placeholder": "https://api.ai.com/getInventory", "selectApp",
"required": false, "selectDataset"
"value": "{{url}}" ],
}, "showDescription": false,
{ "showDefaultValue": true
"key": "system_httpHeader", }
"renderTypeList": ["custom"],
"valueType": "any",
"value": [],
"label": "",
"description": "core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header",
"required": false
},
{
"key": "system_httpParams",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false
},
{
"key": "system_httpJsonBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": "{\r\n \"msg_type\": \"text\",\r\n \"content\": {\r\n \"text\": \"{{text}}\"\r\n }\r\n}",
"label": "",
"required": false
} }
], ],
"outputs": [ "outputs": [
{
"id": "error",
"key": "error",
"label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{ {
"id": "system_addOutputParam", "id": "system_addOutputParam",
"key": "system_addOutputParam", "key": "system_addOutputParam",
@ -195,25 +319,22 @@
"key": true, "key": true,
"valueType": true "valueType": true
} }
},
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
} }
] ]
},
{
"nodeId": "q3ccNXiZIHoS",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": 99.73879703925843,
"y": -201.26482361861054
},
"version": "4811",
"inputs": [],
"outputs": []
} }
], ],
"edges": [ "edges": [

View File

@ -8,7 +8,8 @@ import {
useDisclosure, useDisclosure,
HStack, HStack,
Switch, Switch,
ModalFooter ModalFooter,
BoxProps
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
@ -25,8 +26,9 @@ import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
const FileSelect = ({ const FileSelect = ({
forbidVision = false, forbidVision = false,
value = defaultAppSelectFileConfig, value = defaultAppSelectFileConfig,
onChange onChange,
}: { ...labelStyle
}: Omit<BoxProps, 'onChange'> & {
forbidVision?: boolean; forbidVision?: boolean;
value?: AppFileSelectConfigType; value?: AppFileSelectConfigType;
onChange: (e: AppFileSelectConfigType) => void; onChange: (e: AppFileSelectConfigType) => void;
@ -57,7 +59,7 @@ const FileSelect = ({
return ( return (
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/app/simpleMode/file'} mr={2} w={'20px'} /> <MyIcon name={'core/app/simpleMode/file'} mr={2} w={'20px'} />
<FormLabel>{t('app:file_upload')}</FormLabel> <FormLabel {...labelStyle}>{t('app:file_upload')}</FormLabel>
<ChatFunctionTip type={'file'} /> <ChatFunctionTip type={'file'} />
<Box flex={1} /> <Box flex={1} />
<MyTooltip label={t('app:config_file_upload')}> <MyTooltip label={t('app:config_file_upload')}>

View File

@ -1,34 +1,21 @@
import { useSpeech } from '@/web/common/hooks/useSpeech'; import { useSpeech } from '@/web/common/hooks/useSpeech';
import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useSystemStore } from '@/web/common/system/useSystemStore';
import { Box, CircularProgress, Flex, HStack, Image, Spinner, Textarea } from '@chakra-ui/react'; import { Box, Flex, Spinner, Textarea } from '@chakra-ui/react';
import React, { useRef, useEffect, useCallback, useMemo } from 'react'; import React, { useRef, useEffect, useCallback, useMemo } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
import { uploadFile2DB } from '@/web/common/file/controller';
import { ChatFileTypeEnum } from '@fastgpt/global/core/chat/constants';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { import { ChatBoxInputFormType, ChatBoxInputType, SendPromptFnType } from '../type';
ChatBoxInputFormType,
ChatBoxInputType,
SendPromptFnType,
UserInputFileItemType
} from '../type';
import { textareaMinH } from '../constants'; import { textareaMinH } from '../constants';
import { UseFormReturn, useFieldArray } from 'react-hook-form'; import { UseFormReturn } from 'react-hook-form';
import { ChatBoxContext } from '../Provider'; import { ChatBoxContext } from '../Provider';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { useContextSelector } from 'use-context-selector'; import { useContextSelector } from 'use-context-selector';
import { getNanoid } from '@fastgpt/global/common/string/tools';
import { useSystem } from '@fastgpt/web/hooks/useSystem'; import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { documentFileType } from '@fastgpt/global/common/file/constants'; import { documentFileType } from '@fastgpt/global/common/file/constants';
import { getFileIcon } from '@fastgpt/global/common/file/icon'; import FilePreview from '../../components/FilePreview';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useFileUpload } from '../hooks/useFileUpload';
import { clone } from 'lodash';
import { formatFileSize } from '@fastgpt/global/common/file/tools';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { getErrText } from '@fastgpt/global/common/error/utils';
import ComplianceTip from '@/components/common/ComplianceTip/index'; import ComplianceTip from '@/components/common/ComplianceTip/index';
const InputGuideBox = dynamic(() => import('./InputGuideBox')); const InputGuideBox = dynamic(() => import('./InputGuideBox'));
@ -56,21 +43,10 @@ const ChatInput = ({
appId: string; appId: string;
}) => { }) => {
const { isPc } = useSystem(); const { isPc } = useSystem();
const { toast } = useToast();
const { t } = useTranslation(); const { t } = useTranslation();
const { feConfigs } = useSystemStore();
const { setValue, watch, control } = chatForm; const { setValue, watch, control } = chatForm;
const inputValue = watch('input'); const inputValue = watch('input');
const {
update: updateFiles,
remove: removeFiles,
fields: fileList,
replace: replaceFiles
} = useFieldArray({
control,
name: 'files'
});
const { const {
chatId, chatId,
@ -82,86 +58,32 @@ const ChatInput = ({
fileSelectConfig fileSelectConfig
} = useContextSelector(ChatBoxContext, (v) => v); } = useContextSelector(ChatBoxContext, (v) => v);
const {
File,
onOpenSelectFile,
fileList,
onSelectFile,
uploadFiles,
selectFileIcon,
selectFileLabel,
showSelectFile,
showSelectImg,
removeFiles,
replaceFiles
} = useFileUpload({
outLinkAuthData,
chatId: chatId || '',
fileSelectConfig,
control
});
const havInput = !!inputValue || fileList.length > 0; const havInput = !!inputValue || fileList.length > 0;
const hasFileUploading = fileList.some((item) => !item.url); const hasFileUploading = fileList.some((item) => !item.url);
const canSendMessage = havInput && !hasFileUploading; const canSendMessage = havInput && !hasFileUploading;
const showSelectFile = fileSelectConfig.canSelectFile;
const showSelectImg = fileSelectConfig.canSelectImg;
const maxSelectFiles = fileSelectConfig.maxFiles ?? 10;
const maxSize = (feConfigs?.uploadFileMaxSize || 1024) * 1024 * 1024; // nkb
const { icon: selectFileIcon, tooltip: selectFileTip } = useMemo(() => {
if (showSelectFile) {
return {
icon: 'core/chat/fileSelect',
tooltip: t('chat:select_file')
};
} else if (showSelectImg) {
return {
icon: 'core/chat/fileSelect',
tooltip: t('chat:select_img')
};
}
return {};
}, [showSelectFile, showSelectImg, t]);
/* file selector and upload */
const { File, onOpen: onOpenSelectFile } = useSelectFile({
fileType: `${showSelectImg ? 'image/*,' : ''} ${showSelectFile ? documentFileType : ''}`,
multiple: true,
maxCount: maxSelectFiles
});
// Upload files // Upload files
useRequest2( useRequest2(
async () => { async () => {
const filterFiles = fileList.filter((item) => item.status === 0); uploadFiles();
if (filterFiles.length === 0) return;
replaceFiles(fileList.map((item) => ({ ...item, status: 1 })));
let errorFileIndex: number[] = [];
await Promise.allSettled(
filterFiles.map(async (file) => {
const copyFile = clone(file);
copyFile.status = 1;
if (!copyFile.rawFile) return;
try {
const fileIndex = fileList.findIndex((item) => item.id === file.id)!;
// Start upload and update process
const { previewUrl } = await uploadFile2DB({
file: copyFile.rawFile,
bucketName: 'chat',
outLinkAuthData,
metadata: {
chatId
},
percentListen(e) {
copyFile.process = e;
if (!copyFile.url) {
updateFiles(fileIndex, copyFile);
}
}
});
// Update file url
copyFile.url = `${location.origin}${previewUrl}`;
updateFiles(fileIndex, copyFile);
} catch (error) {
errorFileIndex.push(fileList.findIndex((item) => item.id === file.id)!);
toast({
status: 'warning',
title: t(
getErrText(error, t('common:error.upload_file_error_filename', { name: file.name }))
)
});
}
})
);
removeFiles(errorFileIndex);
}, },
{ {
manual: false, manual: false,
@ -169,78 +91,6 @@ const ChatInput = ({
refreshDeps: [fileList, outLinkAuthData, chatId] refreshDeps: [fileList, outLinkAuthData, chatId]
} }
); );
const onSelectFile = useCallback(
async (files: File[]) => {
if (!files || files.length === 0) {
return;
}
// filter max files
if (fileList.length + files.length > maxSelectFiles) {
files = files.slice(0, maxSelectFiles - fileList.length);
toast({
status: 'warning',
title: t('chat:file_amount_over', { max: maxSelectFiles })
});
}
const filterFilesByMaxSize = files.filter((file) => file.size <= maxSize);
if (filterFilesByMaxSize.length < files.length) {
toast({
status: 'warning',
title: t('file:some_file_size_exceeds_limit', { maxSize: formatFileSize(maxSize) })
});
}
const loadFiles = await Promise.all(
filterFilesByMaxSize.map(
(file) =>
new Promise<UserInputFileItemType>((resolve, reject) => {
if (file.type.includes('image')) {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
const item: UserInputFileItemType = {
id: getNanoid(6),
rawFile: file,
type: ChatFileTypeEnum.image,
name: file.name,
icon: reader.result as string,
status: 0
};
resolve(item);
};
reader.onerror = () => {
reject(reader.error);
};
} else {
resolve({
id: getNanoid(6),
rawFile: file,
type: ChatFileTypeEnum.file,
name: file.name,
icon: getFileIcon(file.name),
status: 0
});
}
})
)
);
// Document, image
const concatFileList = clone(
fileList.concat(loadFiles).sort((a, b) => {
if (a.type === ChatFileTypeEnum.image && b.type === ChatFileTypeEnum.file) {
return 1;
} else if (a.type === ChatFileTypeEnum.file && b.type === ChatFileTypeEnum.image) {
return -1;
}
return 0;
})
);
replaceFiles(concatFileList);
},
[fileList, maxSelectFiles, replaceFiles, toast, t, maxSize]
);
/* on send */ /* on send */
const handleSend = useCallback( const handleSend = useCallback(
@ -330,91 +180,7 @@ const ChatInput = ({
), ),
[isSpeaking, isTransCription, t] [isSpeaking, isTransCription, t]
); );
const RenderFilePreview = useMemo(
() =>
fileList.length > 0 ? (
<Flex
maxH={'250px'}
overflowY={'auto'}
wrap={'wrap'}
px={[2, 4]}
pt={3}
userSelect={'none'}
gap={2}
mb={fileList.length > 0 ? 2 : 0}
>
{fileList.map((item, index) => (
<MyBox
key={index}
border={'sm'}
boxShadow={
'0px 2.571px 6.429px 0px rgba(19, 51, 107, 0.08), 0px 0px 0.643px 0px rgba(19, 51, 107, 0.08)'
}
rounded={'md'}
position={'relative'}
_hover={{
'.close-icon': { display: 'block' }
}}
>
<MyIcon
name={'closeSolid'}
w={'16px'}
h={'16px'}
color={'myGray.700'}
cursor={'pointer'}
_hover={{ color: 'red.500' }}
position={'absolute'}
bg={'white'}
right={'-8px'}
top={'-8px'}
onClick={() => removeFiles(index)}
className="close-icon"
display={['', 'none']}
zIndex={10}
/>
{item.type === ChatFileTypeEnum.image && (
<Image
alt={'img'}
src={item.icon}
w={['2rem', '3rem']}
h={['2rem', '3rem']}
borderRadius={'md'}
objectFit={'contain'}
/>
)}
{item.type === ChatFileTypeEnum.file && (
<HStack minW={['100px', '150px']} maxW={'250px'} p={2}>
<MyIcon name={item.icon as any} w={['1.5rem', '2rem']} h={['1.5rem', '2rem']} />
<Box flex={'1 0 0'} className="textEllipsis" fontSize={'xs'}>
{item.name}
</Box>
</HStack>
)}
{/* Process */}
{!item.url && (
<Flex
position={'absolute'}
inset="0"
bg="rgba(255,255,255,0.4)"
alignItems="center"
justifyContent="center"
>
<CircularProgress
value={item.process}
color="primary.600"
bg={'white'}
size={isPc ? '30px' : '35px'}
>
{/* <CircularProgressLabel>{item.process ?? 0}%</CircularProgressLabel> */}
</CircularProgress>
</Flex>
)}
</MyBox>
))}
</Flex>
) : null,
[fileList, isPc, removeFiles]
);
const RenderTextarea = useMemo( const RenderTextarea = useMemo(
() => ( () => (
<Flex alignItems={'flex-end'} mt={fileList.length > 0 ? 1 : 0} pl={[2, 4]}> <Flex alignItems={'flex-end'} mt={fileList.length > 0 ? 1 : 0} pl={[2, 4]}>
@ -431,10 +197,10 @@ const ChatInput = ({
onOpenSelectFile(); onOpenSelectFile();
}} }}
> >
<MyTooltip label={selectFileTip}> <MyTooltip label={selectFileLabel}>
<MyIcon name={selectFileIcon as any} w={'18px'} color={'myGray.600'} /> <MyIcon name={selectFileIcon as any} w={'18px'} color={'myGray.600'} />
</MyTooltip> </MyTooltip>
<File onSelect={onSelectFile} /> <File onSelect={(files) => onSelectFile({ files, fileList })} />
</Flex> </Flex>
)} )}
@ -510,7 +276,7 @@ const ChatInput = ({
.filter((file) => { .filter((file) => {
return file && fileTypeFilter(file); return file && fileTypeFilter(file);
}) as File[]; }) as File[];
onSelectFile(files); onSelectFile({ files, fileList });
if (files.length > 0) { if (files.length > 0) {
e.stopPropagation(); e.stopPropagation();
@ -636,7 +402,7 @@ const ChatInput = ({
[ [
File, File,
TextareaDom, TextareaDom,
fileList.length, fileList,
handleSend, handleSend,
hasFileUploading, hasFileUploading,
havInput, havInput,
@ -650,7 +416,7 @@ const ChatInput = ({
onStop, onStop,
onWhisperRecord, onWhisperRecord,
selectFileIcon, selectFileIcon,
selectFileTip, selectFileLabel,
setValue, setValue,
showSelectFile, showSelectFile,
showSelectImg, showSelectImg,
@ -700,7 +466,9 @@ const ChatInput = ({
{RenderTranslateLoading} {RenderTranslateLoading}
{/* file preview */} {/* file preview */}
{RenderFilePreview} <Box px={[2, 4]}>
<FilePreview fileList={fileList} removeFiles={removeFiles} />
</Box>
{RenderTextarea} {RenderTextarea}
</Box> </Box>

View File

@ -20,6 +20,7 @@ import { createContext } from 'use-context-selector';
import { FieldValues, UseFormReturn } from 'react-hook-form'; import { FieldValues, UseFormReturn } from 'react-hook-form';
import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants'; import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
import { getChatResData } from '@/web/core/chat/api'; import { getChatResData } from '@/web/core/chat/api';
import { ChatBoxInputFormType } from './type';
export type ChatProviderProps = OutLinkChatAuthProps & { export type ChatProviderProps = OutLinkChatAuthProps & {
appAvatar?: string; appAvatar?: string;
@ -29,7 +30,7 @@ export type ChatProviderProps = OutLinkChatAuthProps & {
chatHistories: ChatSiteItemType[]; chatHistories: ChatSiteItemType[];
setChatHistories: React.Dispatch<React.SetStateAction<ChatSiteItemType[]>>; setChatHistories: React.Dispatch<React.SetStateAction<ChatSiteItemType[]>>;
variablesForm: UseFormReturn<FieldValues, any>; variablesForm: UseFormReturn<ChatBoxInputFormType, any>;
// not chat test params // not chat test params
chatId?: string; chatId?: string;

View File

@ -0,0 +1,214 @@
import { useCallback, useMemo } from 'react';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useTranslation } from 'next-i18next';
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
import { uploadFile2DB } from '@/web/common/file/controller';
import { ChatFileTypeEnum } from '@fastgpt/global/core/chat/constants';
import { getNanoid } from '@fastgpt/global/common/string/tools';
import { getFileIcon } from '@fastgpt/global/common/file/icon';
import { formatFileSize } from '@fastgpt/global/common/file/tools';
import { clone } from 'lodash';
import { getErrText } from '@fastgpt/global/common/error/utils';
import { Control, useFieldArray } from 'react-hook-form';
import { ChatBoxInputFormType, UserInputFileItemType } from '../type';
import { AppFileSelectConfigType } from '@fastgpt/global/core/app/type';
import { documentFileType } from '@fastgpt/global/common/file/constants';
import { useSystemStore } from '@/web/common/system/useSystemStore';
interface UseFileUploadOptions {
outLinkAuthData: any;
chatId: string;
fileSelectConfig: AppFileSelectConfigType;
control: Control<ChatBoxInputFormType, any>;
}
export const useFileUpload = (props: UseFileUploadOptions) => {
const { outLinkAuthData, chatId, fileSelectConfig, control } = props;
const { toast } = useToast();
const { t } = useTranslation();
const { feConfigs } = useSystemStore();
const {
update: updateFiles,
remove: removeFiles,
fields: fileList,
replace: replaceFiles
} = useFieldArray({
control: control,
name: 'files'
});
const showSelectFile = fileSelectConfig?.canSelectFile;
const showSelectImg = fileSelectConfig?.canSelectImg;
const maxSelectFiles = fileSelectConfig?.maxFiles ?? 10;
const maxSize = (feConfigs?.uploadFileMaxSize || 1024) * 1024 * 1024; // nkb
const { icon: selectFileIcon, label: selectFileLabel } = useMemo(() => {
if (showSelectFile && showSelectImg) {
return {
icon: 'core/chat/fileSelect',
label: t('chat:select_file_img')
};
} else if (showSelectFile) {
return {
icon: 'core/chat/fileSelect',
label: t('chat:select_file')
};
} else if (showSelectImg) {
return {
icon: 'core/chat/imgSelect',
label: t('chat:select_img')
};
}
return {};
}, [showSelectFile, showSelectImg, t]);
const { File, onOpen: onOpenSelectFile } = useSelectFile({
fileType: `${showSelectImg ? 'image/*,' : ''} ${showSelectFile ? documentFileType : ''}`,
multiple: true,
maxCount: maxSelectFiles
});
const onSelectFile = useCallback(
async ({ files, fileList }: { files: File[]; fileList: UserInputFileItemType[] }) => {
if (!files || files.length === 0) {
return [];
}
// Filter max files
if (files.length > maxSelectFiles) {
files = files.slice(0, maxSelectFiles);
toast({
status: 'warning',
title: t('chat:file_amount_over', { max: maxSelectFiles })
});
}
// Filter files by max size
const filterFilesByMaxSize = files.filter((file) => file.size <= maxSize);
if (filterFilesByMaxSize.length < files.length) {
toast({
status: 'warning',
title: t('file:some_file_size_exceeds_limit', { maxSize: formatFileSize(maxSize) })
});
}
// Convert files to UserInputFileItemType
const loadFiles = await Promise.all(
filterFilesByMaxSize.map(
(file) =>
new Promise<UserInputFileItemType>((resolve, reject) => {
if (file.type.includes('image')) {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
const item: UserInputFileItemType = {
id: getNanoid(6),
rawFile: file,
type: ChatFileTypeEnum.image,
name: file.name,
icon: reader.result as string,
status: 0
};
resolve(item);
};
reader.onerror = () => {
reject(reader.error);
};
} else {
resolve({
id: getNanoid(6),
rawFile: file,
type: ChatFileTypeEnum.file,
name: file.name,
icon: getFileIcon(file.name),
status: 0
});
}
})
)
);
// Document, image
const concatFileList = clone(
fileList.concat(loadFiles).sort((a, b) => {
if (a.type === ChatFileTypeEnum.image && b.type === ChatFileTypeEnum.file) {
return 1;
} else if (a.type === ChatFileTypeEnum.file && b.type === ChatFileTypeEnum.image) {
return -1;
}
return 0;
})
);
replaceFiles(concatFileList);
return loadFiles;
},
[maxSelectFiles, replaceFiles, toast, t, maxSize]
);
const uploadFiles = async () => {
const filterFiles = fileList.filter((item) => item.status === 0);
if (filterFiles.length === 0) return;
replaceFiles(fileList.map((item) => ({ ...item, status: 1 })));
let errorFileIndex: number[] = [];
await Promise.allSettled(
filterFiles.map(async (file) => {
const copyFile = clone(file);
copyFile.status = 1;
if (!copyFile.rawFile) return;
try {
const fileIndex = fileList.findIndex((item) => item.id === file.id)!;
// Start upload and update process
const { previewUrl } = await uploadFile2DB({
file: copyFile.rawFile,
bucketName: 'chat',
outLinkAuthData,
metadata: {
chatId
},
percentListen(e) {
copyFile.process = e;
if (!copyFile.url) {
updateFiles(fileIndex, copyFile);
}
}
});
// Update file url
copyFile.url = `${location.origin}${previewUrl}`;
updateFiles(fileIndex, copyFile);
} catch (error) {
errorFileIndex.push(fileList.findIndex((item) => item.id === file.id)!);
toast({
status: 'warning',
title: t(
getErrText(error, t('common:error.upload_file_error_filename', { name: file.name }))
)
});
}
})
);
removeFiles(errorFileIndex);
};
return {
File,
onOpenSelectFile,
fileList,
onSelectFile,
uploadFiles,
selectFileIcon,
selectFileLabel,
showSelectFile,
showSelectImg,
removeFiles,
replaceFiles
};
};

View File

@ -430,7 +430,8 @@ const ChatBox = (
file: { file: {
type: file.type, type: file.type,
name: file.name, name: file.name,
url: file.url || '' url: file.url || '',
icon: file.icon || ''
} }
})), })),
...(text ...(text

View File

@ -22,6 +22,7 @@ export type ChatBoxInputFormType = {
input: string; input: string;
files: UserInputFileItemType[]; files: UserInputFileItemType[];
chatStarted: boolean; chatStarted: boolean;
[key: string]: any;
}; };
export type ChatBoxInputType = { export type ChatBoxInputType = {

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo } from 'react'; import React, { useCallback, useEffect, useMemo } from 'react';
import { Controller } from 'react-hook-form'; import { Controller } from 'react-hook-form';
import RenderPluginInput from './renderPluginInput'; import RenderPluginInput from './renderPluginInput';
import { Box, Button, Flex } from '@chakra-ui/react'; import { Box, Button, Flex } from '@chakra-ui/react';
@ -6,11 +6,19 @@ import { useTranslation } from 'next-i18next';
import { useContextSelector } from 'use-context-selector'; import { useContextSelector } from 'use-context-selector';
import { PluginRunContext } from '../context'; import { PluginRunContext } from '../context';
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants'; import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
import { isEqual } from 'lodash';
import { AppChatConfigType } from '@fastgpt/global/core/app/type';
import Markdown from '@/components/Markdown'; import Markdown from '@/components/Markdown';
import MyIcon from '@fastgpt/web/components/common/Icon';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useFileUpload } from '../../ChatBox/hooks/useFileUpload';
import FilePreview from '../../components/FilePreview';
import { UserChatItemValueItemType } from '@fastgpt/global/core/chat/type';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { ChatBoxInputFormType, UserInputFileItemType } from '../../ChatBox/type';
const RenderInput = () => { const RenderInput = () => {
const { t } = useTranslation();
const { const {
pluginInputs, pluginInputs,
variablesForm, variablesForm,
@ -19,10 +27,13 @@ const RenderInput = () => {
onNewChat, onNewChat,
onSubmit, onSubmit,
isChatting, isChatting,
chatConfig chatConfig,
chatId,
outLinkAuthData,
restartInputStore,
setRestartInputStore
} = useContextSelector(PluginRunContext, (v) => v); } = useContextSelector(PluginRunContext, (v) => v);
const { t } = useTranslation();
const { const {
control, control,
handleSubmit, handleSubmit,
@ -31,46 +42,102 @@ const RenderInput = () => {
formState: { errors } formState: { errors }
} = variablesForm; } = variablesForm;
const defaultFormValues = useMemo(() => { const {
return pluginInputs.reduce( File,
onOpenSelectFile,
fileList,
onSelectFile,
uploadFiles,
selectFileIcon,
showSelectFile,
showSelectImg,
removeFiles,
replaceFiles
} = useFileUpload({
outLinkAuthData,
chatId: chatId || '',
fileSelectConfig: chatConfig?.fileSelectConfig,
control
});
const isDisabledInput = histories.length > 0;
const onClickNewChat = useCallback(
(e: ChatBoxInputFormType, files: UserInputFileItemType[] = []) => {
setRestartInputStore({
...e,
files
});
onNewChat?.();
},
[onNewChat, setRestartInputStore]
);
useEffect(() => {
// Set last run value
if (!isDisabledInput && restartInputStore) {
reset(restartInputStore);
return;
}
// Set history to default value
const defaultFormValues = pluginInputs.reduce(
(acc, input) => { (acc, input) => {
acc[input.key] = input.defaultValue; acc[input.key] = input.defaultValue;
return acc; return acc;
}, },
{} as Record<string, any> {} as Record<string, any>
); );
}, [pluginInputs]);
const historyFormValues = useMemo(() => { const historyFormValues = (() => {
if (histories.length === 0) return undefined; if (!isDisabledInput) return undefined;
const historyValue = histories[0].value;
try {
const inputValueString = historyValue.find((item) => item.type === 'text')?.text?.content;
return (
inputValueString &&
JSON.parse(inputValueString).reduce(
(
acc: Record<string, any>,
{
key,
value
}: {
key: string;
value: any;
}
) => ({ ...acc, [key]: value }),
{}
)
);
} catch (error) {
console.error('Failed to parse input value:', error);
return undefined;
}
})();
try { // Parse history file
const inputValueString = histories[0].value[0].text?.content || '[]'; const historyFileList = (() => {
return JSON.parse(inputValueString).reduce( if (!isDisabledInput) return [];
( const historyValue = histories[0].value as UserChatItemValueItemType[];
acc: Record<string, any>, return historyValue.filter((item) => item.type === 'file').map((item) => item.file);
{ })();
key,
value
}: {
key: string;
value: any;
}
) => ({ ...acc, [key]: value }),
{}
);
} catch (error) {
console.error('Failed to parse input value:', error);
return undefined;
}
}, [histories]);
useEffect(() => { reset({
if (isEqual(getValues(), defaultFormValues)) return; ...(historyFormValues || defaultFormValues),
reset(historyFormValues || defaultFormValues); files: historyFileList
}, [defaultFormValues, getValues, historyFormValues, reset]); });
}, [getValues, histories, isDisabledInput, pluginInputs, replaceFiles, reset, restartInputStore]);
const isDisabledInput = histories.length > 0; const hasFileUploading = useMemo(() => {
return fileList.some((item) => !item.url);
}, [fileList]);
useRequest2(uploadFiles, {
manual: false,
errorToast: t('common:upload_file_error'),
refreshDeps: [fileList, outLinkAuthData, chatId]
});
return ( return (
<> <>
@ -88,7 +155,35 @@ const RenderInput = () => {
<Markdown source={chatConfig.instruction} /> <Markdown source={chatConfig.instruction} />
</Box> </Box>
)} )}
{/* file select */}
{(showSelectFile || showSelectImg) && (
<Box mb={5}>
<Flex alignItems={'center'}>
<FormLabel fontSize={'md'} fontWeight={'medium'}>
{t('chat:file_input')}
</FormLabel>
<QuestionTip ml={1} label={t('chat:file_input_tip')} />
<Box flex={1} />
{histories.length === 0 && (
<Button
leftIcon={<MyIcon name={selectFileIcon as any} w={'16px'} />}
variant={'whiteBase'}
onClick={() => {
onOpenSelectFile();
}}
>
{t('chat:select')}
</Button>
)}
<File onSelect={(files) => onSelectFile({ files, fileList })} />
</Flex>
<FilePreview
fileList={fileList}
removeFiles={isDisabledInput ? undefined : removeFiles}
/>
</Box>
)}
{/* Filed */}
{pluginInputs.map((input) => { {pluginInputs.map((input) => {
return ( return (
<Controller <Controller
@ -118,18 +213,22 @@ const RenderInput = () => {
/> />
); );
})} })}
{/* Run Button */}
{onStartChat && onNewChat && ( {onStartChat && onNewChat && (
<Flex justifyContent={'end'} mt={8}> <Flex justifyContent={'end'} mt={8}>
<Button <Button
isLoading={isChatting} isLoading={isChatting || hasFileUploading}
onClick={() => { onClick={() => {
if (histories.length > 0) { handleSubmit((e) => {
return onNewChat(); if (isDisabledInput) {
} onClickNewChat(e, fileList);
handleSubmit(onSubmit)(); } else {
onSubmit(e, fileList);
}
})();
}} }}
> >
{histories.length > 0 ? t('common:common.Restart') : t('common:common.Run')} {isDisabledInput ? t('common:common.Restart') : t('common:common.Run')}
</Button> </Button>
</Flex> </Flex>
)} )}

View File

@ -1,8 +1,12 @@
import React, { ReactNode, useCallback, useMemo, useRef, useState } from 'react'; import React, { ReactNode, useCallback, useMemo, useRef, useState } from 'react';
import { createContext } from 'use-context-selector'; import { createContext } from 'use-context-selector';
import { PluginRunBoxProps } from './type'; import { PluginRunBoxProps } from './type';
import { AIChatItemValueItemType, ChatSiteItemType } from '@fastgpt/global/core/chat/type'; import {
import { FieldValues } from 'react-hook-form'; AIChatItemValueItemType,
ChatSiteItemType,
RuntimeUserPromptType
} from '@fastgpt/global/core/chat/type';
import { FieldValues, useForm } from 'react-hook-form';
import { PluginRunBoxTabEnum } from './constants'; import { PluginRunBoxTabEnum } from './constants';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
@ -10,17 +14,23 @@ import { getNanoid } from '@fastgpt/global/common/string/tools';
import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants'; import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
import { generatingMessageProps } from '../type'; import { generatingMessageProps } from '../type';
import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import { getPluginRunContent } from '@fastgpt/global/core/app/plugin/utils';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
type PluginRunContextType = PluginRunBoxProps & { import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
isChatting: boolean; import { ChatBoxInputFormType, UserInputFileItemType } from '../ChatBox/type';
onSubmit: (e: FieldValues) => Promise<any>; import { chats2GPTMessages } from '@fastgpt/global/core/chat/adapt';
}; import { getPluginRunUserQuery } from '@fastgpt/global/core/workflow/utils';
type PluginRunContextType = OutLinkChatAuthProps &
PluginRunBoxProps & {
isChatting: boolean;
onSubmit: (e: ChatBoxInputFormType, files?: UserInputFileItemType[]) => Promise<any>;
outLinkAuthData: OutLinkChatAuthProps;
restartInputStore?: ChatBoxInputFormType;
setRestartInputStore: React.Dispatch<React.SetStateAction<ChatBoxInputFormType | undefined>>;
};
export const PluginRunContext = createContext<PluginRunContextType>({ export const PluginRunContext = createContext<PluginRunContextType>({
pluginInputs: [], pluginInputs: [],
//@ts-ignore
variablesForm: undefined,
histories: [], histories: [],
setHistories: function (value: React.SetStateAction<ChatSiteItemType[]>): void { setHistories: function (value: React.SetStateAction<ChatSiteItemType[]>): void {
throw new Error('Function not implemented.'); throw new Error('Function not implemented.');
@ -33,15 +43,24 @@ export const PluginRunContext = createContext<PluginRunContextType>({
isChatting: false, isChatting: false,
onSubmit: function (e: FieldValues): Promise<any> { onSubmit: function (e: FieldValues): Promise<any> {
throw new Error('Function not implemented.'); throw new Error('Function not implemented.');
} },
outLinkAuthData: {},
//@ts-ignore
variablesForm: undefined
}); });
const PluginRunContextProvider = ({ const PluginRunContextProvider = ({
shareId,
outLinkUid,
teamId,
teamToken,
children, children,
...props ...props
}: PluginRunBoxProps & { children: ReactNode }) => { }: PluginRunBoxProps & { children: ReactNode }) => {
const { pluginInputs, onStartChat, setHistories, histories, setTab } = props; const { pluginInputs, onStartChat, setHistories, histories, setTab } = props;
const [restartInputStore, setRestartInputStore] = useState<ChatBoxInputFormType>();
const { toast } = useToast(); const { toast } = useToast();
const chatController = useRef(new AbortController()); const chatController = useRef(new AbortController());
const { t } = useTranslation(); const { t } = useTranslation();
@ -50,6 +69,22 @@ const PluginRunContextProvider = ({
chatController.current?.abort('stop'); chatController.current?.abort('stop');
}, []); }, []);
const outLinkAuthData = useMemo(
() => ({
shareId,
outLinkUid,
teamId,
teamToken
}),
[shareId, outLinkUid, teamId, teamToken]
);
const variablesForm = useForm<ChatBoxInputFormType>({
defaultValues: {
files: []
}
});
const generatingMessage = useCallback( const generatingMessage = useCallback(
({ event, text = '', status, name, tool }: generatingMessageProps) => { ({ event, text = '', status, name, tool }: generatingMessageProps) => {
setHistories((state) => setHistories((state) =>
@ -144,90 +179,99 @@ const PluginRunContextProvider = ({
[histories] [histories]
); );
const { runAsync: onSubmit } = useRequest2(async (e: FieldValues) => { const { runAsync: onSubmit } = useRequest2(
if (!onStartChat) return; async (e: ChatBoxInputFormType, files?: UserInputFileItemType[]) => {
if (isChatting) { if (!onStartChat) return;
toast({ if (isChatting) {
title: t('chat:is_chatting'), toast({
status: 'warning' title: t('chat:is_chatting'),
}); status: 'warning'
return; });
} return;
setTab(PluginRunBoxTabEnum.output); }
// reset controller // reset controller
abortRequest(); abortRequest();
const abortSignal = new AbortController(); const abortSignal = new AbortController();
chatController.current = abortSignal; chatController.current = abortSignal;
setHistories([ setHistories([
{ {
dataId: getNanoid(24), ...getPluginRunUserQuery({
obj: ChatRoleEnum.Human, pluginInputs,
status: 'finish', variables: e,
value: [ files: files as RuntimeUserPromptType['files']
{ }),
type: ChatItemValueTypeEnum.text, status: 'finish'
text: { },
content: getPluginRunContent({ {
pluginInputs, dataId: getNanoid(24),
variables: e obj: ChatRoleEnum.AI,
}) value: [
{
type: ChatItemValueTypeEnum.text,
text: {
content: ''
}
} }
} ],
] status: 'loading'
}, }
{ ]);
dataId: getNanoid(24), setTab(PluginRunBoxTabEnum.output);
obj: ChatRoleEnum.AI,
value: [ const messages = chats2GPTMessages({
messages: [
{ {
type: ChatItemValueTypeEnum.text, dataId: getNanoid(24),
text: { obj: ChatRoleEnum.Human,
content: '' value: []
}
} }
], ],
status: 'loading' reserveId: true
}
]);
try {
const { responseData } = await onStartChat({
messages: [],
controller: chatController.current,
generatingMessage,
variables: e
}); });
setHistories((state) => try {
state.map((item, index) => { const { responseData } = await onStartChat({
if (index !== state.length - 1) return item; messages: messages,
return { controller: chatController.current,
...item, generatingMessage,
status: 'finish', variables: e
responseData });
};
}) setHistories((state) =>
); state.map((item, index) => {
} catch (err: any) { if (index !== state.length - 1) return item;
toast({ title: err.message, status: 'error' }); return {
setHistories((state) => ...item,
state.map((item, index) => { status: 'finish',
if (index !== state.length - 1) return item; responseData
return { };
...item, })
status: 'finish' );
}; } catch (err: any) {
}) toast({ title: err.message, status: 'error' });
); setHistories((state) =>
state.map((item, index) => {
if (index !== state.length - 1) return item;
return {
...item,
status: 'finish'
};
})
);
}
} }
}); );
const contextValue: PluginRunContextType = { const contextValue: PluginRunContextType = {
...props, ...props,
isChatting, isChatting,
onSubmit onSubmit,
outLinkAuthData,
variablesForm,
restartInputStore,
setRestartInputStore
}; };
return <PluginRunContext.Provider value={contextValue}>{children}</PluginRunContext.Provider>; return <PluginRunContext.Provider value={contextValue}>{children}</PluginRunContext.Provider>;
}; };

View File

@ -5,10 +5,11 @@ import { PluginRunBoxTabEnum } from './constants';
import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat'; import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
import React from 'react'; import React from 'react';
import { onStartChatType } from '../type'; import { onStartChatType } from '../type';
import { ChatBoxInputFormType } from '../ChatBox/type';
export type PluginRunBoxProps = OutLinkChatAuthProps & { export type PluginRunBoxProps = OutLinkChatAuthProps & {
pluginInputs: FlowNodeInputItemType[]; pluginInputs: FlowNodeInputItemType[];
variablesForm: UseFormReturn<FieldValues, any>; variablesForm: UseFormReturn<ChatBoxInputFormType, any>;
histories: ChatSiteItemType[]; // chatHistories[1] is the response histories: ChatSiteItemType[]; // chatHistories[1] is the response
setHistories: React.Dispatch<React.SetStateAction<ChatSiteItemType[]>>; setHistories: React.Dispatch<React.SetStateAction<ChatSiteItemType[]>>;

View File

@ -0,0 +1,121 @@
import React, { useMemo } from 'react';
import { FieldArrayWithId } from 'react-hook-form';
import { ChatBoxInputFormType } from '../ChatBox/type';
import { Box, CircularProgress, Flex, HStack, Image } from '@chakra-ui/react';
import MyBox from '@fastgpt/web/components/common/MyBox';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { ChatFileTypeEnum } from '@fastgpt/global/core/chat/constants';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
const RenderFilePreview = ({
fileList,
removeFiles
}: {
fileList: FieldArrayWithId<ChatBoxInputFormType, 'files', 'id'>[];
removeFiles?: (index?: number | number[]) => void;
}) => {
const { isPc } = useSystem();
return fileList.length > 0 ? (
<Flex
maxH={'250px'}
overflowY={'auto'}
wrap={'wrap'}
pt={3}
userSelect={'none'}
mb={fileList.length > 0 ? 2 : 0}
pr={0.5}
>
{fileList.map((item, index) => {
const isFile = item.type === ChatFileTypeEnum.file;
const isImage = item.type === ChatFileTypeEnum.image;
return (
<MyBox
key={index}
maxW={isFile ? 56 : 14}
w={isFile ? '50%' : '12.5%'}
aspectRatio={isFile ? 4 : 1}
pr={1.5}
pb={1.5}
mb={0.5}
>
<Box
border={'sm'}
boxShadow={
'0px 2.571px 6.429px 0px rgba(19, 51, 107, 0.08), 0px 0px 0.643px 0px rgba(19, 51, 107, 0.08)'
}
rounded={'md'}
position={'relative'}
_hover={{
'.close-icon': { display: 'block' }
}}
w={'full'}
h={'full'}
alignItems={'center'}
pl={isFile ? 1 : 0}
>
{removeFiles && (
<MyIcon
name={'closeSolid'}
w={'16px'}
h={'16px'}
color={'myGray.700'}
cursor={'pointer'}
_hover={{ color: 'red.500' }}
position={'absolute'}
rounded={'full'}
bg={'white'}
right={'-8px'}
top={'-8px'}
onClick={() => removeFiles(index)}
className="close-icon"
display={['', 'none']}
zIndex={10}
/>
)}
{isImage && (
<Image
alt={'img'}
src={item.icon}
w={'full'}
h={'full'}
borderRadius={'md'}
objectFit={'contain'}
/>
)}
{isFile && (
<HStack alignItems={'center'} h={'full'}>
<MyIcon name={item.icon as any} w={['1.5rem', '2rem']} h={['1.5rem', '2rem']} />
<Box flex={'1 0 0'} pr={2} className="textEllipsis" fontSize={'xs'}>
{item.name}
</Box>
</HStack>
)}
{/* Process */}
{!item.url && (
<Flex
position={'absolute'}
inset="0"
bg="rgba(255,255,255,0.4)"
alignItems="center"
justifyContent="center"
>
<CircularProgress
value={item.process}
color="primary.600"
bg={'white'}
size={isPc ? '30px' : '35px'}
>
{/* <CircularProgressLabel>{item.process ?? 0}%</CircularProgressLabel> */}
</CircularProgress>
</Flex>
)}
</Box>
</MyBox>
);
})}
</Flex>
) : null;
};
export default React.memo(RenderFilePreview);

View File

@ -2,14 +2,18 @@ import { ChatSiteItemType } from '@fastgpt/global/core/chat/type';
import { useCallback, useRef, useState } from 'react'; import { useCallback, useRef, useState } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { PluginRunBoxTabEnum } from './PluginRunBox/constants'; import { PluginRunBoxTabEnum } from './PluginRunBox/constants';
import { ComponentRef as ChatComponentRef, SendPromptFnType } from './ChatBox/type'; import {
ChatBoxInputFormType,
ComponentRef as ChatComponentRef,
SendPromptFnType
} from './ChatBox/type';
import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus'; import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus';
export const useChat = () => { export const useChat = () => {
const ChatBoxRef = useRef<ChatComponentRef>(null); const ChatBoxRef = useRef<ChatComponentRef>(null);
const [chatRecords, setChatRecords] = useState<ChatSiteItemType[]>([]); const [chatRecords, setChatRecords] = useState<ChatSiteItemType[]>([]);
const variablesForm = useForm(); const variablesForm = useForm<ChatBoxInputFormType>();
// plugin // plugin
const [pluginRunTab, setPluginRunTab] = useState<PluginRunBoxTabEnum>(PluginRunBoxTabEnum.input); const [pluginRunTab, setPluginRunTab] = useState<PluginRunBoxTabEnum>(PluginRunBoxTabEnum.input);

View File

@ -4,7 +4,7 @@ import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/cons
import { responseWrite } from '@fastgpt/service/common/response'; import { responseWrite } from '@fastgpt/service/common/response';
import { pushChatUsage } from '@/service/support/wallet/usage/push'; import { pushChatUsage } from '@/service/support/wallet/usage/push';
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants'; import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
import type { UserChatItemValueItemType } from '@fastgpt/global/core/chat/type'; import type { UserChatItemType } from '@fastgpt/global/core/chat/type';
import { authApp } from '@fastgpt/service/support/permission/app/auth'; import { authApp } from '@fastgpt/service/support/permission/app/auth';
import { dispatchWorkFlow } from '@fastgpt/service/core/workflow/dispatch'; import { dispatchWorkFlow } from '@fastgpt/service/core/workflow/dispatch';
import { authCert } from '@fastgpt/service/support/permission/auth/common'; import { authCert } from '@fastgpt/service/support/permission/auth/common';
@ -13,7 +13,10 @@ import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
import { removeEmptyUserInput } from '@fastgpt/global/core/chat/utils'; import { removeEmptyUserInput } from '@fastgpt/global/core/chat/utils';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { updatePluginInputByVariables } from '@fastgpt/global/core/workflow/utils'; import {
getPluginRunUserQuery,
updatePluginInputByVariables
} from '@fastgpt/global/core/workflow/utils';
import { NextAPI } from '@/service/middleware/entry'; import { NextAPI } from '@/service/middleware/entry';
import { GPTMessages2Chats } from '@fastgpt/global/core/chat/adapt'; import { GPTMessages2Chats } from '@fastgpt/global/core/chat/adapt';
import { ChatCompletionMessageParam } from '@fastgpt/global/core/ai/type'; import { ChatCompletionMessageParam } from '@fastgpt/global/core/ai/type';
@ -28,6 +31,7 @@ import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
import { getWorkflowResponseWrite } from '@fastgpt/service/core/workflow/dispatch/utils'; import { getWorkflowResponseWrite } from '@fastgpt/service/core/workflow/dispatch/utils';
import { getNanoid } from '@fastgpt/global/common/string/tools'; import { getNanoid } from '@fastgpt/global/common/string/tools';
import { WORKFLOW_MAX_RUN_TIMES } from '@fastgpt/service/core/workflow/constants'; import { WORKFLOW_MAX_RUN_TIMES } from '@fastgpt/service/core/workflow/constants';
import { getPluginInputsFromStoreNodes } from '@fastgpt/global/core/app/plugin/utils';
export type Props = { export type Props = {
messages: ChatCompletionMessageParam[]; messages: ChatCompletionMessageParam[];
@ -65,8 +69,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
throw new Error('Edges is not array'); throw new Error('Edges is not array');
} }
const chatMessages = GPTMessages2Chats(messages); const chatMessages = GPTMessages2Chats(messages);
const userInput = chatMessages.pop()?.value as UserChatItemValueItemType[] | undefined;
// console.log(JSON.stringify(chatMessages, null, 2), '====', chatMessages.length); // console.log(JSON.stringify(chatMessages, null, 2), '====', chatMessages.length);
/* user auth */ /* user auth */
@ -82,6 +84,22 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
const isPlugin = app.type === AppTypeEnum.plugin; const isPlugin = app.type === AppTypeEnum.plugin;
const userQuestion: UserChatItemType = (() => {
if (isPlugin) {
return getPluginRunUserQuery({
pluginInputs: getPluginInputsFromStoreNodes(app.modules),
variables,
files: variables.files
});
}
const latestHumanChat = chatMessages.pop() as UserChatItemType | undefined;
if (!latestHumanChat) {
throw new Error('User question is empty');
}
return latestHumanChat;
})();
let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes, chatMessages)); let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes, chatMessages));
// Plugin need to replace inputs // Plugin need to replace inputs
@ -89,7 +107,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables); runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables);
variables = {}; variables = {};
} else { } else {
if (!userInput) { if (!userQuestion.value) {
throw new Error('Params Error'); throw new Error('Params Error');
} }
} }
@ -117,7 +135,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
runtimeNodes, runtimeNodes,
runtimeEdges: initWorkflowEdgeStatus(edges, chatMessages), runtimeEdges: initWorkflowEdgeStatus(edges, chatMessages),
variables, variables,
query: removeEmptyUserInput(userInput), query: removeEmptyUserInput(userQuestion.value),
chatConfig, chatConfig,
histories: chatMessages, histories: chatMessages,
stream: true, stream: true,

View File

@ -49,13 +49,16 @@ import { NextAPI } from '@/service/middleware/entry';
import { getAppLatestVersion } from '@fastgpt/service/core/app/controller'; import { getAppLatestVersion } from '@fastgpt/service/core/app/controller';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { updatePluginInputByVariables } from '@fastgpt/global/core/workflow/utils'; import {
getPluginRunUserQuery,
updatePluginInputByVariables
} from '@fastgpt/global/core/workflow/utils';
import { getNanoid } from '@fastgpt/global/common/string/tools'; import { getNanoid } from '@fastgpt/global/common/string/tools';
import { getSystemTime } from '@fastgpt/global/common/time/timezone'; import { getSystemTime } from '@fastgpt/global/common/time/timezone';
import { rewriteNodeOutputByHistories } from '@fastgpt/global/core/workflow/runtime/utils'; import { rewriteNodeOutputByHistories } from '@fastgpt/global/core/workflow/runtime/utils';
import { getWorkflowResponseWrite } from '@fastgpt/service/core/workflow/dispatch/utils'; import { getWorkflowResponseWrite } from '@fastgpt/service/core/workflow/dispatch/utils';
import { getPluginRunUserQuery } from '@fastgpt/service/core/workflow/utils';
import { WORKFLOW_MAX_RUN_TIMES } from '@fastgpt/service/core/workflow/constants'; import { WORKFLOW_MAX_RUN_TIMES } from '@fastgpt/service/core/workflow/constants';
import { getPluginInputsFromStoreNodes } from '@fastgpt/global/core/app/plugin/utils';
type FastGptWebChatProps = { type FastGptWebChatProps = {
chatId?: string; // undefined: get histories from messages, '': new chat, 'xxxxx': get histories from db chatId?: string; // undefined: get histories from messages, '': new chat, 'xxxxx': get histories from db
@ -185,8 +188,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
// Get obj=Human history // Get obj=Human history
const userQuestion: UserChatItemType = (() => { const userQuestion: UserChatItemType = (() => {
if (isPlugin) { if (isPlugin) {
// TODOget plugin files from variables return getPluginRunUserQuery({
return getPluginRunUserQuery({ nodes: app.modules, variables }); pluginInputs: getPluginInputsFromStoreNodes(app.modules),
variables,
files: variables.files
});
} }
const latestHumanChat = chatMessages.pop() as UserChatItemType | undefined; const latestHumanChat = chatMessages.pop() as UserChatItemType | undefined;

View File

@ -145,6 +145,7 @@ const DetailLogsModal = ({
{isPlugin ? ( {isPlugin ? (
<Box px={5} pt={2} h={'100%'}> <Box px={5} pt={2} h={'100%'}>
<PluginRunBox <PluginRunBox
chatConfig={chat?.app?.chatConfig}
pluginInputs={chat?.app.pluginInputs} pluginInputs={chat?.app.pluginInputs}
variablesForm={variablesForm} variablesForm={variablesForm}
histories={chatRecords} histories={chatRecords}

View File

@ -408,10 +408,11 @@ export const useWorkflow = () => {
/* node */ /* node */
const handleRemoveNode = useMemoizedFn((change: NodeRemoveChange, node: Node) => { const handleRemoveNode = useMemoizedFn((change: NodeRemoveChange, node: Node) => {
if (node.data.forbidDelete) { if (node.data.forbidDelete) {
return toast({ toast({
status: 'warning', status: 'warning',
title: t('common:core.workflow.Can not delete node') title: t('common:core.workflow.Can not delete node')
}); });
return false;
} }
// If the node has child nodes, remove the child nodes // If the node has child nodes, remove the child nodes
@ -438,6 +439,8 @@ export const useWorkflow = () => {
setEdges((state) => setEdges((state) =>
state.filter((edge) => edge.source !== change.id && edge.target !== change.id) state.filter((edge) => edge.source !== change.id && edge.target !== change.id)
); );
return true;
}); });
const handleSelectNode = useMemoizedFn((change: NodeSelectionChange) => { const handleSelectNode = useMemoizedFn((change: NodeSelectionChange) => {
// If the node is not selected and the Ctrl key is pressed, select the node // If the node is not selected and the Ctrl key is pressed, select the node
@ -506,8 +509,9 @@ export const useWorkflow = () => {
for (const change of changes) { for (const change of changes) {
if (change.type === 'remove') { if (change.type === 'remove') {
const node = nodes.find((n) => n.id === change.id); const node = nodes.find((n) => n.id === change.id);
if (node) { // 如果删除失败,则不继续执行
handleRemoveNode(change, node); if (node && !handleRemoveNode(change, node)) {
return;
} }
} else if (change.type === 'select') { } else if (change.type === 'select') {
handleSelectNode(change); handleSelectNode(change);

View File

@ -13,6 +13,11 @@ import { getAppChatConfig } from '@fastgpt/global/core/workflow/utils';
import { useCreation } from 'ahooks'; import { useCreation } from 'ahooks';
import ChatFunctionTip from '@/components/core/app/Tip'; import ChatFunctionTip from '@/components/core/app/Tip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
import { WorkflowContext } from '../../../context';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import FileSelect from '@/components/core/app/FileSelect';
import { userFilesInput } from '@fastgpt/global/core/workflow/template/system/workflowStart';
import MyIcon from '@fastgpt/web/components/common/Icon';
type ComponentProps = { type ComponentProps = {
chatConfig: AppChatConfigType; chatConfig: AppChatConfigType;
@ -60,6 +65,9 @@ const NodePluginConfig = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
> >
<Container w={'360px'}> <Container w={'360px'}>
<Instruction {...componentsProps} /> <Instruction {...componentsProps} />
<Box pt={4}>
<FileSelectConfig {...componentsProps} />
</Box>
</Container> </Container>
</NodeCard> </NodeCard>
); );
@ -72,6 +80,7 @@ function Instruction({ chatConfig: { instruction }, setAppDetail }: ComponentPro
return ( return (
<> <>
<Flex> <Flex>
<MyIcon name={'core/app/simpleMode/chat'} mr={2} w={'20px'} />
<FormLabel color={'myGray.600'} fontWeight={'medium'} fontSize={'14px'}> <FormLabel color={'myGray.600'} fontWeight={'medium'} fontSize={'14px'}>
{t('workflow:plugin.Instructions')} {t('workflow:plugin.Instructions')}
</FormLabel> </FormLabel>
@ -100,3 +109,48 @@ function Instruction({ chatConfig: { instruction }, setAppDetail }: ComponentPro
</> </>
); );
} }
function FileSelectConfig({ chatConfig: { fileSelectConfig }, setAppDetail }: ComponentProps) {
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
const nodes = useContextSelector(WorkflowContext, (v) => v.nodes);
const pluginInputNode = nodes.find((item) => item.type === FlowNodeTypeEnum.pluginInput)!;
return (
<FileSelect
value={fileSelectConfig}
color={'myGray.600'}
fontWeight={'medium'}
fontSize={'14px'}
onChange={(e) => {
setAppDetail((state) => ({
...state,
chatConfig: {
...state.chatConfig,
fileSelectConfig: e
}
}));
// Dynamic add or delete userFilesInput
const canUploadFiles = e.canSelectFile || e.canSelectImg;
const repeatKey = pluginInputNode?.data.outputs.find(
(item) => item.key === userFilesInput.key
);
if (canUploadFiles) {
!repeatKey &&
onChangeNode({
nodeId: pluginInputNode.id,
type: 'addOutput',
value: userFilesInput
});
} else {
repeatKey &&
onChangeNode({
nodeId: pluginInputNode.id,
type: 'delOutput',
key: userFilesInput.key
});
}
}}
/>
);
}

View File

@ -22,6 +22,7 @@ import { WorkflowContext } from '../../../context';
import IOTitle from '../../components/IOTitle'; import IOTitle from '../../components/IOTitle';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { defaultInput } from './InputEditModal'; import { defaultInput } from './InputEditModal';
import RenderOutput from '../render/RenderOutput';
const FieldEditModal = dynamic(() => import('./InputEditModal')); const FieldEditModal = dynamic(() => import('./InputEditModal'));
@ -140,9 +141,15 @@ const NodePluginInput = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
}} }}
/> />
</Container> </Container>
{!!outputs.length && (
<Container>
<IOTitle text={t('common:common.Output')} />
<RenderOutput nodeId={nodeId} flowOutputList={outputs} />
</Container>
)}
</NodeCard> </NodeCard>
); );
}, [data, inputs, nodeId, onChangeNode, selected, t]); }, [data, inputs, nodeId, onChangeNode, outputs, selected, t]);
return ( return (
<> <>

View File

@ -72,7 +72,7 @@ export const useChatTest = ({
const CustomChatContainer = useMemoizedFn(() => const CustomChatContainer = useMemoizedFn(() =>
appDetail.type === AppTypeEnum.plugin ? ( appDetail.type === AppTypeEnum.plugin ? (
<Box p={3}> <Box p={5}>
<PluginRunBox <PluginRunBox
pluginInputs={pluginInputs} pluginInputs={pluginInputs}
variablesForm={variablesForm} variablesForm={variablesForm}

View File

@ -17,7 +17,6 @@ import { useTranslation } from 'next-i18next';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants'; import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants'; import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
import AIModelSelector from '@/components/Select/AIModelSelector'; import AIModelSelector from '@/components/Select/AIModelSelector';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useSystem } from '@fastgpt/web/hooks/useSystem'; import { useSystem } from '@fastgpt/web/hooks/useSystem';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import ComplianceTip from '@/components/common/ComplianceTip/index'; import ComplianceTip from '@/components/common/ComplianceTip/index';

View File

@ -360,7 +360,7 @@ export const emptyTemplates: Record<
nodes: [ nodes: [
{ {
nodeId: 'pluginInput', nodeId: 'pluginInput',
name: i18nT('common:core.module.template.self_input'), name: i18nT('workflow:template.plugin_start'),
avatar: 'core/workflow/template/workflowStart', avatar: 'core/workflow/template/workflowStart',
flowNodeType: FlowNodeTypeEnum.pluginInput, flowNodeType: FlowNodeTypeEnum.pluginInput,
showStatus: false, showStatus: false,
@ -385,6 +385,20 @@ export const emptyTemplates: Record<
version: '481', version: '481',
inputs: [], inputs: [],
outputs: [] outputs: []
},
{
nodeId: 'pluginConfig',
name: i18nT('common:core.module.template.system_config'),
intro: '',
avatar: 'core/workflow/template/systemConfig',
flowNodeType: FlowNodeTypeEnum.pluginConfig,
position: {
x: 184.66337662472682,
y: -216.05298493910115
},
version: '4811',
inputs: [],
outputs: []
} }
], ],
edges: [] edges: []