File input (#2270)

* doc

* feat: file upload  config

* perf: chat box file params

* feat: markdown show file

* feat: chat file store and clear

* perf: read file contentType

* feat: llm vision config

* feat: file url output

* perf: plugin error text

* perf: image load

* feat: ai chat document

* perf: file block ui

* feat: read file node

* feat: file read response field

* feat: simple mode support read files

* feat: tool call

* feat: read file histories

* perf: select file

* perf: select file config

* i18n

* i18n

* fix: ts; feat: tool response preview result
This commit is contained in:
Archer
2024-08-06 10:00:22 +08:00
committed by GitHub
parent 10dcdb5491
commit e36d9d794f
121 changed files with 2600 additions and 1142 deletions

View File

@@ -9,7 +9,10 @@ export const postUploadFiles = (
data: FormData,
onUploadProgress: (progressEvent: AxiosProgressEvent) => void
) =>
POST<string>('/common/file/upload', data, {
POST<{
fileId: string;
previewUrl: string;
}>('/common/file/upload', data, {
timeout: 600000,
onUploadProgress,
headers: {

View File

@@ -7,7 +7,6 @@ import {
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node.d';
import {
FlowNodeInputTypeEnum,
FlowNodeOutputTypeEnum,
FlowNodeTypeEnum
} from '@fastgpt/global/core/workflow/node/constant';
import { NodeInputKeyEnum, WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
@@ -18,32 +17,45 @@ import { EditorVariablePickerType } from '@fastgpt/web/components/common/Textare
import { TFunction } from 'next-i18next';
import { ToolModule } from '@fastgpt/global/core/workflow/template/system/tools';
import { useDatasetStore } from '../dataset/store/dataset';
import {
WorkflowStart,
userFilesInput
} from '@fastgpt/global/core/workflow/template/system/workflowStart';
import { SystemConfigNode } from '@fastgpt/global/core/workflow/template/system/systemConfig';
import { AiChatModule } from '@fastgpt/global/core/workflow/template/system/aiChat';
import { DatasetSearchModule } from '@fastgpt/global/core/workflow/template/system/datasetSearch';
import { ReadFilesNodes } from '@fastgpt/global/core/workflow/template/system/readFiles';
type WorkflowType = {
nodes: StoreNodeItemType[];
edges: StoreEdgeItemType[];
};
export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType & {
export function form2AppWorkflow(
data: AppSimpleEditFormType,
t: any // i18nT
): WorkflowType & {
chatConfig: AppChatConfigType;
} {
const workflowStartNodeId = 'workflowStartNodeId';
const datasetNodeId = 'iKBoX2vIzETU';
const aiChatNodeId = '7BdojPlukIQw';
const allDatasets = useDatasetStore.getState().allDatasets;
const selectedDatasets = data.dataset.datasets.filter((item) =>
allDatasets.some((ds) => ds._id === item.datasetId)
);
function systemConfigTemplate(formData: AppSimpleEditFormType): StoreNodeItemType {
function systemConfigTemplate(): StoreNodeItemType {
return {
nodeId: 'userGuide',
name: '系统配置',
intro: '可以配置应用的系统参数',
flowNodeType: FlowNodeTypeEnum.systemConfig,
nodeId: SystemConfigNode.id,
name: t(SystemConfigNode.name),
intro: '',
flowNodeType: SystemConfigNode.flowNodeType,
position: {
x: 531.2422736065552,
y: -486.7611729549753
},
version: '481',
version: SystemConfigNode.version,
inputs: [],
outputs: []
};
@@ -51,509 +63,259 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType & {
function workflowStartTemplate(): StoreNodeItemType {
return {
nodeId: workflowStartNodeId,
name: '流程开始',
name: t(WorkflowStart.name),
intro: '',
avatar: '/imgs/workflow/userChatInput.svg',
flowNodeType: FlowNodeTypeEnum.workflowStart,
avatar: WorkflowStart.avatar,
flowNodeType: WorkflowStart.flowNodeType,
position: {
x: 558.4082376415505,
y: 123.72387429194112
},
version: '481',
version: WorkflowStart.version,
inputs: WorkflowStart.inputs,
outputs: [...WorkflowStart.outputs, userFilesInput]
};
}
function aiChatTemplate(formData: AppSimpleEditFormType): StoreNodeItemType {
return {
nodeId: aiChatNodeId,
name: t(AiChatModule.name),
intro: t(AiChatModule.intro),
avatar: AiChatModule.avatar,
flowNodeType: AiChatModule.flowNodeType,
showStatus: true,
position: {
x: 1106.3238387960757,
y: -350.6030674683474
},
version: AiChatModule.version,
inputs: [
{
key: 'model',
renderTypeList: [FlowNodeInputTypeEnum.settingLLMModel, FlowNodeInputTypeEnum.reference],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.aiSettings.model
},
{
key: 'temperature',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: formData.aiSettings.temperature,
valueType: WorkflowIOValueTypeEnum.number,
min: 0,
max: 10,
step: 1
},
{
key: 'maxToken',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: formData.aiSettings.maxToken,
valueType: WorkflowIOValueTypeEnum.number,
min: 100,
max: 4000,
step: 50
},
{
key: 'isResponseAnswerText',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: true,
valueType: WorkflowIOValueTypeEnum.boolean
},
{
key: 'quoteTemplate',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string
},
{
key: 'quotePrompt',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string
},
{
key: 'systemPrompt',
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
max: 3000,
valueType: WorkflowIOValueTypeEnum.string,
label: 'core.ai.Prompt',
description: 'core.app.tip.chatNodeSystemPromptTip',
placeholder: 'core.app.tip.chatNodeSystemPromptTip',
value: formData.aiSettings.systemPrompt
},
{
key: 'history',
renderTypeList: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.chatHistory,
label: 'core.module.input.label.chat history',
required: true,
min: 0,
max: 30,
value: formData.aiSettings.maxHistories
},
{
key: 'userChatInput',
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea],
valueType: WorkflowIOValueTypeEnum.string,
label: '用户问题',
required: true,
toolDescription: '用户问题'
toolDescription: '用户问题',
value: [workflowStartNodeId, 'userChatInput']
},
{
key: 'quoteQA',
renderTypeList: [FlowNodeInputTypeEnum.settingDatasetQuotePrompt],
label: '',
debugLabel: '知识库引用',
description: '',
valueType: WorkflowIOValueTypeEnum.datasetQuote,
value: selectedDatasets ? [datasetNodeId, 'quoteQA'] : undefined
},
{
key: NodeInputKeyEnum.aiChatVision,
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: true
}
],
outputs: [
outputs: AiChatModule.outputs
};
}
function datasetNodeTemplate(formData: AppSimpleEditFormType, question: any): StoreNodeItemType {
return {
nodeId: datasetNodeId,
name: t(DatasetSearchModule.name),
intro: t(DatasetSearchModule.intro),
avatar: DatasetSearchModule.avatar,
flowNodeType: DatasetSearchModule.flowNodeType,
showStatus: true,
position: {
x: 918.5901682164496,
y: -227.11542247619582
},
version: '481',
inputs: [
{
id: 'userChatInput',
key: 'userChatInput',
label: 'core.module.input.label.user question',
key: 'datasets',
renderTypeList: [FlowNodeInputTypeEnum.selectDataset, FlowNodeInputTypeEnum.reference],
label: 'core.module.input.label.Select dataset',
value: selectedDatasets,
valueType: WorkflowIOValueTypeEnum.selectDataset,
list: [],
required: true
},
{
key: 'similarity',
renderTypeList: [FlowNodeInputTypeEnum.selectDatasetParamsModal],
label: '',
value: formData.dataset.similarity,
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'limit',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: formData.dataset.limit,
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'searchMode',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
type: FlowNodeOutputTypeEnum.static
value: formData.dataset.searchMode
},
{
key: 'usingReRank',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: formData.dataset.usingReRank
},
{
key: 'datasetSearchUsingExtensionQuery',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: formData.dataset.datasetSearchUsingExtensionQuery
},
{
key: 'datasetSearchExtensionModel',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.dataset.datasetSearchExtensionModel
},
{
key: 'datasetSearchExtensionBg',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.dataset.datasetSearchExtensionBg
},
{
key: 'userChatInput',
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea],
valueType: WorkflowIOValueTypeEnum.string,
label: '用户问题',
required: true,
toolDescription: '需要检索的内容',
value: question
}
]
],
outputs: DatasetSearchModule.outputs
};
}
// Start, AiChat
function simpleChatTemplate(formData: AppSimpleEditFormType): WorkflowType {
return {
nodes: [
{
nodeId: '7BdojPlukIQw',
name: 'AI 对话',
intro: 'AI 大模型对话',
avatar: '/imgs/workflow/AI.png',
flowNodeType: FlowNodeTypeEnum.chatNode,
showStatus: true,
position: {
x: 1106.3238387960757,
y: -350.6030674683474
},
version: '481',
inputs: [
{
key: 'model',
renderTypeList: [
FlowNodeInputTypeEnum.settingLLMModel,
FlowNodeInputTypeEnum.reference
],
label: 'core.module.input.label.aiModel',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.aiSettings.model
},
{
key: 'temperature',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: formData.aiSettings.temperature,
valueType: WorkflowIOValueTypeEnum.number,
min: 0,
max: 10,
step: 1
},
{
key: 'maxToken',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: formData.aiSettings.maxToken,
valueType: WorkflowIOValueTypeEnum.number,
min: 100,
max: 4000,
step: 50
},
{
key: 'isResponseAnswerText',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: true,
valueType: WorkflowIOValueTypeEnum.boolean
},
{
key: 'quoteTemplate',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string
},
{
key: 'quotePrompt',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string
},
{
key: 'systemPrompt',
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
max: 3000,
valueType: WorkflowIOValueTypeEnum.string,
label: 'core.ai.Prompt',
description: 'core.app.tip.chatNodeSystemPromptTip',
placeholder: 'core.app.tip.chatNodeSystemPromptTip',
value: formData.aiSettings.systemPrompt
},
{
key: 'history',
renderTypeList: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.chatHistory,
label: 'core.module.input.label.chat history',
required: true,
min: 0,
max: 30,
value: formData.aiSettings.maxHistories
},
{
key: 'userChatInput',
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea],
valueType: WorkflowIOValueTypeEnum.string,
label: '用户问题',
required: true,
toolDescription: '用户问题',
value: [workflowStartNodeId, 'userChatInput']
},
{
key: 'quoteQA',
renderTypeList: [FlowNodeInputTypeEnum.settingDatasetQuotePrompt],
label: '',
debugLabel: '知识库引用',
description: '',
valueType: WorkflowIOValueTypeEnum.datasetQuote
}
],
outputs: [
{
id: 'history',
key: 'history',
label: 'core.module.output.label.New context',
description: 'core.module.output.description.New context',
valueType: WorkflowIOValueTypeEnum.chatHistory,
type: FlowNodeOutputTypeEnum.static
},
{
id: 'answerText',
key: 'answerText',
label: 'core.module.output.label.Ai response content',
description: 'core.module.output.description.Ai response content',
valueType: WorkflowIOValueTypeEnum.string,
type: FlowNodeOutputTypeEnum.static
}
]
}
],
nodes: [aiChatTemplate(formData)],
edges: [
{
source: workflowStartNodeId,
target: '7BdojPlukIQw',
target: aiChatNodeId,
sourceHandle: `${workflowStartNodeId}-source-right`,
targetHandle: '7BdojPlukIQw-target-left'
targetHandle: `${aiChatNodeId}-target-left`
}
]
};
}
// Start, Dataset search, AiChat
function datasetTemplate(formData: AppSimpleEditFormType): WorkflowType {
return {
nodes: [
{
nodeId: '7BdojPlukIQw',
name: 'AI 对话',
intro: 'AI 大模型对话',
avatar: '/imgs/workflow/AI.png',
flowNodeType: FlowNodeTypeEnum.chatNode,
showStatus: true,
position: {
x: 1638.509551404687,
y: -341.0428450861567
},
version: '481', // [FlowNodeTypeEnum.chatNode]
inputs: [
{
key: 'model',
renderTypeList: [
FlowNodeInputTypeEnum.settingLLMModel,
FlowNodeInputTypeEnum.reference
],
label: 'core.module.input.label.aiModel',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.aiSettings.model
},
{
key: 'temperature',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: formData.aiSettings.temperature,
valueType: WorkflowIOValueTypeEnum.number,
min: 0,
max: 10,
step: 1
},
{
key: 'maxToken',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: formData.aiSettings.maxToken,
valueType: WorkflowIOValueTypeEnum.number,
min: 100,
max: 4000,
step: 50
},
{
key: 'isResponseAnswerText',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: true,
valueType: WorkflowIOValueTypeEnum.boolean
},
{
key: 'quoteTemplate',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string
},
{
key: 'quotePrompt',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string
},
{
key: 'systemPrompt',
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
max: 3000,
valueType: WorkflowIOValueTypeEnum.string,
label: 'core.ai.Prompt',
description: 'core.app.tip.chatNodeSystemPromptTip',
placeholder: 'core.app.tip.chatNodeSystemPromptTip',
value: formData.aiSettings.systemPrompt
},
{
key: 'history',
renderTypeList: [FlowNodeInputTypeEnum.numberInput, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.chatHistory,
label: 'core.module.input.label.chat history',
required: true,
min: 0,
max: 30,
value: formData.aiSettings.maxHistories
},
{
key: 'userChatInput',
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea],
valueType: WorkflowIOValueTypeEnum.string,
label: '用户问题',
required: true,
toolDescription: '用户问题',
value: [workflowStartNodeId, 'userChatInput']
},
{
key: 'quoteQA',
renderTypeList: [FlowNodeInputTypeEnum.settingDatasetQuotePrompt],
label: '',
debugLabel: '知识库引用',
description: '',
valueType: WorkflowIOValueTypeEnum.datasetQuote,
value: ['iKBoX2vIzETU', 'quoteQA']
}
],
outputs: [
{
id: 'history',
key: 'history',
label: 'core.module.output.label.New context',
description: 'core.module.output.description.New context',
valueType: WorkflowIOValueTypeEnum.chatHistory,
type: FlowNodeOutputTypeEnum.static
},
{
id: 'answerText',
key: 'answerText',
label: 'core.module.output.label.Ai response content',
description: 'core.module.output.description.Ai response content',
valueType: WorkflowIOValueTypeEnum.string,
type: FlowNodeOutputTypeEnum.static
}
]
},
{
nodeId: 'iKBoX2vIzETU',
name: '知识库搜索',
intro: '调用“语义检索”和“全文检索”能力,从“知识库”中查找可能与问题相关的参考内容',
avatar: '/imgs/workflow/db.png',
flowNodeType: FlowNodeTypeEnum.datasetSearchNode,
showStatus: true,
position: {
x: 918.5901682164496,
y: -227.11542247619582
},
version: '481',
inputs: [
{
key: 'datasets',
renderTypeList: [
FlowNodeInputTypeEnum.selectDataset,
FlowNodeInputTypeEnum.reference
],
label: 'core.module.input.label.Select dataset',
value: selectedDatasets,
valueType: WorkflowIOValueTypeEnum.selectDataset,
list: [],
required: true
},
{
key: 'similarity',
renderTypeList: [FlowNodeInputTypeEnum.selectDatasetParamsModal],
label: '',
value: formData.dataset.similarity,
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'limit',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: formData.dataset.limit,
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'searchMode',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.dataset.searchMode
},
{
key: 'usingReRank',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: formData.dataset.usingReRank
},
{
key: 'datasetSearchUsingExtensionQuery',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: formData.dataset.datasetSearchUsingExtensionQuery
},
{
key: 'datasetSearchExtensionModel',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.dataset.datasetSearchExtensionModel
},
{
key: 'datasetSearchExtensionBg',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.dataset.datasetSearchExtensionBg
},
{
key: 'userChatInput',
renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.textarea],
valueType: WorkflowIOValueTypeEnum.string,
label: '用户问题',
required: true,
toolDescription: '需要检索的内容',
value: [workflowStartNodeId, 'userChatInput']
}
],
outputs: [
{
id: 'quoteQA',
key: 'quoteQA',
label: 'core.module.Dataset quote.label',
type: FlowNodeOutputTypeEnum.static,
valueType: WorkflowIOValueTypeEnum.datasetQuote
}
]
}
aiChatTemplate(formData),
datasetNodeTemplate(formData, [workflowStartNodeId, 'userChatInput'])
],
edges: [
{
source: workflowStartNodeId,
target: 'iKBoX2vIzETU',
target: datasetNodeId,
sourceHandle: `${workflowStartNodeId}-source-right`,
targetHandle: 'iKBoX2vIzETU-target-left'
targetHandle: `${datasetNodeId}-target-left`
},
{
source: 'iKBoX2vIzETU',
target: '7BdojPlukIQw',
sourceHandle: 'iKBoX2vIzETU-source-right',
targetHandle: '7BdojPlukIQw-target-left'
source: datasetNodeId,
target: aiChatNodeId,
sourceHandle: `${datasetNodeId}-source-right`,
targetHandle: `${aiChatNodeId}-target-left`
}
]
};
}
function toolTemplates(formData: AppSimpleEditFormType): WorkflowType {
const toolNodeId = getNanoid(6);
const datasetNodeId = getNanoid(6);
// Dataset tool config
const datasetTool: WorkflowType | null =
selectedDatasets.length > 0
? {
nodes: [
{
nodeId: datasetNodeId,
name: '知识库搜索',
intro: '调用“语义检索”和“全文检索”能力,从“知识库”中查找可能与问题相关的参考内容',
avatar: '/imgs/workflow/db.png',
flowNodeType: FlowNodeTypeEnum.datasetSearchNode,
showStatus: true,
position: {
x: 500,
y: 545
},
version: '481',
inputs: [
{
key: 'datasets',
renderTypeList: [
FlowNodeInputTypeEnum.selectDataset,
FlowNodeInputTypeEnum.reference
],
label: 'core.module.input.label.Select dataset',
value: selectedDatasets,
valueType: WorkflowIOValueTypeEnum.selectDataset,
list: [],
required: true
},
{
key: 'similarity',
renderTypeList: [FlowNodeInputTypeEnum.selectDatasetParamsModal],
label: '',
value: formData.dataset.similarity,
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'limit',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: formData.dataset.limit,
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'searchMode',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.dataset.searchMode
},
{
key: 'usingReRank',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: formData.dataset.usingReRank
},
{
key: 'datasetSearchUsingExtensionQuery',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: formData.dataset.datasetSearchUsingExtensionQuery
},
{
key: 'datasetSearchExtensionModel',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.dataset.datasetSearchExtensionModel
},
{
key: 'datasetSearchExtensionBg',
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.string,
value: formData.dataset.datasetSearchExtensionBg
},
{
key: 'userChatInput',
renderTypeList: [
FlowNodeInputTypeEnum.reference,
FlowNodeInputTypeEnum.textarea
],
valueType: WorkflowIOValueTypeEnum.string,
label: '用户问题',
required: true,
toolDescription: '需要检索的内容'
}
],
outputs: [
{
id: 'quoteQA',
key: 'quoteQA',
label: 'core.module.Dataset quote.label',
type: FlowNodeOutputTypeEnum.static,
valueType: WorkflowIOValueTypeEnum.datasetQuote
}
]
}
],
nodes: [datasetNodeTemplate(formData, '')],
edges: [
{
source: toolNodeId,
@@ -564,7 +326,46 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType & {
]
}
: null;
// Read file tool config
const readFileTool: WorkflowType | null = data.chatConfig.fileSelectConfig?.canSelectFile
? {
nodes: [
{
nodeId: ReadFilesNodes.id,
name: t(ReadFilesNodes.name),
intro: t(ReadFilesNodes.intro),
avatar: ReadFilesNodes.avatar,
flowNodeType: ReadFilesNodes.flowNodeType,
showStatus: true,
position: {
x: 974.6209854328943,
y: 587.6378828744465
},
version: '489',
inputs: [
{
key: NodeInputKeyEnum.fileUrlList,
renderTypeList: [FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.arrayString,
label: t('app:workflow.file_url'),
value: [workflowStartNodeId, 'userFiles']
}
],
outputs: ReadFilesNodes.outputs
}
],
edges: [
{
source: toolNodeId,
target: ReadFilesNodes.id,
sourceHandle: 'selectedTools',
targetHandle: 'selectedTools'
}
]
}
: null;
// Computed tools config
const pluginTool: WorkflowType[] = formData.selectedTools.map((tool, i) => {
const nodeId = getNanoid(6);
return {
@@ -602,16 +403,16 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType & {
nodes: [
{
nodeId: toolNodeId,
name: '工具调用',
intro: '通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。',
avatar: '/imgs/workflow/tool.svg',
flowNodeType: FlowNodeTypeEnum.tools,
name: ToolModule.name,
intro: ToolModule.intro,
avatar: ToolModule.avatar,
flowNodeType: ToolModule.flowNodeType,
showStatus: true,
position: {
x: 1062.1738942532802,
y: -223.65033022650476
},
version: '481',
version: ToolModule.version,
inputs: [
{
key: 'model',
@@ -671,12 +472,20 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType & {
label: '用户问题',
required: true,
value: [workflowStartNodeId, 'userChatInput']
},
{
key: NodeInputKeyEnum.aiChatVision,
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: true
}
],
outputs: ToolModule.outputs
},
// tool nodes
...(datasetTool ? datasetTool.nodes : []),
...(readFileTool ? readFileTool.nodes : []),
...pluginTool.map((tool) => tool.nodes).flat()
],
edges: [
@@ -688,6 +497,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType & {
},
// tool edges
...(datasetTool ? datasetTool.edges : []),
...(readFileTool ? readFileTool.edges : []),
...pluginTool.map((tool) => tool.edges).flat()
]
};
@@ -696,13 +506,14 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType & {
}
const workflow = (() => {
if (data.selectedTools.length > 0) return toolTemplates(data);
if (data.selectedTools.length > 0 || data.chatConfig.fileSelectConfig?.canSelectFile)
return toolTemplates(data);
if (selectedDatasets.length > 0) return datasetTemplate(data);
return simpleChatTemplate(data);
})();
return {
nodes: [systemConfigTemplate(data), workflowStartTemplate(), ...workflow.nodes],
nodes: [systemConfigTemplate(), workflowStartTemplate(), ...workflow.nodes],
edges: workflow.edges,
chatConfig: data.chatConfig
};

View File

@@ -450,7 +450,8 @@ export const compareWorkflow = (workflow1: WorkflowType, workflow2: WorkflowType
ttsConfig: clone1.chatConfig?.ttsConfig || undefined,
whisperConfig: clone1.chatConfig?.whisperConfig || undefined,
scheduledTriggerConfig: clone1.chatConfig?.scheduledTriggerConfig || undefined,
chatInputGuide: clone1.chatConfig?.chatInputGuide || undefined
chatInputGuide: clone1.chatConfig?.chatInputGuide || undefined,
fileSelectConfig: clone1.chatConfig?.fileSelectConfig || undefined
},
{
welcomeText: clone2.chatConfig?.welcomeText || '',
@@ -459,7 +460,8 @@ export const compareWorkflow = (workflow1: WorkflowType, workflow2: WorkflowType
ttsConfig: clone2.chatConfig?.ttsConfig || undefined,
whisperConfig: clone2.chatConfig?.whisperConfig || undefined,
scheduledTriggerConfig: clone2.chatConfig?.scheduledTriggerConfig || undefined,
chatInputGuide: clone2.chatConfig?.chatInputGuide || undefined
chatInputGuide: clone2.chatConfig?.chatInputGuide || undefined,
fileSelectConfig: clone2.chatConfig?.fileSelectConfig || undefined
}
)
) {