From 23642af6e2707211c6a9d9be21cb2481db66d47f Mon Sep 17 00:00:00 2001 From: archer <545436317@qq.com> Date: Thu, 6 Jul 2023 19:35:02 +0800 Subject: [PATCH] feat: agent and ui --- client/public/imgs/loading.gif | Bin 99234 -> 0 bytes client/public/imgs/modelAvatar.png | Bin 8537 -> 0 bytes client/public/imgs/module/AI.png | Bin 0 -> 1551 bytes client/public/imgs/module/cq.png | Bin 0 -> 2646 bytes client/public/imgs/module/db.png | Bin 0 -> 1473 bytes client/public/imgs/module/history.png | Bin 0 -> 1531 bytes client/public/imgs/module/reply.png | Bin 0 -> 776 bytes client/public/imgs/module/userChatInput.png | Bin 0 -> 572 bytes client/src/components/Icon/icons/minus.svg | 1 + client/src/components/Icon/index.tsx | 3 +- client/src/components/Layout/navbar.tsx | 2 +- .../src/components/Markdown/img/Loading.tsx | 25 -- client/src/components/MyTooltip/index.tsx | 24 ++ client/src/constants/app.ts | 276 ++++++------ client/src/constants/chat.ts | 2 +- client/src/constants/flow/ModuleTemplate.ts | 67 ++- client/src/constants/flow/index.ts | 3 +- client/src/constants/theme.ts | 11 + .../openapi/modules/agent/classifyQuestion.ts | 7 +- .../src/pages/api/openapi/modules/chat/gpt.ts | 12 +- .../pages/api/openapi/modules/kb/search.ts | 3 +- .../pages/api/openapi/v1/chat/completions2.ts | 11 +- client/src/pages/app/detail/components/Kb.tsx | 394 ------------------ .../src/pages/app/detail/components/Share.tsx | 6 +- .../components/edit/components/NodeAnswer.tsx | 8 +- .../components/edit/components/NodeCQNode.tsx | 136 ++++++ .../edit/components/NodeKbSearch.tsx | 2 +- .../edit/components/TemplateList.tsx | 127 +++--- .../edit/components/modules/Label.tsx | 7 +- .../edit/components/render/RenderInput.tsx | 27 +- .../edit/components/render/RenderOutput.tsx | 7 +- .../app/detail/components/edit/index.tsx | 136 +++--- .../pages/app/list/component/CreateModal.tsx | 2 +- client/src/pages/app/list/index.tsx | 8 +- client/src/pages/appStore/components/list.tsx | 7 +- client/src/pages/chat/index.tsx | 6 +- client/src/pages/chat/share.tsx | 6 +- client/src/pages/kb/components/Info.tsx | 7 +- client/src/pages/kb/components/KbList.tsx | 7 +- .../components/detail/components/Settings.tsx | 388 ----------------- client/src/types/app.d.ts | 2 +- client/src/types/flow.d.ts | 1 + client/src/utils/adapt.ts | 2 - client/src/utils/plugin/index.ts | 3 - 44 files changed, 588 insertions(+), 1148 deletions(-) delete mode 100644 client/public/imgs/loading.gif delete mode 100644 client/public/imgs/modelAvatar.png create mode 100644 client/public/imgs/module/AI.png create mode 100644 client/public/imgs/module/cq.png create mode 100644 client/public/imgs/module/db.png create mode 100644 client/public/imgs/module/history.png create mode 100644 client/public/imgs/module/reply.png create mode 100644 client/public/imgs/module/userChatInput.png create mode 100644 client/src/components/Icon/icons/minus.svg delete mode 100644 client/src/components/Markdown/img/Loading.tsx create mode 100644 client/src/components/MyTooltip/index.tsx delete mode 100644 client/src/pages/app/detail/components/Kb.tsx create mode 100644 client/src/pages/app/detail/components/edit/components/NodeCQNode.tsx delete mode 100644 client/src/pages/model/components/detail/components/Settings.tsx diff --git a/client/public/imgs/loading.gif b/client/public/imgs/loading.gif deleted file mode 100644 index e5e62462d48dd4fd3f5fbe7c16aa834e37c64582..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99234 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 diff --git a/client/public/imgs/modelAvatar.png b/client/public/imgs/modelAvatar.png deleted file mode 100644 index 58cf2b2182048322470a9b287a8aa98ee144219d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8537 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 T`FUS`00000NkvXXu0mjf+Cz!4 diff --git a/client/public/imgs/module/AI.png b/client/public/imgs/module/AI.png new file mode 100644 index 0000000000000000000000000000000000000000..800ee763c65fdc493e714132aafea860c0195b43 GIT binary patch literal 1551 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 Ef(Rz@=>Px# literal 0 HcmV?d00001 diff --git a/client/public/imgs/module/db.png b/client/public/imgs/module/db.png new file mode 100644 index 0000000000000000000000000000000000000000..4c048f896362a14046a269066af79d3615748b9c GIT binary patch literal 1473 zcmV;y1wQ(TP)Px)dr3q=RCr$Pn$K?=MHI)sZ{ie^Q$?h3pcUrQ6IBjTtd>TplT_lu86++=5+_6@ zj)+U)z+b=-p|%|0zzuQ4uA3$#xXPg_CnJPWa!I5}0Vy#`?0IO`yJl^?-ubnTL$i`4 zOFM7oz0bUP^WMx7PVt$Yot=z^-`d(bIt^85ScA?jELso`g^EQS0!}OA&e|t98&&ZFG{P zE&ykB<_B=BwHgOIgFtiuWLw4go@(R%5 z1$pM%^+2EzDQJevHI_6{*6vTBX%N56%vVDzrx}<|vY3E90DDZ>6`(z4Jj;Sklrxa; ztxp-ukhd6koq)(_R~vQ#{KAB1#8h(aERYYE0u>gPminI28;(MRtIWI%K>f0O0vJS8 za`uj6Y^WvR6adwXOUREr&bA4>ZvpzoM4+c_&B+5ocmK*k0Ux5f0KIS3k;J|e0018X z{HE35euX{ionE4$d zVSc+Dc!0~v?lCrSf$spg>(e0Zz8G~uVx=XHe#gt@8|vovTCtet z6LFUbw~dvs7x=8YR{m6pw-0J9001?&VkiU<*`Pqkrnt@En*=J_+m;~7sDtnzGCXSK z48Yb41WU2G{_y*L>M9tmmIxpSiJOu*uMI^R3V?tL6aEkomCdyuD@j1-ZY;iS69cMi zr5_v*MEG5ilb>u>DuKc}j{?)xu9?dt*X+of^riZ_Hh-%qAwRI#1%ex;?jte7yZvAr zWW3VPEp=eHwkgansTiOFu-P^!_^7&CE{9&$t%gZJjOPIiu7K#llgH)zu7;(_2Zl4= z10nJzGXSyJ)&E#rGdJj)2r=qv?Mi`1V`H*n>e5N^Lz znINOi#C5?`R{@Qw9pJ`T{3mX-Nal&#v#N|W2%LHVdUmb8OCUZ2X;))f0Mh)~&-=ju z27F|tbvfDrk>iQ@*}>=oklQ#GJA*#6(*n@z75w7KB+2m!Fn7I)Y&H#cE*W;ShfzpXN;Yk!R?%Pg+9{`cou{ywaQ4}*;jn;JpH#z{~(-%9` z2nwSx_fHE}o%4cbE-xXAIyJ#)0?_g0DDd?LL><{!o3jhR(9opj&piMptk}jJryzJ< z3q*&K=e0olKH$6-2=4-hT?@FxQl}V@HgK?~XIu-U>5%q5Qvhj$kHY(N0HZJqr>Vnp b?*ab+6n^R|eV-RY00000NkvXXu0mjf&0?;g literal 0 HcmV?d00001 diff --git a/client/public/imgs/module/history.png b/client/public/imgs/module/history.png new file mode 100644 index 0000000000000000000000000000000000000000..3fd4b5140d79bc930b07b1cc542cb64acd52ad04 GIT binary patch literal 1531 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 \ No newline at end of file diff --git a/client/src/components/Icon/index.tsx b/client/src/components/Icon/index.tsx index 4ef827685..62d4b9c40 100644 --- a/client/src/components/Icon/index.tsx +++ b/client/src/components/Icon/index.tsx @@ -35,7 +35,8 @@ const map = { kbTest: require('./icons/kbTest.svg').default, date: require('./icons/date.svg').default, apikey: require('./icons/apikey.svg').default, - save: require('./icons/save.svg').default + save: require('./icons/save.svg').default, + minus: require('./icons/minus.svg').default }; export type IconName = keyof typeof map; diff --git a/client/src/components/Layout/navbar.tsx b/client/src/components/Layout/navbar.tsx index 45b335e75..f36764e4f 100644 --- a/client/src/components/Layout/navbar.tsx +++ b/client/src/components/Layout/navbar.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import { Box, Flex, Tooltip, Link } from '@chakra-ui/react'; +import { Box, Flex, Link } from '@chakra-ui/react'; import { useRouter } from 'next/router'; import MyIcon from '../Icon'; import { useUserStore } from '@/store/user'; diff --git a/client/src/components/Markdown/img/Loading.tsx b/client/src/components/Markdown/img/Loading.tsx deleted file mode 100644 index 4e454a1d9..000000000 --- a/client/src/components/Markdown/img/Loading.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React, { memo } from 'react'; -import { Box } from '@chakra-ui/react'; - -const Loading = ({ text }: { text?: string }) => { - return ( - - - {text && ( - - {text} - - )} - - ); -}; - -export default memo(Loading); diff --git a/client/src/components/MyTooltip/index.tsx b/client/src/components/MyTooltip/index.tsx new file mode 100644 index 000000000..d51261c56 --- /dev/null +++ b/client/src/components/MyTooltip/index.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { Tooltip, TooltipProps } from '@chakra-ui/react'; + +const MyTooltip = ({ children, ...props }: TooltipProps) => { + return ( + + {children} + + ); +}; + +export default MyTooltip; diff --git a/client/src/constants/app.ts b/client/src/constants/app.ts index 007d01c34..aed39f7bf 100644 --- a/client/src/constants/app.ts +++ b/client/src/constants/app.ts @@ -155,145 +155,145 @@ export const chatAppDemo: AppItemType = { modules: [chatModule({ id: 'chat' })] }; -export const kbChatAppDemo: AppItemType = { - id: 'kbchat', - name: 'kbchat', - // 标记字段 - modules: [ - { - moduleId: 'kbsearch', - flowType: FlowModuleTypeEnum.kbSearchNode, - type: AppModuleItemTypeEnum.http, - url: '/openapi/modules/kb/search', - position: { x: -500, y: 0 }, - inputs: [ - { - key: 'kb_ids', - type: FlowInputItemTypeEnum.custom, - label: '关联的知识库', - value: ['646627f4f7b896cfd8910e38'], - list: [] - }, +// export const kbChatAppDemo: AppItemType = { +// id: 'kbchat', +// name: 'kbchat', +// // 标记字段 +// modules: [ +// { +// moduleId: 'kbsearch', +// flowType: FlowModuleTypeEnum.kbSearchNode, +// type: AppModuleItemTypeEnum.http, +// url: '/openapi/modules/kb/search', +// position: { x: -500, y: 0 }, +// inputs: [ +// { +// key: 'kb_ids', +// type: FlowInputItemTypeEnum.custom, +// label: '关联的知识库', +// value: ['646627f4f7b896cfd8910e38'], +// list: [] +// }, - { - key: 'similarity', - type: FlowInputItemTypeEnum.slider, - label: '相似度', - value: 0.8, - min: 0, - max: 1, - step: 0.01, - markList: [ - { label: '0', value: 0 }, - { label: '1', value: 1 } - ] - }, - { - key: 'limit', - type: FlowInputItemTypeEnum.slider, - label: '单次搜索上限', - value: 5, - min: 1, - max: 20, - step: 1, - markList: [ - { label: '1', value: 1 }, - { label: '20', value: 20 } - ] - }, - { - key: SystemInputEnum.history, - type: FlowInputItemTypeEnum.hidden, - label: '引用复用数量', - value: 1 - }, - { - key: SystemInputEnum.userChatInput, - type: FlowInputItemTypeEnum.none, - label: '用户输入(系统自动填写)', - description: '' - } - ], - outputs: [ - { - key: 'rawSearch', - label: '源搜索数据', - type: FlowOutputItemTypeEnum.none, - response: true, - targets: [] - }, - { - key: 'isEmpty', - label: '无搜索结果', - type: FlowOutputItemTypeEnum.source, - targets: [ - { - moduleId: 'tfswitch', - key: SystemInputEnum.switch - } - ] - }, - { - key: 'quotePrompt', - label: '引用内容(字符串)', - type: FlowOutputItemTypeEnum.source, - targets: [ - { - moduleId: 'chat', - key: 'quotePrompt' - } - ] - } - ] - }, - { - moduleId: 'tfswitch', - type: AppModuleItemTypeEnum.switch, - flowType: FlowModuleTypeEnum.tfSwitchNode, - position: { x: 0, y: 510 }, - inputs: [ - { - key: SystemInputEnum.switch, - type: FlowInputItemTypeEnum.target, - label: '触发器', - connected: true - } - ], - outputs: [ - { - key: 'true', - label: '无搜索数据', - type: FlowOutputItemTypeEnum.source, - targets: [ - { - moduleId: 'answer', - key: SystemInputEnum.switch - } - ] - }, - { - key: 'false', - label: '有搜索数据', - type: FlowOutputItemTypeEnum.source, - targets: [ - { - moduleId: 'chat', - key: SystemInputEnum.switch - } - ] - } - ] - }, - { - ...chatModule({ id: 'chat', limitPrompt: '参考知识库内容进行回答', history: 5 }), - position: { x: 300, y: 240 } - }, - { - ...answerModule({ id: 'answer' }), - position: { x: 300, y: 0 } - } - ] -}; +// { +// key: 'similarity', +// type: FlowInputItemTypeEnum.slider, +// label: '相似度', +// value: 0.8, +// min: 0, +// max: 1, +// step: 0.01, +// markList: [ +// { label: '0', value: 0 }, +// { label: '1', value: 1 } +// ] +// }, +// { +// key: 'limit', +// type: FlowInputItemTypeEnum.slider, +// label: '单次搜索上限', +// value: 5, +// min: 1, +// max: 20, +// step: 1, +// markList: [ +// { label: '1', value: 1 }, +// { label: '20', value: 20 } +// ] +// }, +// { +// key: SystemInputEnum.history, +// type: FlowInputItemTypeEnum.hidden, +// label: '引用复用数量', +// value: 1 +// }, +// { +// key: SystemInputEnum.userChatInput, +// type: FlowInputItemTypeEnum.none, +// label: '用户输入(系统自动填写)', +// description: '' +// } +// ], +// outputs: [ +// { +// key: 'rawSearch', +// label: '源搜索数据', +// type: FlowOutputItemTypeEnum.none, +// response: true, +// targets: [] +// }, +// { +// key: 'isEmpty', +// label: '无搜索结果', +// type: FlowOutputItemTypeEnum.source, +// targets: [ +// { +// moduleId: 'tfswitch', +// key: SystemInputEnum.switch +// } +// ] +// }, +// { +// key: 'quotePrompt', +// label: '引用内容(字符串)', +// type: FlowOutputItemTypeEnum.source, +// targets: [ +// { +// moduleId: 'chat', +// key: 'quotePrompt' +// } +// ] +// } +// ] +// }, +// { +// moduleId: 'tfswitch', +// type: AppModuleItemTypeEnum.switch, +// flowType: FlowModuleTypeEnum.tfSwitchNode, +// position: { x: 0, y: 510 }, +// inputs: [ +// { +// key: SystemInputEnum.switch, +// type: FlowInputItemTypeEnum.target, +// label: '触发器', +// connected: true +// } +// ], +// outputs: [ +// { +// key: 'true', +// label: '无搜索数据', +// type: FlowOutputItemTypeEnum.source, +// targets: [ +// { +// moduleId: 'answer', +// key: SystemInputEnum.switch +// } +// ] +// }, +// { +// key: 'false', +// label: '有搜索数据', +// type: FlowOutputItemTypeEnum.source, +// targets: [ +// { +// moduleId: 'chat', +// key: SystemInputEnum.switch +// } +// ] +// } +// ] +// }, +// { +// ...chatModule({ id: 'chat', limitPrompt: '参考知识库内容进行回答', history: 5 }), +// position: { x: 300, y: 240 } +// }, +// { +// ...answerModule({ id: 'answer' }), +// position: { x: 300, y: 0 } +// } +// ] +// }; // export const classifyQuestionDemo: AppItemType = { // id: 'classifyQuestionDemo', diff --git a/client/src/constants/chat.ts b/client/src/constants/chat.ts index f51641db5..f1bc61234 100644 --- a/client/src/constants/chat.ts +++ b/client/src/constants/chat.ts @@ -25,4 +25,4 @@ export const ChatRoleMap = { }; export const HUMAN_ICON = `https://fastgpt.run/icon/human.png`; -export const LOGO_ICON = `https://fastgpt.run/imgs/modelAvatar.png`; +export const LOGO_ICON = `https://fastgpt.run/icon/logo.png`; diff --git a/client/src/constants/flow/ModuleTemplate.ts b/client/src/constants/flow/ModuleTemplate.ts index 42d5d70cd..ee102433b 100644 --- a/client/src/constants/flow/ModuleTemplate.ts +++ b/client/src/constants/flow/ModuleTemplate.ts @@ -1,4 +1,4 @@ -import { AppModuleItemTypeEnum, SystemInputEnum } from '../app'; +import { AppModuleItemTypeEnum, SystemInputEnum, SpecificInputEnum } from '../app'; import { FlowModuleTypeEnum, FlowInputItemTypeEnum, FlowOutputItemTypeEnum } from './index'; import type { AppModuleTemplateItemType } from '@/types/app'; import { chatModelList } from '../data'; @@ -9,7 +9,7 @@ import { } from './inputTemplate'; export const UserInputModule: AppModuleTemplateItemType = { - logo: '', + logo: '/imgs/module/userChatInput.png', name: '用户问题', intro: '用户输入的内容。该模块通常作为应用的入口,用户在发送消息后会首先执行该模块。', type: AppModuleItemTypeEnum.initInput, @@ -32,7 +32,7 @@ export const UserInputModule: AppModuleTemplateItemType = { ] }; export const HistoryModule: AppModuleTemplateItemType = { - logo: '', + logo: '/imgs/module/history.png', name: '聊天记录', intro: '用户输入的内容。该模块通常作为应用的入口,用户在发送消息后会首先执行该模块。', type: AppModuleItemTypeEnum.initInput, @@ -64,7 +64,7 @@ export const HistoryModule: AppModuleTemplateItemType = { }; export const ChatModule: AppModuleTemplateItemType = { - logo: '', + logo: '/imgs/module/AI.png', name: 'AI 对话', intro: 'OpenAI GPT 大模型对话。', flowType: FlowModuleTypeEnum.chatNode, @@ -135,7 +135,7 @@ export const ChatModule: AppModuleTemplateItemType = { ], outputs: [ { - key: 'answer', + key: SpecificInputEnum.answerText, label: '模型回复', description: '直接响应,无需配置', type: FlowOutputItemTypeEnum.hidden, @@ -145,7 +145,7 @@ export const ChatModule: AppModuleTemplateItemType = { }; export const KBSearchModule: AppModuleTemplateItemType = { - logo: '', + logo: '/imgs/module/db.png', name: '知识库搜索', intro: '去知识库中搜索对应的答案。可作为 AI 对话引用参考。', flowType: FlowModuleTypeEnum.kbSearchNode, @@ -205,7 +205,7 @@ export const KBSearchModule: AppModuleTemplateItemType = { { key: 'quotePrompt', label: '引用内容', - description: '搜索结果为空时不触发', + description: '搜索结果为空时不返回', type: FlowOutputItemTypeEnum.source, targets: [] } @@ -213,7 +213,7 @@ export const KBSearchModule: AppModuleTemplateItemType = { }; export const AnswerModule: AppModuleTemplateItemType = { - logo: '', + logo: '/imgs/module/reply.png', name: '指定回复', intro: '该模块可以直接回复一段指定的内容。常用于引导、提示。', type: AppModuleItemTypeEnum.answer, @@ -221,7 +221,7 @@ export const AnswerModule: AppModuleTemplateItemType = { inputs: [ Input_Template_TFSwitch, { - key: 'answerText', + key: SpecificInputEnum.answerText, value: '', type: FlowInputItemTypeEnum.input, label: '回复的内容' @@ -257,31 +257,52 @@ export const TFSwitchModule: AppModuleTemplateItemType = { } ] }; - export const ClassifyQuestionModule: AppModuleTemplateItemType = { - logo: '', + logo: '/imgs/module/cq.png', name: '意图识别', intro: '可以判断用户问题属于哪方面问题,从而执行不同的操作。', - type: AppModuleItemTypeEnum.switch, - flowType: FlowModuleTypeEnum.tfSwitchNode, + type: AppModuleItemTypeEnum.http, + url: '/openapi/modules/agent/classifyQuestion', + flowType: FlowModuleTypeEnum.classifyQuestionNode, inputs: [ { - key: SystemInputEnum.switch, - type: FlowInputItemTypeEnum.target, - label: '输入' + key: 'systemPrompt', + type: FlowInputItemTypeEnum.textarea, + label: '系统提示词', + description: + '你可以添加一些特定内容的介绍,从而更好的识别用户的问题类型。这个内容通常是给模型介绍一个它不知道的内容。', + placeholder: '例如: \n1. Laf 是一个云函数开发平台……\n2. Sealos 是一个集群操作系统', + value: '' + }, + Input_Template_History, + Input_Template_UserChatInput, + { + key: 'agents', + type: FlowInputItemTypeEnum.custom, + label: '', + value: [ + { + value: '', + key: 'a' + }, + { + value: '', + key: 'b' + } + ] } ], outputs: [ { - key: 'true', - label: 'True', - type: FlowOutputItemTypeEnum.source, + key: 'a', + label: '', + type: FlowOutputItemTypeEnum.hidden, targets: [] }, { - key: 'false', - label: 'False', - type: FlowOutputItemTypeEnum.source, + key: 'b', + label: '', + type: FlowOutputItemTypeEnum.hidden, targets: [] } ] @@ -302,7 +323,7 @@ export const ModuleTemplates = [ }, { label: '工具', - list: [AnswerModule, TFSwitchModule] + list: [AnswerModule] }, { label: 'Agent', diff --git a/client/src/constants/flow/index.ts b/client/src/constants/flow/index.ts index db6e6c6f8..5184e713f 100644 --- a/client/src/constants/flow/index.ts +++ b/client/src/constants/flow/index.ts @@ -24,7 +24,8 @@ export enum FlowModuleTypeEnum { chatNode = 'chatNode', kbSearchNode = 'kbSearchNode', tfSwitchNode = 'tfSwitchNode', - answerNode = 'answerNode' + answerNode = 'answerNode', + classifyQuestionNode = 'classifyQuestionNode' } export const edgeOptions = { diff --git a/client/src/constants/theme.ts b/client/src/constants/theme.ts index f98ae0026..99c06f554 100644 --- a/client/src/constants/theme.ts +++ b/client/src/constants/theme.ts @@ -202,6 +202,16 @@ const Select = selectMultiStyle({ } }); +const Tooltip = defineStyleConfig({ + baseStyle: { + p: 3, + bg: 'white', + color: 'blackAlpha.800', + borderRadius: '8px', + boxShadow: '1px 1px 10px rgba(0,0,0,0.2)' + } +}); + // 全局主题 export const theme = extendTheme({ styles: { @@ -297,6 +307,7 @@ export const theme = extendTheme({ Textarea, Switch, Select, + Tooltip, NumberInput } }); diff --git a/client/src/pages/api/openapi/modules/agent/classifyQuestion.ts b/client/src/pages/api/openapi/modules/agent/classifyQuestion.ts index 330bb1a30..9c5af1e8b 100644 --- a/client/src/pages/api/openapi/modules/agent/classifyQuestion.ts +++ b/client/src/pages/api/openapi/modules/agent/classifyQuestion.ts @@ -79,7 +79,7 @@ export async function classifyQuestion({ properties: { type: { type: 'string', - description: agents.map((item) => `${item.desc},返回: '${item.key}'`).join('; '), + description: agents.map((item) => `${item.value},返回: '${item.key}'`).join('; '), enum: agents.map((item) => item.key) } }, @@ -106,7 +106,10 @@ export async function classifyQuestion({ if (!arg.type) { throw new Error(''); } - console.log(arg.type); + console.log( + '意图结果', + agents.findIndex((item) => item.key === arg.type) + ); return { [arg.type]: 1 diff --git a/client/src/pages/api/openapi/modules/chat/gpt.ts b/client/src/pages/api/openapi/modules/chat/gpt.ts index eb5ccee70..3cc3eebb8 100644 --- a/client/src/pages/api/openapi/modules/chat/gpt.ts +++ b/client/src/pages/api/openapi/modules/chat/gpt.ts @@ -10,6 +10,7 @@ import type { ChatItemType } from '@/types/chat'; import { ChatRoleEnum, sseResponseEventEnum } from '@/constants/chat'; import { parseStreamChunk, textAdaptGptResponse } from '@/utils/adapt'; import { getOpenAIApi, axiosConfig } from '@/service/ai/openai'; +import { SpecificInputEnum } from '@/constants/app'; export type Props = { model: `${OpenAiChatEnum}`; @@ -22,7 +23,7 @@ export type Props = { systemPrompt?: string; limitPrompt?: string; }; -export type Response = { answer: string }; +export type Response = { [SpecificInputEnum.answerText]: string }; export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { @@ -132,7 +133,8 @@ export async function chatCompletion({ const chatAPI = getOpenAIApi(); /* count response max token */ - const promptsToken = modelToolMap[model].countTokens({ + const promptsToken = modelToolMap.countTokens({ + model, messages: filterMessages }); maxToken = maxToken + promptsToken > modelTokenLimit ? modelTokenLimit - promptsToken : maxToken; @@ -143,8 +145,8 @@ export async function chatCompletion({ temperature: Number(temperature || 0), max_tokens: maxToken, messages: adaptMessages, - frequency_penalty: 0.5, // 越大,重复内容越少 - presence_penalty: -0.5, // 越大,越容易出现新内容 + // frequency_penalty: 0.5, // 越大,重复内容越少 + // presence_penalty: -0.5, // 越大,越容易出现新内容 stream }, { @@ -184,7 +186,7 @@ export async function chatCompletion({ })(); return { - answer + answerText: answer }; } diff --git a/client/src/pages/api/openapi/modules/kb/search.ts b/client/src/pages/api/openapi/modules/kb/search.ts index 983fa5758..21ed9cf5f 100644 --- a/client/src/pages/api/openapi/modules/kb/search.ts +++ b/client/src/pages/api/openapi/modules/kb/search.ts @@ -92,8 +92,9 @@ export async function kbSearch({ const searchRes: QuoteItemType[] = res?.[2]?.rows || []; // filter part quote by maxToken - const sliceResult = modelToolMap['gpt-3.5-turbo'] + const sliceResult = modelToolMap .tokenSlice({ + model: 'gpt-3.5-turbo', maxToken, messages: searchRes.map((item, i) => ({ obj: ChatRoleEnum.System, diff --git a/client/src/pages/api/openapi/v1/chat/completions2.ts b/client/src/pages/api/openapi/v1/chat/completions2.ts index 37a7daabb..e6b3703f5 100644 --- a/client/src/pages/api/openapi/v1/chat/completions2.ts +++ b/client/src/pages/api/openapi/v1/chat/completions2.ts @@ -10,12 +10,7 @@ import { getChatHistory } from './getHistory'; import { saveChat } from '@/pages/api/chat/saveChat'; import { sseResponse } from '@/service/utils/tools'; import { type ChatCompletionRequestMessage } from 'openai'; -import { - kbChatAppDemo, - chatAppDemo, - SpecificInputEnum, - AppModuleItemTypeEnum -} from '@/constants/app'; +import { SpecificInputEnum, AppModuleItemTypeEnum } from '@/constants/app'; import { model, Types } from 'mongoose'; import { moduleFetch } from '@/service/api/request'; import { AppModuleItemType, RunningModuleItemType } from '@/types/app'; @@ -42,7 +37,6 @@ export type ChatResponseType = { quoteLen?: number; }; -/* 发送提示词 */ export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse) { res.on('close', () => { res.end(); @@ -117,7 +111,6 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex }, stream }); - console.log(responseData, answerText); // save chat if (typeof chatId === 'string') { @@ -354,7 +347,7 @@ function loadModules(modules: AppModuleItemType[]): RunningModuleItemType[] { })), outputs: module.outputs.map((item) => ({ key: item.key, - answer: item.type === FlowOutputItemTypeEnum.answer, + answer: item.key === SpecificInputEnum.answerText, response: item.response, value: undefined, targets: item.targets diff --git a/client/src/pages/app/detail/components/Kb.tsx b/client/src/pages/app/detail/components/Kb.tsx deleted file mode 100644 index af27644f8..000000000 --- a/client/src/pages/app/detail/components/Kb.tsx +++ /dev/null @@ -1,394 +0,0 @@ -import React, { useState, useCallback } from 'react'; -import { useRouter } from 'next/router'; -import { - Card, - Flex, - Box, - Button, - useDisclosure, - Modal, - ModalOverlay, - ModalContent, - ModalBody, - ModalHeader, - ModalFooter, - ModalCloseButton, - Grid, - useTheme, - IconButton, - Tooltip, - Textarea -} from '@chakra-ui/react'; -import { useUserStore } from '@/store/user'; -import { useQuery } from '@tanstack/react-query'; -import Avatar from '@/components/Avatar'; -import { AddIcon, DeleteIcon, QuestionOutlineIcon } from '@chakra-ui/icons'; -import { putAppById } from '@/api/app'; -import { useToast } from '@/hooks/useToast'; -import { useLoading } from '@/hooks/useLoading'; -import { useForm } from 'react-hook-form'; -import MyIcon from '@/components/Icon'; -import MySlider from '@/components/Slider'; - -const Kb = ({ modelId }: { modelId: string }) => { - const theme = useTheme(); - const router = useRouter(); - const { toast } = useToast(); - const { appDetail, loadKbList, loadAppDetail } = useUserStore(); - const { Loading, setIsLoading } = useLoading(); - const [selectedIdList, setSelectedIdList] = useState([]); - const [refresh, setRefresh] = useState(false); - const { register, reset, getValues, setValue } = useForm({ - defaultValues: { - searchSimilarity: appDetail.chat.searchSimilarity, - searchLimit: appDetail.chat.searchLimit, - searchEmptyText: appDetail.chat.searchEmptyText - } - }); - - const { - isOpen: isOpenKbSelect, - onOpen: onOpenKbSelect, - onClose: onCloseKbSelect - } = useDisclosure(); - const { - isOpen: isOpenEditParams, - onOpen: onOpenEditParams, - onClose: onCloseEditParams - } = useDisclosure(); - - const onchangeKb = useCallback( - async ( - data: { - relatedKbs?: string[]; - searchSimilarity?: number; - searchLimit?: number; - searchEmptyText?: string; - } = {} - ) => { - setIsLoading(true); - try { - await putAppById(modelId, { - chat: { - ...appDetail.chat, - ...data - } - }); - loadAppDetail(modelId, true); - } catch (err: any) { - toast({ - title: err?.message || '更新失败', - status: 'error' - }); - } - setIsLoading(false); - }, - [setIsLoading, modelId, appDetail.chat, loadAppDetail, toast] - ); - - // init kb select list - const { isLoading, data: kbList = [] } = useQuery(['loadKbList'], () => loadKbList()); - - return ( - - 关联的知识库({appDetail.chat?.relatedKbs.length}) - {(() => { - const kbs = - appDetail.chat?.relatedKbs - ?.map((id) => kbList.find((kb) => kb._id === id)) - .filter((item) => item) || []; - return ( - - { - reset({ - searchSimilarity: appDetail.chat.searchSimilarity, - searchLimit: appDetail.chat.searchLimit, - searchEmptyText: appDetail.chat.searchEmptyText - }); - onOpenEditParams(); - }} - > - - } - aria-label={''} - variant={'base'} - /> - 调整搜索参数 - - - 相似度: {appDetail.chat.searchSimilarity}, 单次搜索数量:{' '} - {appDetail.chat.searchLimit}, 空搜索时拒绝回复:{' '} - {appDetail.chat.searchEmptyText !== '' ? 'true' : 'false'} - - - { - setSelectedIdList( - appDetail.chat?.relatedKbs ? [...appDetail.chat?.relatedKbs] : [] - ); - onOpenKbSelect(); - }} - > - - } - aria-label={''} - variant={'base'} - /> - 选择关联知识库 - - - 关联知识库,让 AI 应用回答你的特有内容。 - - - {kbs.map((item) => - item ? ( - - - - - {item.name} - - - - - } - variant={'outline'} - aria-label={'delete'} - size={'sm'} - _hover={{ color: 'red.600' }} - onClick={() => { - const ids = appDetail.chat?.relatedKbs - ? [...appDetail.chat.relatedKbs] - : []; - const i = ids.findIndex((id) => id === item._id); - ids.splice(i, 1); - onchangeKb({ relatedKbs: ids }); - }} - /> - - - ) : null - )} - - ); - })()} - {/* select kb modal */} - - - - 关联的知识库({selectedIdList.length}) - - - {kbList.map((item) => ( - { - let ids = [...selectedIdList]; - if (!selectedIdList.includes(item._id)) { - ids = ids.concat(item._id); - } else { - const i = ids.findIndex((id) => id === item._id); - ids.splice(i, 1); - } - - ids = ids.filter((id) => kbList.find((item) => item._id === id)); - setSelectedIdList(ids); - }} - > - - - - {item.name} - - - - ))} - - - - - - - - {/* edit mode */} - - - - 搜索参数调整 - - - - - 相似度 - - - - - { - setValue('searchSimilarity', val); - setRefresh(!refresh); - }} - /> - - - 单次搜索数量 - - { - setValue('searchLimit', val); - setRefresh(!refresh); - }} - /> - - - - 空搜索回复 - - - - - - - - - - - - - - ); -}; - -export default Kb; diff --git a/client/src/pages/app/detail/components/Share.tsx b/client/src/pages/app/detail/components/Share.tsx index ada868683..112e706c4 100644 --- a/client/src/pages/app/detail/components/Share.tsx +++ b/client/src/pages/app/detail/components/Share.tsx @@ -2,7 +2,6 @@ import React, { useCallback, useState } from 'react'; import { Flex, Box, - Tooltip, Button, TableContainer, Table, @@ -37,6 +36,7 @@ import { formatTimeToChatTime, useCopyData, getErrText } from '@/utils/tools'; import { useForm } from 'react-hook-form'; import { defaultShareChat } from '@/constants/model'; import type { ShareChatEditType } from '@/types/app'; +import MyTooltip from '@/components/MyTooltip'; const Share = ({ modelId }: { modelId: string }) => { const { toast } = useToast(); @@ -112,9 +112,9 @@ ${e.password ? `密码为: ${e.password}` : ''}`; 免登录聊天窗口 - + - + + + ) + }} + /> + + + ); +}; +export default React.memo(NodeCQNode); diff --git a/client/src/pages/app/detail/components/edit/components/NodeKbSearch.tsx b/client/src/pages/app/detail/components/edit/components/NodeKbSearch.tsx index fd1de5b5d..23e720aa5 100644 --- a/client/src/pages/app/detail/components/edit/components/NodeKbSearch.tsx +++ b/client/src/pages/app/detail/components/edit/components/NodeKbSearch.tsx @@ -26,7 +26,7 @@ const NodeKbSearch = ({ onChangeNode={onChangeNode} flowInputList={inputs} CustomComponent={{ - kb_ids: ({ key, value, onChangeNode }) => ( + kb_ids: ({ key, value }) => ( { diff --git a/client/src/pages/app/detail/components/edit/components/TemplateList.tsx b/client/src/pages/app/detail/components/edit/components/TemplateList.tsx index ae93b095a..11dd2ce8b 100644 --- a/client/src/pages/app/detail/components/edit/components/TemplateList.tsx +++ b/client/src/pages/app/detail/components/edit/components/TemplateList.tsx @@ -1,5 +1,5 @@ -import React from 'react'; -import { Box, Flex } from '@chakra-ui/react'; +import React, { useRef } from 'react'; +import { Box, Flex, useOutsideClick } from '@chakra-ui/react'; import { ModuleTemplates } from '@/constants/flow/ModuleTemplate'; import type { AppModuleTemplateItemType } from '@/types/app'; import type { XYPosition } from 'reactflow'; @@ -7,62 +7,85 @@ import Avatar from '@/components/Avatar'; const ModuleStoreList = ({ isOpen, - onAddNode + onAddNode, + onClose }: { isOpen: boolean; onAddNode: (e: { template: AppModuleTemplateItemType; position: XYPosition }) => void; + onClose: () => void; }) => { + const ContextMenuRef = useRef(null); + + useOutsideClick({ + ref: ContextMenuRef, + handler: () => { + onClose(); + } + }); + return ( - - - 添加模块 - - - {ModuleTemplates.map((item) => - item.list.map((item) => ( - { - if (e.clientX < 400) return; - onAddNode({ - template: item, - position: { x: e.clientX, y: e.clientY } - }); - }} - > - - - {item.name} - - {item.intro} + <> + + + + 添加模块 + + + {ModuleTemplates.map((item) => + item.list.map((item) => ( + { + // if (e.clientX < 400) return; + onAddNode({ + template: item, + position: { x: e.clientX, y: e.clientY } + }); + }} + > + + + {item.name} + + {item.intro} + - - - )) - )} - - + + )) + )} + + + ); }; diff --git a/client/src/pages/app/detail/components/edit/components/modules/Label.tsx b/client/src/pages/app/detail/components/edit/components/modules/Label.tsx index f46d7f1a8..043af54f6 100644 --- a/client/src/pages/app/detail/components/edit/components/modules/Label.tsx +++ b/client/src/pages/app/detail/components/edit/components/modules/Label.tsx @@ -1,6 +1,7 @@ import React from 'react'; -import { Box, Tooltip } from '@chakra-ui/react'; +import { Box } from '@chakra-ui/react'; import { QuestionOutlineIcon } from '@chakra-ui/icons'; +import MyTooltip from '@/components/MyTooltip'; const Label = ({ required = false, @@ -19,9 +20,9 @@ const Label = ({ )} {description && ( - + - + )} ); diff --git a/client/src/pages/app/detail/components/edit/components/render/RenderInput.tsx b/client/src/pages/app/detail/components/edit/components/render/RenderInput.tsx index 0095f3c58..81635078a 100644 --- a/client/src/pages/app/detail/components/edit/components/render/RenderInput.tsx +++ b/client/src/pages/app/detail/components/edit/components/render/RenderInput.tsx @@ -4,7 +4,6 @@ import { Box, Textarea, Input, - Tooltip, NumberInput, NumberInputField, NumberInputStepper, @@ -16,6 +15,7 @@ import { QuestionOutlineIcon } from '@chakra-ui/icons'; import { Handle, Position } from 'reactflow'; import MySelect from '@/components/Select'; import MySlider from '@/components/Slider'; +import MyTooltip from '@/components/MyTooltip'; const Label = ({ required = false, @@ -34,9 +34,9 @@ const Label = ({ )} {description && ( - + - + )} ); @@ -49,14 +49,7 @@ const RenderBody = ({ }: { flowInputList: FlowInputItemType[]; moduleId: string; - CustomComponent?: Record< - string, - (e: { - key: string; - value: any; - onChangeNode: FlowModuleItemType['onChangeNode']; - }) => React.ReactNode - >; + CustomComponent?: Record React.ReactNode>; onChangeNode: FlowModuleItemType['onChangeNode']; }) => { return ( @@ -65,9 +58,11 @@ const RenderBody = ({ (item) => item.type !== FlowInputItemTypeEnum.hidden && ( - + {!!item.label && ( + + )} {item.type === FlowInputItemTypeEnum.numberInput && ( )} {item.type === FlowInputItemTypeEnum.custom && CustomComponent[item.key] && ( - <> - {CustomComponent[item.key]({ key: item.key, value: item.value, onChangeNode })} - + <>{CustomComponent[item.key]({ ...item })} )} {item.type === FlowInputItemTypeEnum.target && ( ( {description && ( - + - + )} {children} diff --git a/client/src/pages/app/detail/components/edit/index.tsx b/client/src/pages/app/detail/components/edit/index.tsx index 15d6de586..b8a1b2897 100644 --- a/client/src/pages/app/detail/components/edit/index.tsx +++ b/client/src/pages/app/detail/components/edit/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from 'react'; +import React, { useCallback, useEffect, useRef } from 'react'; import ReactFlow, { Background, Controls, @@ -7,7 +7,8 @@ import ReactFlow, { useNodesState, useEdgesState, XYPosition, - Connection + Connection, + useViewport } from 'reactflow'; import { Box, Flex, IconButton, useTheme, useDisclosure } from '@chakra-ui/react'; import { SmallCloseIcon } from '@chakra-ui/icons'; @@ -47,6 +48,9 @@ const NodeQuestionInput = dynamic(() => import('./components/NodeQuestionInput') const TemplateList = dynamic(() => import('./components/TemplateList'), { ssr: false }); +const NodeCQNode = dynamic(() => import('./components/NodeCQNode'), { + ssr: false +}); import 'reactflow/dist/style.css'; import styles from './index.module.scss'; @@ -60,14 +64,18 @@ const nodeTypes = { [FlowModuleTypeEnum.chatNode]: NodeChat, [FlowModuleTypeEnum.kbSearchNode]: NodeKbSearch, [FlowModuleTypeEnum.tfSwitchNode]: NodeTFSwitch, - [FlowModuleTypeEnum.answerNode]: NodeAnswer + [FlowModuleTypeEnum.answerNode]: NodeAnswer, + [FlowModuleTypeEnum.classifyQuestionNode]: NodeCQNode }; const edgeTypes = { buttonedge: ButtonEdge }; +type Props = { app: AppSchema; onBack: () => void }; -const AppEdit = ({ app, onBack }: { app: AppSchema; onBack: () => void }) => { +const AppEdit = ({ app, onBack }: Props) => { + const reactFlowWrapper = useRef(null); const theme = useTheme(); + const { x, y, zoom } = useViewport(); const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); const { @@ -77,24 +85,33 @@ const AppEdit = ({ app, onBack }: { app: AppSchema; onBack: () => void }) => { } = useDisclosure(); const onChangeNode = useCallback( - ({ moduleId, key, value, valueKey = 'value' }: FlowModuleItemChangeProps) => { + ({ moduleId, key, type = 'inputs', value, valueKey = 'value' }: FlowModuleItemChangeProps) => { setNodes((nodes) => nodes.map((node) => { if (node.id !== moduleId) return node; + if (type === 'inputs') { + return { + ...node, + data: { + ...node.data, + inputs: node.data.inputs.map((item) => { + if (item.key === key) { + return { + ...item, + [valueKey]: value + }; + } + return item; + }) + } + }; + } return { ...node, data: { ...node.data, - inputs: node.data.inputs.map((item) => { - if (item.key === key) { - return { - ...item, - [valueKey]: value - }; - } - return item; - }) + outputs: value } }; }) @@ -111,12 +128,17 @@ const AppEdit = ({ app, onBack }: { app: AppSchema; onBack: () => void }) => { ); const onAddNode = useCallback( ({ template, position }: { template: AppModuleTemplateItemType; position: XYPosition }) => { + if (!reactFlowWrapper.current) return; + const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect(); + const mouseX = (position.x - reactFlowBounds.left - x) / zoom - 100; + const mouseY = (position.y - reactFlowBounds.top - y) / zoom; + setNodes((state) => state.concat( appModule2FlowNode({ item: { ...template, - position, + position: { x: mouseX, y: mouseY }, moduleId: nanoid() }, onChangeNode, @@ -125,7 +147,7 @@ const AppEdit = ({ app, onBack }: { app: AppSchema; onBack: () => void }) => { ) ); }, - [onChangeNode, onDelNode, setNodes] + [onChangeNode, onDelNode, setNodes, x, y, zoom] ); const onDelConnect = useCallback( @@ -245,6 +267,13 @@ const AppEdit = ({ app, onBack }: { app: AppSchema; onBack: () => void }) => { borderRadius={'lg'} isLoading={isLoading} aria-label={'save'} + bg={'myBlue.200'} + variant={'base'} + border={'none'} + color={'myGray.900'} + _hover={{ + bg: 'myBlue.300' + }} onClick={onclickSave} /> @@ -270,43 +299,50 @@ const AppEdit = ({ app, onBack }: { app: AppSchema; onBack: () => void }) => { transition={'0.2s ease'} aria-label={''} zIndex={1} - boxShadow={'1px 1px 6px #4e83fd'} - onClick={() => (isOpenTemplate ? onCloseTemplate() : onOpenTemplate())} + boxShadow={'2px 2px 6px #85b1ff'} + onClick={() => { + isOpenTemplate ? onCloseTemplate() : onOpenTemplate(); + }} /> - - { - connect.sourceHandle && - connect.targetHandle && - onConnect({ - connect - }); - }} - > - - - - - + { + connect.sourceHandle && + connect.targetHandle && + onConnect({ + connect + }); + }} + > + + + + ); }; -export default AppEdit; +const Flow = (data: Props) => ( + + + +); + +export default Flow; diff --git a/client/src/pages/app/list/component/CreateModal.tsx b/client/src/pages/app/list/component/CreateModal.tsx index 79750916a..3570569d5 100644 --- a/client/src/pages/app/list/component/CreateModal.tsx +++ b/client/src/pages/app/list/component/CreateModal.tsx @@ -173,7 +173,7 @@ const CreateModal = ({ onClose, onSuccess }: { onClose: () => void; onSuccess: ( boxShadow={'sm'} {...(getValues('templateId') === item.id ? { - bg: 'myBlue.300' + bg: 'myWhite.600' } : { _hover: { diff --git a/client/src/pages/app/list/index.tsx b/client/src/pages/app/list/index.tsx index 22b0fd5b9..69964c6e7 100644 --- a/client/src/pages/app/list/index.tsx +++ b/client/src/pages/app/list/index.tsx @@ -120,7 +120,13 @@ const MyApps = () => { }} /> - + {app.intro || '这个应用还没写介绍~'} diff --git a/client/src/pages/appStore/components/list.tsx b/client/src/pages/appStore/components/list.tsx index f7e118bd3..ee42104bc 100644 --- a/client/src/pages/appStore/components/list.tsx +++ b/client/src/pages/appStore/components/list.tsx @@ -1,10 +1,11 @@ import React from 'react'; -import { Box, Flex, Button, Tooltip, Card } from '@chakra-ui/react'; +import { Box, Flex, Button, Card } from '@chakra-ui/react'; import type { ShareAppItem } from '@/types/app'; import { useRouter } from 'next/router'; import MyIcon from '@/components/Icon'; import styles from '../index.module.scss'; import Avatar from '@/components/Avatar'; +import MyTooltip from '@/components/MyTooltip'; const ShareModelList = ({ models = [], @@ -44,7 +45,7 @@ const ShareModelList = ({ {model.name} - + {model.intro || '这个应用还没有介绍~'} - + await import('@/components/Markdown')); const PhoneSliderBar = dynamic(() => import('./components/PhoneSliderBar'), { @@ -701,7 +701,7 @@ const Chat = () => { {item.obj === 'Human' && } {/* avatar */}

- + { h={['20px', '34px']} /> - + {!isPc && } {/* message */} diff --git a/client/src/pages/chat/share.tsx b/client/src/pages/chat/share.tsx index 10b89cf33..5ec1f2a9e 100644 --- a/client/src/pages/chat/share.tsx +++ b/client/src/pages/chat/share.tsx @@ -22,7 +22,6 @@ import { DrawerOverlay, DrawerContent, Card, - Tooltip, useOutsideClick, useTheme, Input, @@ -49,6 +48,7 @@ import SideBar from '@/components/SideBar'; import Avatar from '@/components/Avatar'; import Empty from './components/Empty'; import { HUMAN_ICON } from '@/constants/chat'; +import MyTooltip from '@/components/MyTooltip'; const ShareHistory = dynamic(() => import('./components/ShareHistory'), { loading: () => , @@ -619,7 +619,7 @@ const Chat = () => { {item.obj === 'Human' && } {/* avatar */} - + { h={['20px', '34px']} /> - + {!isPc && } {/* message */} diff --git a/client/src/pages/kb/components/Info.tsx b/client/src/pages/kb/components/Info.tsx index 2cbf399a9..2920464ba 100644 --- a/client/src/pages/kb/components/Info.tsx +++ b/client/src/pages/kb/components/Info.tsx @@ -7,7 +7,7 @@ import React, { ForwardedRef } from 'react'; import { useRouter } from 'next/router'; -import { Box, Flex, Button, FormControl, IconButton, Tooltip, Input, Card } from '@chakra-ui/react'; +import { Box, Flex, Button, FormControl, IconButton, Input, Card } from '@chakra-ui/react'; import { QuestionOutlineIcon, DeleteIcon } from '@chakra-ui/icons'; import { delKbById, putKbById } from '@/api/plugins/kb'; import { useSelectFile } from '@/hooks/useSelectFile'; @@ -19,6 +19,7 @@ import { compressImg } from '@/utils/file'; import type { KbItemType } from '@/types/plugin'; import Avatar from '@/components/Avatar'; import Tag from '@/components/Tag'; +import MyTooltip from '@/components/MyTooltip'; export interface ComponentRef { initInput: (tags: string) => void; @@ -173,9 +174,9 @@ const Info = ( 分类标签 - + - + { const theme = useTheme(); @@ -78,7 +79,7 @@ const KbList = ({ kbId }: { kbId: string }) => { /> )} - + } @@ -86,7 +87,7 @@ const KbList = ({ kbId }: { kbId: string }) => { variant={'base'} onClick={handleCreateModel} /> - + {kbs.map((item) => ( diff --git a/client/src/pages/model/components/detail/components/Settings.tsx b/client/src/pages/model/components/detail/components/Settings.tsx deleted file mode 100644 index ec39c0cdb..000000000 --- a/client/src/pages/model/components/detail/components/Settings.tsx +++ /dev/null @@ -1,388 +0,0 @@ -import React, { useCallback, useState, useMemo } from 'react'; -import { - Box, - Flex, - Button, - FormControl, - Input, - Textarea, - Divider, - Tooltip -} from '@chakra-ui/react'; -import { QuestionOutlineIcon } from '@chakra-ui/icons'; -import { useQuery } from '@tanstack/react-query'; -import { useForm } from 'react-hook-form'; -import { useRouter } from 'next/router'; -import { useUserStore } from '@/store/user'; -import { useToast } from '@/hooks/useToast'; -import { useLoading } from '@/hooks/useLoading'; -import { delModelById, putAppById } from '@/api/app'; -import { useSelectFile } from '@/hooks/useSelectFile'; -import { compressImg } from '@/utils/file'; -import { getErrText } from '@/utils/tools'; -import { useConfirm } from '@/hooks/useConfirm'; -import { ChatModelMap, chatModelList } from '@/constants/model'; -import { formatPrice } from '@/utils/user'; - -import type { AppSchema } from '@/types/mongoSchema'; - -import Avatar from '@/components/Avatar'; -import MySelect from '@/components/Select'; -import MySlider from '@/components/Slider'; - -const systemPromptTip = - '模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。'; -const limitPromptTip = - '限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。例如:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"'; - -const Settings = ({ modelId }: { modelId: string }) => { - const { toast } = useToast(); - const router = useRouter(); - const { Loading, setIsLoading } = useLoading(); - const { userInfo, appDetail, myApps, loadAppDetail, refreshModel, setLastModelId } = - useUserStore(); - const { File, onOpen: onOpenSelectFile } = useSelectFile({ - fileType: '.jpg,.png', - multiple: false - }); - const { openConfirm, ConfirmChild } = useConfirm({ - content: '确认删除该应用?' - }); - - const [btnLoading, setBtnLoading] = useState(false); - const [refresh, setRefresh] = useState(false); - - const { - register, - setValue, - getValues, - formState: { errors }, - reset, - handleSubmit - } = useForm({ - defaultValues: appDetail - }); - - const isOwner = useMemo( - () => appDetail.userId === userInfo?._id, - [appDetail.userId, userInfo?._id] - ); - const tokenLimit = useMemo(() => { - const max = ChatModelMap[getValues('chat.chatModel')]?.contextMaxToken || 4000; - - if (max < getValues('chat.maxToken')) { - setValue('chat.maxToken', max); - } - - return max; - }, [getValues, setValue, refresh]); - - // 提交保存模型修改 - const saveSubmitSuccess = useCallback( - async (data: AppSchema) => { - setBtnLoading(true); - try { - await putAppById(data._id, { - name: data.name, - avatar: data.avatar, - intro: data.intro, - chat: data.chat, - share: data.share - }); - - refreshModel.updateModelDetail(data); - } catch (err: any) { - toast({ - title: err?.message || '更新失败', - status: 'error' - }); - } - setBtnLoading(false); - }, - [refreshModel, toast] - ); - // 提交保存表单失败 - const saveSubmitError = useCallback(() => { - // deep search message - const deepSearch = (obj: any): string => { - if (!obj) return '提交表单错误'; - if (!!obj.message) { - return obj.message; - } - return deepSearch(Object.values(obj)[0]); - }; - toast({ - title: deepSearch(errors), - status: 'error', - duration: 4000, - isClosable: true - }); - }, [errors, toast]); - - const saveUpdateModel = useCallback( - () => handleSubmit(saveSubmitSuccess, saveSubmitError)(), - [handleSubmit, saveSubmitError, saveSubmitSuccess] - ); - - /* 点击删除 */ - const handleDelModel = useCallback(async () => { - if (!appDetail) return; - setIsLoading(true); - try { - await delModelById(appDetail._id); - toast({ - title: '删除成功', - status: 'success' - }); - refreshModel.removeModelDetail(appDetail._id); - router.replace(`/model?modelId=${myApps[1]?._id}`); - } catch (err: any) { - toast({ - title: err?.message || '删除失败', - status: 'error' - }); - } - setIsLoading(false); - }, [appDetail, setIsLoading, toast, refreshModel, router, myApps]); - - const onSelectFile = useCallback( - async (e: File[]) => { - const file = e[0]; - if (!file) return; - try { - const src = await compressImg({ - file, - maxW: 100, - maxH: 100 - }); - setValue('avatar', src); - setRefresh((state) => !state); - } catch (err: any) { - toast({ - title: getErrText(err, '头像选择异常'), - status: 'warning' - }); - } - }, - [setValue, toast] - ); - - // load model data - const { isLoading } = useQuery([modelId], () => loadAppDetail(modelId, true), { - onSuccess(res) { - res && reset(res); - modelId && setLastModelId(modelId); - setRefresh(!refresh); - }, - onError(err: any) { - toast({ - title: err?.message || '获取应用异常', - status: 'error' - }); - setLastModelId(''); - refreshModel.freshMyModels(); - router.replace('/model'); - } - }); - - return ( - - - - 头像 - - isOwner && onOpenSelectFile()} - /> - - - - - 名称 - - - - - - - 介绍 - - - - - - - - - 对话模型 - - ({ - value: item.chatModel, - label: `${item.name} (${formatPrice( - ChatModelMap[item.chatModel]?.price, - 1000 - )} 元/1k tokens)` - }))} - onchange={(val: any) => { - setValue('chat.chatModel', val); - setRefresh(!refresh); - }} - /> - - - - 温度 - - - { - setValue('chat.temperature', val); - setRefresh(!refresh); - }} - /> - - - - - 回复上限 - - - { - setValue('chat.maxToken', val); - setRefresh(!refresh); - }} - /> - - - - - 提示词 - - - - - - - - - 限定词 - - - - - - - - - - - - {isOwner && ( - - )} - - - - - - - ); -}; - -export default Settings; diff --git a/client/src/types/app.d.ts b/client/src/types/app.d.ts index 217c442cd..1a50685f5 100644 --- a/client/src/types/app.d.ts +++ b/client/src/types/app.d.ts @@ -40,7 +40,7 @@ export type ShareChatEditType = { /* agent */ /* question classify */ export type ClassifyQuestionAgentItemType = { - desc: string; + value: string; key: string; }; diff --git a/client/src/types/flow.d.ts b/client/src/types/flow.d.ts index 40631d4a0..99e66540e 100644 --- a/client/src/types/flow.d.ts +++ b/client/src/types/flow.d.ts @@ -37,6 +37,7 @@ export type FlowOutputItemType = { export type FlowModuleItemChangeProps = { moduleId: string; + type?: 'inputs' | 'outputs'; key: string; value: any; valueKey?: keyof FlowInputItemType & keyof FlowBodyItemType; diff --git a/client/src/utils/adapt.ts b/client/src/utils/adapt.ts index 6819e1431..b0ae8d658 100644 --- a/client/src/utils/adapt.ts +++ b/client/src/utils/adapt.ts @@ -109,8 +109,6 @@ export const appModule2FlowEdge = ({ modules: AppModuleItemType[]; onDelete: (id: string) => void; }) => { - console.log(modules); - const edges: Edge[] = []; modules.forEach((module) => module.outputs.forEach((output) => diff --git a/client/src/utils/plugin/index.ts b/client/src/utils/plugin/index.ts index 96153f7d8..d70a066e7 100644 --- a/client/src/utils/plugin/index.ts +++ b/client/src/utils/plugin/index.ts @@ -1,6 +1,3 @@ -import { OpenAiChatEnum } from '@/constants/model'; -import type { ChatModelType } from '@/constants/model'; -import type { ChatItemType } from '@/types/chat'; import { countOpenAIToken, openAiSliceTextByToken } from './openai'; import { gpt_chatItemTokenSlice } from '@/pages/api/openapi/text/gptMessagesSlice';