V4.9.1 feature (#4206)

* fix: remove DefaultTeam (#4037)

* fix :Get application bound knowledge base information logical rewrite (#4057)

* fix :Get application bound knowledge base information logical rewrite

* fix :Get application bound knowledge base information logical rewrite

* fix :Get application bound knowledge base information logical rewrite

* fix :Get application bound knowledge base information logical rewrite

* update package

* fix: import dataset step error;perf: ai proxy avatar (#4074)

* perf: pg config params

* perf: ai proxy avatar

* fix: import dataset step error

* feat: data input ux

* perf: app dataset rewite

* fix: 文本提取不支持arrayString,arrayNumber等jsonSchema (#4079)

* update doc ;perf: model test (#4098)

* perf: extract array

* update doc

* perf: model test

* perf: model test

* perf: think tag parse (#4102)

* chat quote reader (#3912)

* init chat quote full text reader

* linked structure

* dataset data linked

* optimize code

* fix ts build

* test finish

* delete log

* fix

* fix ts

* fix ts

* remove nextId

* initial scroll

* fix

* fix

* perf: chunk read   (#4109)

* package

* perf: chunk read

* feat: api dataset support pdf parse;fix: chunk reader auth (#4117)

* feat: api dataset support pdf parse

* fix: chunk reader auth

* feat: invitation link (#3979)

* feat: invitation link schema and apis

* feat: add invitation link

* feat: member status: active, leave, forbidden

* fix: expires show hours and minutes

* feat: invalid invitation link hint

* fix: typo

* chore: fix typo & i18n

* fix

* pref: fe

* feat: add ttl index for 30-day-clean-up

* perf: invite member code (#4118)

* perf: invite member code

* fix: ts

* fix: model test channel id;fix: quote reader (#4123)

* fix: model test channel id

* fix: quote reader

* fix chat quote reader (#4125)

* perf: model test;perf: sidebar trigger (#4127)

* fix: import dataset step error;perf: ai proxy avatar (#4074)

* perf: pg config params

* perf: ai proxy avatar

* fix: import dataset step error

* feat: data input ux

* perf: app dataset rewite

* perf: model test

* perf: sidebar trigger

* lock

* update nanoid version

* fix: select component ux

* fix: ts

* fix: vitest

* remove test

* fix: prompt toolcall ui (#4139)

* load log error adapt

* fix: prompt toolcall ui

* perf: commercial function tip

* update package

* pref: copy link (#4147)

* fix(i18n): namespace (#4143)

* hiden dataset source (#4152)

* hiden dataset source

* perf: reader

* chore: move all tests into a single folder (#4160)

* fix modal close scroll (#4162)

* fix modal close scroll

* update refresh

* feat: rerank modal select and weight (#4164)

* fix loadInitData refresh (#4169)

* fix

* fix

* form input number default & api dataset max token

* feat: mix search weight (#4170)

* feat: mix search weight

* feat: svg render

* fix: avatar error remove (#4173)

* fix: avatar error remove

* fix: index

* fix: guide

* fix: auth

* update package;fix: input data model ui (#4181)

* update package

* fix: ts

* update config

* update jieba package

* add type sign

* fix: input data ui

* fix: page title refresh (#4186)

* fix: ts

* update jieba package

* fix: page title refresh

* fix: remove member length check when opening invite create modal (#4193)

* add env to check internal ip (#4187)

* fix: ts

* update jieba package

* add env to check internal ip

* package

* fix: jieba

* reset package

* update config

* fix: jieba package

* init shell

* init version

* change team reload

* update jieba package (#4200)

* update jieba package

* package

* update package

* remove invalid code

* action

* package (#4201)

* package

* update package

* remove invalid code

* package

* remove i18n tip (#4202)

* doc (#4205)

* fix: i18n (#4208)

* fix: next config (#4207)

* reset package

* i18n

* update config

* i18n

* remove log

---------

Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
Co-authored-by: gggaaallleee <91131304+gggaaallleee@users.noreply.github.com>
Co-authored-by: shilin <39396378+shilin66@users.noreply.github.com>
Co-authored-by: heheer <heheer@sealos.io>
This commit is contained in:
Archer
2025-03-18 14:40:41 +08:00
committed by GitHub
parent 56793114d8
commit e75d81d05a
316 changed files with 10626 additions and 8464 deletions

View File

@@ -0,0 +1,358 @@
{
"nodes": [
{
"nodeId": "userGuide",
"name": "common:core.module.template.system_config",
"intro": "common:core.module.template.system_config_info",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "userGuide",
"position": {
"x": 220.4077028616387,
"y": -429.3158723159836
},
"version": "481",
"inputs": [
{
"key": "welcomeText",
"renderTypeList": [
"hidden"
],
"valueType": "string",
"label": "core.app.Welcome Text",
"value": ""
},
{
"key": "variables",
"renderTypeList": [
"hidden"
],
"valueType": "any",
"label": "core.app.Chat Variable",
"value": []
},
{
"key": "questionGuide",
"valueType": "any",
"renderTypeList": [
"hidden"
],
"label": "core.app.Question Guide",
"value": {
"open": false
}
},
{
"key": "tts",
"renderTypeList": [
"hidden"
],
"valueType": "any",
"label": "",
"value": {
"type": "web"
}
},
{
"key": "whisper",
"renderTypeList": [
"hidden"
],
"valueType": "any",
"label": "",
"value": {
"open": false,
"autoSend": false,
"autoTTSResponse": false
}
},
{
"key": "scheduleTrigger",
"renderTypeList": [
"hidden"
],
"valueType": "any",
"label": "",
"value": null
}
],
"outputs": []
},
{
"nodeId": "448745",
"name": "common:core.module.template.work_start",
"intro": "",
"avatar": "core/workflow/template/workflowStart",
"flowNodeType": "workflowStart",
"position": {
"x": 773.4174945178407,
"y": -331.3158723159836
},
"version": "481",
"inputs": [
{
"key": "userChatInput",
"renderTypeList": [
"reference",
"textarea"
],
"valueType": "string",
"label": "common:core.module.input.label.user question",
"required": true,
"toolDescription": "用户问题",
"debugLabel": ""
}
],
"outputs": [
{
"id": "userChatInput",
"key": "userChatInput",
"label": "common:core.module.input.label.user question",
"type": "static",
"valueType": "string",
"description": ""
}
]
},
{
"nodeId": "nlv8iMRsvgkA",
"name": "批量执行",
"intro": "输入一个数组,遍历数组并将每一个数组元素作为输入元素,执行工作流。",
"avatar": "core/workflow/template/loop",
"flowNodeType": "loop",
"showStatus": true,
"position": {
"x": 1236,
"y": -593
},
"version": "4811",
"inputs": [
{
"key": "loopInputArray",
"renderTypeList": [
"reference"
],
"valueType": "arrayNumber",
"required": true,
"label": "数组",
"value": [
[
"VARIABLE_NODE_ID",
"list"
]
],
"valueDesc": "",
"description": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "childrenNodeIdList",
"renderTypeList": [
"hidden"
],
"valueType": "arrayString",
"label": "",
"value": [
"tRxC7faEoGuE",
"cGnptXbKAyMN"
]
},
{
"key": "nodeWidth",
"renderTypeList": [
"hidden"
],
"valueType": "number",
"label": "",
"value": 1246.6404923618281
},
{
"key": "nodeHeight",
"renderTypeList": [
"hidden"
],
"valueType": "number",
"label": "",
"value": 642.1566957382456
},
{
"key": "loopNodeInputHeight",
"renderTypeList": [
"hidden"
],
"valueType": "number",
"label": "",
"value": 83,
"valueDesc": "",
"description": "",
"debugLabel": "",
"toolDescription": ""
}
],
"outputs": [
{
"id": "loopArray",
"key": "loopArray",
"label": "数组执行结果",
"type": "static",
"valueType": "arrayAny",
"valueDesc": "",
"description": ""
}
]
},
{
"nodeId": "tRxC7faEoGuE",
"parentNodeId": "nlv8iMRsvgkA",
"name": "开始",
"avatar": "core/workflow/template/loopStart",
"flowNodeType": "loopStart",
"showStatus": false,
"position": {
"x": 1305.782937883576,
"y": -270.30845154767246
},
"version": "4811",
"inputs": [
{
"key": "loopStartInput",
"renderTypeList": [
"hidden"
],
"valueType": "any",
"label": "",
"required": true,
"value": ""
},
{
"key": "loopStartIndex",
"renderTypeList": [
"hidden"
],
"valueType": "number",
"label": "workflow:Array_element_index"
}
],
"outputs": [
{
"id": "loopStartIndex",
"key": "loopStartIndex",
"label": "workflow:Array_element_index",
"type": "static",
"valueType": "number"
},
{
"id": "loopStartInput",
"key": "loopStartInput",
"label": "数组元素",
"type": "static",
"valueType": "number"
}
]
},
{
"nodeId": "cGnptXbKAyMN",
"parentNodeId": "nlv8iMRsvgkA",
"name": "结束",
"avatar": "core/workflow/template/loopEnd",
"flowNodeType": "loopEnd",
"showStatus": false,
"position": {
"x": 1929.4234302454042,
"y": 135.8482441905731
},
"version": "4811",
"inputs": [
{
"key": "loopEndInput",
"renderTypeList": [
"reference"
],
"valueType": "any",
"label": "",
"required": true,
"value": []
}
],
"outputs": []
},
{
"nodeId": "zpOBWBxfyUap",
"parentNodeId": "nlv8iMRsvgkA",
"name": "指定回复",
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
"avatar": "core/workflow/template/reply",
"flowNodeType": "answerNode",
"position": {
"x": 1806.423430245404,
"y": -217.4185397094268
},
"version": "481",
"inputs": [
{
"key": "text",
"renderTypeList": [
"textarea",
"reference"
],
"valueType": "any",
"required": true,
"label": "回复的内容",
"description": "可以使用 \\n 来实现连续换行。\n可以通过外部模块输入实现回复外部模块输入时会覆盖当前填写的内容。\n如传入非字符串类型数据将会自动转成字符串",
"placeholder": "common:core.module.input.description.Response content",
"value": "{{$tRxC7faEoGuE.loopStartInput$}}",
"valueDesc": "",
"debugLabel": "",
"toolDescription": ""
}
],
"outputs": []
}
],
"edges": [
{
"source": "448745",
"target": "nlv8iMRsvgkA",
"sourceHandle": "448745-source-right",
"targetHandle": "nlv8iMRsvgkA-target-left"
},
{
"source": "tRxC7faEoGuE",
"target": "zpOBWBxfyUap",
"sourceHandle": "tRxC7faEoGuE-source-right",
"targetHandle": "zpOBWBxfyUap-target-left"
}
],
"chatConfig": {
"variables": [
{
"id": "04sm7m",
"key": "list",
"label": "list",
"type": "custom",
"description": "",
"required": false,
"valueType": "arrayNumber",
"list": [
{
"value": "",
"label": ""
}
],
"defaultValue": "[1,2,3]",
"enums": [
{
"value": "",
"label": ""
}
]
}
],
"_id": "67a8d281b54c01f7bd95c995",
"scheduledTriggerConfig": {
"cronString": "",
"timezone": "Asia/Shanghai",
"defaultPrompt": ""
}
}
}

View File

@@ -0,0 +1,319 @@
{
"nodes": [
{
"nodeId": "userGuide",
"name": "系统配置",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "userGuide",
"position": {
"x": 531.2422736065552,
"y": -486.7611729549753
},
"version": "481",
"inputs": [],
"outputs": []
},
{
"nodeId": "workflowStartNodeId",
"name": "流程开始",
"intro": "",
"avatar": "core/workflow/template/workflowStart",
"flowNodeType": "workflowStart",
"position": {
"x": 531.2422736065552,
"y": 244.69591764653183
},
"version": "481",
"inputs": [
{
"key": "userChatInput",
"renderTypeList": [
"reference",
"textarea"
],
"valueType": "string",
"label": "workflow:user_question",
"toolDescription": "用户问题",
"required": true,
"debugLabel": ""
}
],
"outputs": [
{
"id": "userChatInput",
"key": "userChatInput",
"label": "common:core.module.input.label.user question",
"type": "static",
"valueType": "string",
"description": ""
},
{
"id": "userFiles",
"key": "userFiles",
"label": "app:workflow.user_file_input",
"description": "app:workflow.user_file_input_desc",
"type": "static",
"valueType": "arrayString"
}
]
},
{
"nodeId": "7BdojPlukIQw",
"name": "AI 对话",
"intro": "AI 大模型对话",
"avatar": "core/workflow/template/aiChat",
"flowNodeType": "chatNode",
"showStatus": true,
"position": {
"x": 1106.3238387960757,
"y": -350.6030674683474
},
"version": "4813",
"inputs": [
{
"key": "model",
"renderTypeList": [
"settingLLMModel",
"reference"
],
"label": "",
"valueType": "string",
"value": "deepseek-reasoner",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "temperature",
"renderTypeList": [
"hidden"
],
"label": "",
"value": 0,
"valueType": "number",
"min": 0,
"max": 10,
"step": 1,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "maxToken",
"renderTypeList": [
"hidden"
],
"label": "",
"value": 8000,
"valueType": "number",
"min": 100,
"max": 4000,
"step": 50,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "isResponseAnswerText",
"renderTypeList": [
"hidden"
],
"label": "",
"value": true,
"valueType": "boolean",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "aiChatQuoteRole",
"renderTypeList": [
"hidden"
],
"label": "",
"valueType": "string",
"value": "system",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "quoteTemplate",
"renderTypeList": [
"hidden"
],
"label": "",
"valueType": "string",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "quotePrompt",
"renderTypeList": [
"hidden"
],
"label": "",
"valueType": "string",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "aiChatVision",
"renderTypeList": [
"hidden"
],
"label": "",
"valueType": "boolean",
"value": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "aiChatReasoning",
"renderTypeList": [
"hidden"
],
"label": "",
"valueType": "boolean",
"value": true,
"debugLabel": "",
"toolDescription": ""
},
{
"key": "systemPrompt",
"renderTypeList": [
"textarea",
"reference"
],
"max": 3000,
"valueType": "string",
"label": "core.ai.Prompt",
"description": "core.app.tip.systemPromptTip",
"placeholder": "core.app.tip.chatNodeSystemPromptTip",
"value": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "history",
"renderTypeList": [
"numberInput",
"reference"
],
"valueType": "chatHistory",
"label": "core.module.input.label.chat history",
"required": true,
"min": 0,
"max": 50,
"value": 6,
"description": "workflow:max_dialog_rounds",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "quoteQA",
"renderTypeList": [
"settingDatasetQuotePrompt"
],
"label": "",
"debugLabel": "知识库引用",
"description": "",
"valueType": "datasetQuote",
"toolDescription": ""
},
{
"key": "fileUrlList",
"renderTypeList": [
"reference",
"input"
],
"label": "app:file_quote_link",
"debugLabel": "文件链接",
"valueType": "arrayString",
"value": [
[
"workflowStartNodeId",
"userFiles"
]
],
"toolDescription": ""
},
{
"key": "userChatInput",
"renderTypeList": [
"reference",
"textarea"
],
"valueType": "string",
"label": "common:core.module.input.label.user question",
"required": true,
"toolDescription": "用户问题",
"value": [
"workflowStartNodeId",
"userChatInput"
],
"debugLabel": ""
}
],
"outputs": [
{
"id": "history",
"key": "history",
"required": true,
"label": "common:core.module.output.label.New context",
"description": "将本次回复内容拼接上历史记录,作为新的上下文返回",
"valueType": "chatHistory",
"valueDesc": "{\n obj: System | Human | AI;\n value: string;\n}[]",
"type": "static"
},
{
"id": "answerText",
"key": "answerText",
"required": true,
"label": "common:core.module.output.label.Ai response content",
"description": "将在 stream 回复完毕后触发",
"valueType": "string",
"type": "static"
}
]
}
],
"edges": [
{
"source": "workflowStartNodeId",
"target": "7BdojPlukIQw",
"sourceHandle": "workflowStartNodeId-source-right",
"targetHandle": "7BdojPlukIQw-target-left"
}
],
"chatConfig": {
"questionGuide": false,
"ttsConfig": {
"type": "web"
},
"whisperConfig": {
"open": false,
"autoSend": false,
"autoTTSResponse": false
},
"scheduledTriggerConfig": {
"cronString": "",
"timezone": "Asia/Shanghai",
"defaultPrompt": ""
},
"chatInputGuide": {
"open": false,
"textList": [],
"customUrl": ""
},
"instruction": "",
"autoExecute": {
"open": false,
"defaultPrompt": ""
},
"welcomeText": "",
"variables": [],
"fileSelectConfig": {
"canSelectFile": false,
"canSelectImg": false,
"maxFiles": 10
},
"_id": "66f4c2f5e9e4e93a95141004"
}
}

View File

@@ -0,0 +1,82 @@
import { readFileSync } from 'fs';
import { resolve } from 'path';
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { dispatchWorkFlow } from '@fastgpt/service/core/workflow/dispatch';
import {
getWorkflowEntryNodeIds,
storeNodes2RuntimeNodes
} from '@fastgpt/global/core/workflow/runtime/utils';
import { ChatItemValueTypeEnum } from '@fastgpt/global/core/chat/constants';
vi.mock(import('@fastgpt/service/common/string/tiktoken'), async (importOriginal) => {
const mod = await importOriginal();
return {
...mod,
countGptMessagesTokens: async () => {
return 1;
}
};
});
vi.mock(import('@fastgpt/service/support/wallet/usage/utils'), async (importOriginal) => {
const mod = await importOriginal();
return {
...mod,
formatModelChars2Points: () => ({
modelName: 'test',
totalPoints: 1
})
};
});
const testWorkflow = async (path: string) => {
const workflowStr = readFileSync(resolve(path), 'utf-8');
const workflow = JSON.parse(workflowStr);
const { nodes, edges, chatConfig } = workflow;
let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes));
const variables = {};
const { assistantResponses, flowResponses } = await dispatchWorkFlow({
mode: 'test',
runningAppInfo: {
id: 'test',
teamId: 'test',
tmbId: 'test'
},
runningUserInfo: {
tmbId: 'test',
teamId: 'test'
},
timezone: 'Asia/Shanghai',
externalProvider: {},
uid: 'test',
runtimeNodes,
runtimeEdges: edges,
variables,
query: [
{
type: ChatItemValueTypeEnum.text,
text: {
content: '你是谁'
}
}
],
chatConfig,
histories: [],
stream: false,
maxRunTimes: 5
});
expect(assistantResponses).toBeDefined();
expect(assistantResponses[0].text?.content).toBeDefined();
return {
assistantResponses,
flowResponses
};
};
it('Workflow test: simple workflow', async () => {
// create a simple app
await testWorkflow('test/cases/workflow/simple.json');
});
it('Workflow test: output test', async () => {
console.log(await testWorkflow('test/cases/workflow/loopTest.json'));
});