From ae95a8908ea0ef7f33929cb3f497bfcf6add54a2 Mon Sep 17 00:00:00 2001 From: archer <545436317@qq.com> Date: Tue, 1 Aug 2023 21:51:54 +0800 Subject: [PATCH] fix: savechat.feat: extract flow --- client/src/components/MyTooltip/index.tsx | 3 +- client/src/constants/flow/ModuleTemplate.ts | 325 ++++++++++++------ client/src/constants/flow/index.ts | 4 +- client/src/constants/flow/inputTemplate.ts | 2 +- .../pages/api/openapi/v1/chat/completions.ts | 2 +- .../AdEdit/components/Nodes/NodeAnswer.tsx | 3 +- .../AdEdit/components/Nodes/NodeCQNode.tsx | 2 +- .../AdEdit/components/Nodes/NodeExtract.tsx | 101 ++++-- .../AdEdit/components/render/RenderInput.tsx | 2 +- .../AdEdit/components/render/RenderOutput.tsx | 6 +- .../AdEdit/components/render/SourceHandle.tsx | 4 +- .../AdEdit/components/render/TargetHandle.tsx | 2 +- .../app/detail/components/AdEdit/index.tsx | 9 +- .../service/moduleDispatch/agent/extract.ts | 3 +- client/src/service/utils/chat/saveChat.ts | 2 +- client/src/types/app.d.ts | 3 +- client/src/types/flow.d.ts | 4 +- client/src/utils/adapt.ts | 15 +- 18 files changed, 334 insertions(+), 158 deletions(-) diff --git a/client/src/components/MyTooltip/index.tsx b/client/src/components/MyTooltip/index.tsx index 9dc0f39460..8dc85d07a2 100644 --- a/client/src/components/MyTooltip/index.tsx +++ b/client/src/components/MyTooltip/index.tsx @@ -6,7 +6,7 @@ interface Props extends TooltipProps { forceShow?: boolean; } -const MyTooltip = ({ children, forceShow = false, ...props }: Props) => { +const MyTooltip = ({ children, forceShow = false, shouldWrapChildren = true, ...props }: Props) => { const { isPc } = useGlobalStore(); return isPc || forceShow ? ( { borderRadius={'8px'} whiteSpace={'pre-wrap'} boxShadow={'1px 1px 10px rgba(0,0,0,0.2)'} + shouldWrapChildren={shouldWrapChildren} {...props} > {children} diff --git a/client/src/constants/flow/ModuleTemplate.ts b/client/src/constants/flow/ModuleTemplate.ts index 7b993f05dc..0c4ff410e0 100644 --- a/client/src/constants/flow/ModuleTemplate.ts +++ b/client/src/constants/flow/ModuleTemplate.ts @@ -109,7 +109,6 @@ export const HistoryModule: FlowModuleTemplateType = { ] }; -const defaultModel = chatModelList[0]; export const ChatModule: FlowModuleTemplateType = { logo: '/imgs/module/AI.png', name: 'AI 对话', @@ -120,7 +119,7 @@ export const ChatModule: FlowModuleTemplateType = { key: 'model', type: FlowInputItemTypeEnum.custom, label: '对话模型', - value: defaultModel?.model, + value: chatModelList[0]?.model, list: chatModelList.map((item) => ({ label: item.name, value: item.model })) }, { @@ -140,15 +139,15 @@ export const ChatModule: FlowModuleTemplateType = { key: 'maxToken', type: FlowInputItemTypeEnum.custom, label: '回复上限', - value: defaultModel ? defaultModel.contextMaxToken / 2 : 2000, + value: chatModelList[0] ? chatModelList[0].contextMaxToken / 2 : 2000, min: 100, - max: defaultModel?.contextMaxToken || 4000, + max: chatModelList[0]?.contextMaxToken || 4000, step: 50, markList: [ { label: '100', value: 100 }, { - label: `${defaultModel?.contextMaxToken || 4000}`, - value: defaultModel?.contextMaxToken || 4000 + label: `${chatModelList[0]?.contextMaxToken || 4000}`, + value: chatModelList[0]?.contextMaxToken || 4000 } ] }, @@ -280,8 +279,10 @@ export const AnswerModule: FlowModuleTemplateType = { key: SpecialInputKeyEnum.answerText, value: '', type: FlowInputItemTypeEnum.textarea, + valueType: FlowValueTypeEnum.string, label: '回复的内容', - description: '可以使用 \\n 来实现换行' + description: + '可以使用 \\n 来实现换行。也可以通过外部模块输入实现回复,外部模块输入时会覆盖当前填写的内容' } ], outputs: [] @@ -407,13 +408,8 @@ export const ContextExtractModule: FlowModuleTemplateType = { description: "由 '描述' 和 'key' 组成一个目标字段,可提取多个目标字段", value: [ { - key: 'a', - desc: '描述', - required: true - }, - { - key: 'n', - desc: '描述', + key: 'key', + desc: '目标字段', required: true } ] @@ -436,9 +432,16 @@ export const ContextExtractModule: FlowModuleTemplateType = { }, { key: ContextExtractEnum.fields, - label: '提取结果', + label: '完整提取结果', description: '一个 JSON 对象,例如 {"name:":"YY","Time":"2023/7/2 18:00"}', - valueType: FlowValueTypeEnum.other, + valueType: FlowValueTypeEnum.any, + type: FlowOutputItemTypeEnum.source, + targets: [] + }, + { + key: 'key', + label: '提取结果-目标字段', + valueType: FlowValueTypeEnum.string, type: FlowOutputItemTypeEnum.source, targets: [] } @@ -502,6 +505,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'userChatInput', + label: '用户问题', + type: 'source', + valueType: 'string', targets: [ { moduleId: 'chatModule', @@ -521,7 +527,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = inputs: [ { key: 'maxContext', - value: 10, + value: 6, connected: true }, { @@ -532,6 +538,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'history', + label: '聊天记录', + valueType: 'chat_history', + type: 'source', targets: [ { moduleId: 'chatModule', @@ -544,14 +553,14 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = { moduleId: 'chatModule', position: { - x: 981.9682828103937, - y: 890.014595014464 + x: 998.0312473867093, + y: 803.8586941051353 }, flowType: 'chatNode', inputs: [ { key: 'model', - value: 'gpt-3.5-turbo-16k', + value: 'gpt-3.5-turbo', connected: true }, { @@ -561,7 +570,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = }, { key: 'maxToken', - value: 8000, + value: 2000, connected: true }, { @@ -594,6 +603,17 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'answerText', + label: '模型回复', + description: '直接响应,无需配置', + type: 'hidden', + targets: [] + }, + { + key: 'finish', + label: '回复结束', + description: 'AI 回复完成后触发', + valueType: 'boolean', + type: 'source', targets: [] } ] @@ -616,8 +636,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = inputs: [ { key: 'welcomeText', - value: - '我是 laf 助手,请问有什么可以帮助你的么?\n[laf 是什么?]\n[laf 官网是多少?]\n[交流群]', + value: '你好,我是 laf 助手,有什么可以帮助你的么?', connected: true } ], @@ -639,6 +658,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'userChatInput', + label: '用户问题', + type: 'source', + valueType: 'string', targets: [ { moduleId: 'chatModule', @@ -655,14 +677,14 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = { moduleId: 'history', position: { - x: 458.37518916304566, - y: 1296.7930057645262 + x: 452.5466249541586, + y: 1276.3930310334215 }, flowType: 'historyNode', inputs: [ { key: 'maxContext', - value: 10, + value: 6, connected: true }, { @@ -673,6 +695,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'history', + label: '聊天记录', + valueType: 'chat_history', + type: 'source', targets: [ { moduleId: 'chatModule', @@ -697,7 +722,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = }, { key: 'similarity', - value: 0.82, + value: 0.8, connected: true }, { @@ -717,15 +742,21 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'isEmpty', + label: '搜索结果为空', + type: 'source', + valueType: 'boolean', targets: [ { - moduleId: 'asv5cb', + moduleId: 'chatModule', key: 'switch' } ] }, { key: 'unEmpty', + label: '搜索结果不为空', + type: 'source', + valueType: 'boolean', targets: [ { moduleId: 'chatModule', @@ -735,6 +766,10 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = }, { key: 'quoteQA', + label: '引用内容', + description: '搜索结果为空时不返回', + type: 'source', + valueType: 'kb_quote', targets: [ { moduleId: 'chatModule', @@ -747,34 +782,34 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = { moduleId: 'chatModule', position: { - x: 1521.114092861523, - y: 1038.6910820851604 + x: 1564.2820496250988, + y: 842.3852152224699 }, flowType: 'chatNode', inputs: [ { key: 'model', - value: 'gpt-3.5-turbo-16k', + value: 'gpt-3.5-turbo', connected: true }, { key: 'temperature', - value: 5, + value: 0, connected: true }, { key: 'maxToken', - value: 16000, + value: 2000, connected: true }, { key: 'systemPrompt', - value: '知识库是关于 laf 的内容。', + value: '', connected: true }, { key: 'limitPrompt', - value: '根据知识库回答用户问题,回答范围仅限知识库。', + value: '', connected: true }, { @@ -797,29 +832,20 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'answerText', + label: '模型回复', + description: '直接响应,无需配置', + type: 'hidden', + targets: [] + }, + { + key: 'finish', + label: '回复结束', + description: 'AI 回复完成后触发', + valueType: 'boolean', + type: 'source', targets: [] } ] - }, - { - moduleId: 'asv5cb', - position: { - x: 1517.320542832093, - y: 699.8757371712562 - }, - flowType: 'answerNode', - inputs: [ - { - key: 'switch', - connected: true - }, - { - key: 'text', - value: '对不起,我找不到你的问题,请更加详细的描述 laf 相关的问题。', - connected: true - } - ], - outputs: [] } ] }, @@ -839,8 +865,53 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = inputs: [ { key: 'welcomeText', - value: - '你好,我是翻译助手,可以帮你把内容翻译成任何语言,请告诉我,你需要翻译成什么语言?', + value: '你好,我可以为你翻译各种语言,请告诉我你需要翻译成什么语言?', + connected: true + } + ], + outputs: [] + }, + { + moduleId: 'variable', + position: { + x: 444.0369195277651, + y: 1008.5185781784537 + }, + flowType: 'variable', + inputs: [ + { + key: 'variables', + value: [ + { + id: '35c640eb-cf22-431f-bb57-3fc21643880e', + key: 'language', + label: '目标语言', + type: 'input', + required: true, + maxLen: 50, + enums: [ + { + value: '' + } + ] + }, + { + id: '2011ff08-91aa-4f60-ae69-f311ab4797b3', + key: 'language2', + label: '下拉框测试', + type: 'select', + required: false, + maxLen: 50, + enums: [ + { + value: '英语' + }, + { + value: '法语' + } + ] + } + ], connected: true } ], @@ -862,6 +933,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'userChatInput', + label: '用户问题', + type: 'source', + valueType: 'string', targets: [ { moduleId: 'chatModule', @@ -892,6 +966,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'history', + label: '聊天记录', + valueType: 'chat_history', + type: 'source', targets: [ { moduleId: 'chatModule', @@ -911,7 +988,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = inputs: [ { key: 'model', - value: 'gpt-3.5-turbo-16k', + value: 'gpt-3.5-turbo', connected: true }, { @@ -921,7 +998,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = }, { key: 'maxToken', - value: 8000, + value: 2000, connected: true }, { @@ -931,7 +1008,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = }, { key: 'limitPrompt', - value: '把用户发送的内容直接翻译成{{language}},不要做其他回答。', + value: '将我的问题直接翻译成英语{{language}}', connected: true }, { @@ -954,39 +1031,20 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'answerText', + label: '模型回复', + description: '直接响应,无需配置', + type: 'hidden', + targets: [] + }, + { + key: 'finish', + label: '回复结束', + description: 'AI 回复完成后触发', + valueType: 'boolean', + type: 'source', targets: [] } ] - }, - { - moduleId: 'fo9i68', - position: { - x: 445.17843864558927, - y: 992.4891333735476 - }, - flowType: 'variable', - inputs: [ - { - key: 'variables', - value: [ - { - id: '9qjnai', - key: 'language', - label: '目标语言', - type: 'input', - required: true, - maxLen: 50, - enums: [ - { - value: '' - } - ] - } - ], - connected: true - } - ], - outputs: [] } ] }, @@ -1012,6 +1070,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'userChatInput', + label: '用户问题', + type: 'source', + valueType: 'string', targets: [ { moduleId: 'remuj3', @@ -1039,7 +1100,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = inputs: [ { key: 'maxContext', - value: 10, + value: 6, connected: true }, { @@ -1050,6 +1111,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'history', + label: '聊天记录', + valueType: 'chat_history', + type: 'source', targets: [ { moduleId: 'nlfwkc', @@ -1082,7 +1146,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = connected: true }, { - key: SpecialInputKeyEnum.agents, + key: 'agents', value: [ { value: '打招呼、问候等问题', @@ -1093,8 +1157,12 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = key: 'fqsw' }, { - value: '其他问题', + value: '商务问题', key: 'fesw' + }, + { + value: '其他问题', + key: 'oy1c' } ], connected: true @@ -1103,6 +1171,8 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'fasw', + label: '', + type: 'hidden', targets: [ { moduleId: 'a99p6z', @@ -1112,6 +1182,8 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = }, { key: 'fqsw', + label: '', + type: 'hidden', targets: [ { moduleId: 'fljhzy', @@ -1121,6 +1193,19 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = }, { key: 'fesw', + label: '', + type: 'hidden', + targets: [ + { + moduleId: '5v78ap', + key: 'switch' + } + ] + }, + { + key: 'oy1c', + label: '', + type: 'hidden', targets: [ { moduleId: 'iejcou', @@ -1153,8 +1238,8 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = { moduleId: 'iejcou', position: { - x: 1301.7531189034548, - y: 1842.1297123368286 + x: 1294.2531189034548, + y: 2127.1297123368286 }, flowType: 'answerNode', inputs: [ @@ -1224,6 +1309,17 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'answerText', + label: '模型回复', + description: '直接响应,无需配置', + type: 'hidden', + targets: [] + }, + { + key: 'finish', + label: '回复结束', + description: 'AI 回复完成后触发', + valueType: 'boolean', + type: 'source', targets: [] } ] @@ -1249,6 +1345,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'history', + label: '聊天记录', + valueType: 'chat_history', + type: 'source', targets: [ { moduleId: 'remuj3', @@ -1268,7 +1367,11 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = inputs: [ { key: 'kbList', - value: [], + value: [ + { + kbId: '646627f4f7b896cfd8910e24' + } + ], connected: true }, { @@ -1293,6 +1396,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = outputs: [ { key: 'isEmpty', + label: '搜索结果为空', + type: 'source', + valueType: 'boolean', targets: [ { moduleId: 'tc90wz', @@ -1302,6 +1408,9 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = }, { key: 'unEmpty', + label: '搜索结果不为空', + type: 'source', + valueType: 'boolean', targets: [ { moduleId: 'nlfwkc', @@ -1311,6 +1420,10 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = }, { key: 'quoteQA', + label: '引用内容', + description: '搜索结果为空时不返回', + type: 'source', + valueType: 'kb_quote', targets: [ { moduleId: 'nlfwkc', @@ -1356,6 +1469,26 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = } ], outputs: [] + }, + { + moduleId: '5v78ap', + position: { + x: 1294.814522053934, + y: 1822.7626988141562 + }, + flowType: 'answerNode', + inputs: [ + { + key: 'switch', + connected: true + }, + { + key: 'text', + value: '这是一个商务问题', + connected: true + } + ], + outputs: [] } ] } diff --git a/client/src/constants/flow/index.ts b/client/src/constants/flow/index.ts index 2e34718fda..dc7196b192 100644 --- a/client/src/constants/flow/index.ts +++ b/client/src/constants/flow/index.ts @@ -45,7 +45,7 @@ export enum FlowValueTypeEnum { 'boolean' = 'boolean', 'chatHistory' = 'chat_history', 'kbQuote' = 'kb_quote', - 'other' = 'other' + 'any' = 'any' } export const FlowValueTypeStyle: Record<`${FlowValueTypeEnum}`, BoxProps> = { @@ -64,7 +64,7 @@ export const FlowValueTypeStyle: Record<`${FlowValueTypeEnum}`, BoxProps> = { [FlowValueTypeEnum.kbQuote]: { background: '#A558C9' }, - [FlowValueTypeEnum.other]: { + [FlowValueTypeEnum.any]: { background: '#9CA2A8' } }; diff --git a/client/src/constants/flow/inputTemplate.ts b/client/src/constants/flow/inputTemplate.ts index 5dec332408..8bc9187918 100644 --- a/client/src/constants/flow/inputTemplate.ts +++ b/client/src/constants/flow/inputTemplate.ts @@ -6,7 +6,7 @@ export const Input_Template_TFSwitch: FlowInputItemType = { key: SystemInputEnum.switch, type: FlowInputItemTypeEnum.target, label: '触发器', - valueType: FlowValueTypeEnum.boolean + valueType: FlowValueTypeEnum.any }; export const Input_Template_History: FlowInputItemType = { diff --git a/client/src/pages/api/openapi/v1/chat/completions.ts b/client/src/pages/api/openapi/v1/chat/completions.ts index dbf8cbf4ef..2143cf97cf 100644 --- a/client/src/pages/api/openapi/v1/chat/completions.ts +++ b/client/src/pages/api/openapi/v1/chat/completions.ts @@ -139,7 +139,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex // } // save chat - if (typeof chatId === 'string') { + if (chatId) { await saveChat({ chatId, appId, diff --git a/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeAnswer.tsx b/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeAnswer.tsx index 2f61524b06..c47afe2267 100644 --- a/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeAnswer.tsx +++ b/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeAnswer.tsx @@ -11,8 +11,7 @@ const NodeAnswer = ({ }: NodeProps) => { return ( - - + diff --git a/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeCQNode.tsx b/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeCQNode.tsx index 438a841b0d..1720f95e2e 100644 --- a/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeCQNode.tsx +++ b/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeCQNode.tsx @@ -55,7 +55,7 @@ const NodeCQNode = ({ onChangeNode({ moduleId, type: 'outputs', - key: agentKey, + key: '', value: newOutputVal }); }} diff --git a/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeExtract.tsx b/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeExtract.tsx index 1549e5bbb6..936172a7df 100644 --- a/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeExtract.tsx +++ b/client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeExtract.tsx @@ -13,6 +13,8 @@ import RenderOutput from '../render/RenderOutput'; import MyIcon from '@/components/Icon'; import ExtractFieldModal from '../modules/ExtractFieldModal'; import { ContextExtractEnum } from '@/constants/flow/flowField'; +import SourceHandle from '../render/SourceHandle'; +import { FlowOutputItemTypeEnum, FlowValueTypeEnum } from '@/constants/flow'; const NodeExtract = ({ data: { inputs, outputs, moduleId, onChangeNode, ...props } @@ -36,7 +38,22 @@ const NodeExtract = ({ key: string; value?: ContextExtractAgentItemType[]; }) => ( - + + + + @@ -49,10 +66,10 @@ const NodeExtract = ({ {extractKeys.map((item, index) => ( - +
{item.key} - {item.desc}{' '} + {item.desc} {item.required ? '✔' : ''} @@ -70,11 +87,24 @@ const NodeExtract = ({ w={'16px'} cursor={'pointer'} onClick={() => { + const newInputValue = extractKeys.filter( + (extract) => item.key !== extract.key + ); + const newOutputVal = outputs.filter( + (output) => output.key !== item.key + ); + onChangeNode({ moduleId, type: 'inputs', key: ContextExtractEnum.extractKeys, - value: extractKeys.filter((extract) => item.key !== extract.key) + value: newInputValue + }); + onChangeNode({ + moduleId, + type: 'outputs', + key: '', + value: newOutputVal }); }} /> @@ -84,21 +114,6 @@ const NodeExtract = ({
- - -
) }} @@ -119,21 +134,39 @@ const NodeExtract = ({ const exists = extracts.find((item) => item.key === editExtractFiled.key); - if (exists) { - onChangeNode({ - moduleId, - type: 'inputs', - key: ContextExtractEnum.extractKeys, - value: extracts.map((item) => (item.key === editExtractFiled.key ? data : item)) - }); - } else { - onChangeNode({ - moduleId, - type: 'inputs', - key: ContextExtractEnum.extractKeys, - value: extracts.concat(data) - }); - } + const newInputs = exists + ? extracts.map((item) => (item.key === editExtractFiled.key ? data : item)) + : extracts.concat(data); + const newOutputs = exists + ? outputs.map((output) => + output.key === editExtractFiled.key + ? { + ...output, + key: data.key, + label: `提取结果-${data.desc}` + } + : output + ) + : outputs.concat({ + key: data.key, + label: `提取结果-${data.desc}`, + valueType: FlowValueTypeEnum.string, + type: FlowOutputItemTypeEnum.source, + targets: [] + }); + + onChangeNode({ + moduleId, + type: 'inputs', + key: ContextExtractEnum.extractKeys, + value: newInputs + }); + onChangeNode({ + moduleId, + type: 'outputs', + key: '', + value: newOutputs + }); setEditExtractField(undefined); }} diff --git a/client/src/pages/app/detail/components/AdEdit/components/render/RenderInput.tsx b/client/src/pages/app/detail/components/AdEdit/components/render/RenderInput.tsx index 6ccc4a2b35..b76743ee62 100644 --- a/client/src/pages/app/detail/components/AdEdit/components/render/RenderInput.tsx +++ b/client/src/pages/app/detail/components/AdEdit/components/render/RenderInput.tsx @@ -35,7 +35,7 @@ export const Label = ({ )} {description && ( - + )}
diff --git a/client/src/pages/app/detail/components/AdEdit/components/render/RenderOutput.tsx b/client/src/pages/app/detail/components/AdEdit/components/render/RenderOutput.tsx index 3ad299abb3..f4178cd561 100644 --- a/client/src/pages/app/detail/components/AdEdit/components/render/RenderOutput.tsx +++ b/client/src/pages/app/detail/components/AdEdit/components/render/RenderOutput.tsx @@ -17,14 +17,14 @@ const Label = ({ {description && ( - + )} {children} ); -const RenderBody = ({ flowOutputList }: { flowOutputList: FlowOutputItemType[] }) => { +const RenderOutput = ({ flowOutputList }: { flowOutputList: FlowOutputItemType[] }) => { return ( <> {flowOutputList.map( @@ -44,4 +44,4 @@ const RenderBody = ({ flowOutputList }: { flowOutputList: FlowOutputItemType[] } ); }; -export default React.memo(RenderBody); +export default RenderOutput; diff --git a/client/src/pages/app/detail/components/AdEdit/components/render/SourceHandle.tsx b/client/src/pages/app/detail/components/AdEdit/components/render/SourceHandle.tsx index 01b58e0068..bdac370342 100644 --- a/client/src/pages/app/detail/components/AdEdit/components/render/SourceHandle.tsx +++ b/client/src/pages/app/detail/components/AdEdit/components/render/SourceHandle.tsx @@ -14,8 +14,8 @@ const SourceHandle = ({ handleKey, valueType, ...props }: Props) => { () => valueType ? FlowValueTypeStyle[valueType] - : (FlowValueTypeStyle[FlowValueTypeEnum.other] as any), - [] + : (FlowValueTypeStyle[FlowValueTypeEnum.any] as any), + [valueType] ); return ( diff --git a/client/src/pages/app/detail/components/AdEdit/components/render/TargetHandle.tsx b/client/src/pages/app/detail/components/AdEdit/components/render/TargetHandle.tsx index d176b730da..6fe8a72b74 100644 --- a/client/src/pages/app/detail/components/AdEdit/components/render/TargetHandle.tsx +++ b/client/src/pages/app/detail/components/AdEdit/components/render/TargetHandle.tsx @@ -15,7 +15,7 @@ const TargetHandle = ({ handleKey, valueType, onConnect, ...props }: Props) => { () => valueType ? FlowValueTypeStyle[valueType] - : (FlowValueTypeStyle[FlowValueTypeEnum.other] as any), + : (FlowValueTypeStyle[FlowValueTypeEnum.any] as any), [] ); diff --git a/client/src/pages/app/detail/components/AdEdit/index.tsx b/client/src/pages/app/detail/components/AdEdit/index.tsx index d7e04a18cd..3a47c4afec 100644 --- a/client/src/pages/app/detail/components/AdEdit/index.tsx +++ b/client/src/pages/app/detail/components/AdEdit/index.tsx @@ -132,7 +132,7 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => { connected: item.type !== FlowInputItemTypeEnum.target })), outputs: item.data.outputs.map((item) => ({ - key: item.key, + ...item, targets: [] as FlowOutputTargetItemType[] })) })); @@ -254,7 +254,11 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => { title: t('app.Connection is invalid') }); } - if (sourceType !== targetType) { + if ( + sourceType !== FlowValueTypeEnum.any && + targetType !== FlowValueTypeEnum.any && + sourceType !== targetType + ) { return toast({ status: 'warning', title: t('app.Connection type is different') @@ -280,6 +284,7 @@ const AppEdit = ({ app, fullScreen, onFullScreen }: Props) => { const { mutate: onclickSave, isLoading } = useRequest({ mutationFn: () => { + console.log(flow2AppModules(), '===='); return updateAppDetail(app._id, { modules: flow2AppModules() }); diff --git a/client/src/service/moduleDispatch/agent/extract.ts b/client/src/service/moduleDispatch/agent/extract.ts index e096b3bedc..c364ce6d19 100644 --- a/client/src/service/moduleDispatch/agent/extract.ts +++ b/client/src/service/moduleDispatch/agent/extract.ts @@ -96,7 +96,6 @@ export async function dispatchContentExtract({ return {}; } })(); - console.log(adaptMessages, arg); // auth fields let success = !extractKeys.find((item) => !arg[item.key]); @@ -109,6 +108,7 @@ export async function dispatchContentExtract({ } } } + console.log(arg, '===='); const tokens = response.data.usage?.total_tokens || 0; @@ -116,6 +116,7 @@ export async function dispatchContentExtract({ [ContextExtractEnum.success]: success ? true : undefined, [ContextExtractEnum.failed]: success ? undefined : true, [ContextExtractEnum.fields]: arg, + ...arg, [TaskResponseKeyEnum.responseData]: { moduleName: ChatModuleEnum.Extract, price: userOpenaiAccount?.key ? 0 : countModelPrice({ model: agentModel, tokens }), diff --git a/client/src/service/utils/chat/saveChat.ts b/client/src/service/utils/chat/saveChat.ts index 7e7b1fd156..1ddf82474d 100644 --- a/client/src/service/utils/chat/saveChat.ts +++ b/client/src/service/utils/chat/saveChat.ts @@ -36,7 +36,7 @@ export async function saveChat({ if (chatHistory) { promise.push( Chat.findOneAndUpdate( - { chatId }, + { chatId, userId }, { $push: { content: { diff --git a/client/src/types/app.d.ts b/client/src/types/app.d.ts index b22e8ddaf3..fdabd1d571 100644 --- a/client/src/types/app.d.ts +++ b/client/src/types/app.d.ts @@ -64,13 +64,12 @@ export type VariableItemType = { /* app module */ export type AppModuleInputItemType = { key: string; value?: any; connected?: boolean }; -export type AppModuleOutputItemType = { key: string; targets: FlowOutputTargetItemType[] }; export type AppModuleItemType = { moduleId: string; position?: XYPosition; flowType: `${FlowModuleTypeEnum}`; inputs: AppModuleInputItemType[]; - outputs: AppModuleOutputItemType[]; + outputs: FlowOutputItemType[]; }; export type AppItemType = { diff --git a/client/src/types/flow.d.ts b/client/src/types/flow.d.ts index f4fb4d6e3d..6ed9df9d6d 100644 --- a/client/src/types/flow.d.ts +++ b/client/src/types/flow.d.ts @@ -39,10 +39,10 @@ export type FlowOutputTargetItemType = { }; export type FlowOutputItemType = { key: string; // 字段名 - label: string; + label?: string; description?: string; valueType?: `${FlowValueTypeEnum}`; - type: `${FlowOutputItemTypeEnum}`; + type?: `${FlowOutputItemTypeEnum}`; targets: FlowOutputTargetItemType[]; }; diff --git a/client/src/utils/adapt.ts b/client/src/utils/adapt.ts index da1d0fcac2..2e1b4cc6f1 100644 --- a/client/src/utils/adapt.ts +++ b/client/src/utils/adapt.ts @@ -73,6 +73,10 @@ export const appModule2FlowNode = ({ const template = ModuleTemplatesFlat.find((template) => template.flowType === item.flowType) || EmptyModule; + const mergeOutputs = item.outputs.concat( + template.outputs.filter((output) => !item.outputs.find((item) => item.key === output.key)) + ); + // replace item data const moduleItem: FlowModuleItemType = { ...item, @@ -85,14 +89,14 @@ export const appModule2FlowNode = ({ value: itemInput.value }; }), - outputs: template.outputs.map((templateOutput) => { + // 合并 template 和数据库,文案以 template 为准 + outputs: mergeOutputs.map((output) => { // unChange outputs - const itemOutput = - item.outputs.find((item) => item.key === templateOutput.key) || templateOutput; + const templateOutput = template.outputs.find((item) => item.key === output.key); return { - ...templateOutput, - targets: itemOutput.targets || [] + ...(templateOutput ? templateOutput : output), + targets: output.targets || [] }; }), onChangeNode, @@ -131,5 +135,6 @@ export const appModule2FlowEdge = ({ }) ) ); + return edges; };