From 06be57815e94edbae2e01a7312b157f4442ef72a Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Mon, 18 Sep 2023 21:26:42 +0800 Subject: [PATCH] v4.4.3 (#316) --- client/public/locales/en/common.json | 5 + client/public/locales/zh/common.json | 5 + client/src/components/ChatBox/index.tsx | 5 - client/src/components/MyModal/index.tsx | 13 +- client/src/constants/flow/ModuleTemplate.ts | 68 +-- .../src/pages/account/components/PayModal.tsx | 11 +- client/src/pages/api/admin/initv4.ts | 446 ------------------ .../pages/api/openapi/v1/chat/completions.ts | 6 +- .../detail/components/AIChatSettingsModal.tsx | 112 +++++ .../AdEdit/components/Nodes/NodeChat.tsx | 76 ++- .../app/detail/components/BasicEdit/index.tsx | 120 +++-- .../pages/app/detail/components/InfoModal.tsx | 1 - .../pages/app/detail/components/OutLink.tsx | 2 - .../kb/detail/components/InputDataModal.tsx | 5 +- client/src/prompts/core/AIChat.ts | 10 + .../src/service/moduleDispatch/chat/oneapi.ts | 76 ++- client/src/types/core/aiChat.d.ts | 10 + client/src/types/mongoSchema.d.ts | 11 - client/src/utils/app.ts | 43 +- client/src/utils/common/tiktoken/index.ts | 2 +- client/src/utils/common/tools/text.ts | 12 + docSite/assets/jsconfig.json | 4 +- .../docs/installation/upgrading/442.md | 23 + docSite/content/docs/use-cases/prompt.md | 100 ++-- 24 files changed, 459 insertions(+), 707 deletions(-) delete mode 100644 client/src/pages/api/admin/initv4.ts create mode 100644 client/src/pages/app/detail/components/AIChatSettingsModal.tsx create mode 100644 client/src/prompts/core/AIChat.ts create mode 100644 client/src/types/core/aiChat.d.ts create mode 100644 client/src/utils/common/tools/text.ts create mode 100644 docSite/content/docs/installation/upgrading/442.md diff --git a/client/public/locales/en/common.json b/client/public/locales/en/common.json index 9da148367..1e3ee46df 100644 --- a/client/public/locales/en/common.json +++ b/client/public/locales/en/common.json @@ -14,6 +14,7 @@ "UnKnow": "UnKnow", "Warning": "Warning", "app": { + "Quote Prompt Settings": "Quote Prompt Settings", "Advance App TestTip": "The current application is advanced editing mode \n. If you need to switch to [simple mode], please click the save button on the left", "App Detail": "App Detail", "Chat Logs Tips": "Logs record the app's online, shared, and API(chatId is existing) conversations", @@ -219,6 +220,10 @@ "system": { "Help Document": "Document" }, + "template": { + "Quote Content Tip": "This configuration takes effect only when reference content is passed in (knowledge base search). You can customize the structure of the reference content to better fit different scenarios. You can use {{q}}, {{a}}, {{source}} as \"search content\", \"expected content\", and \"source\", they are all optional, and here are the default values: \n{instruction:\"{{q}}\",output:\"{{a}}\"}", + "Quote Prompt Tip": "This configuration takes effect only when reference content is passed in (knowledge base search). \n You can insert references with {{quote}}, here are the default values: \n\"\"\"{{quote}}\"\"\" The three quotes are the knowledge base I gave you, they have the highest priority. instruction is a relevant introduction and output is an expected answer or supplement." + }, "user": { "Account": "Account", "Amount of earnings": "Earnings", diff --git a/client/public/locales/zh/common.json b/client/public/locales/zh/common.json index 3c9b52c6c..eb910068f 100644 --- a/client/public/locales/zh/common.json +++ b/client/public/locales/zh/common.json @@ -14,6 +14,7 @@ "UnKnow": "未知", "Warning": "提示", "app": { + "Quote Prompt Settings": "引用提示词配置", "Advance App TestTip": "当前应用为高级编排模式\n如需切换为【简易模式】请点击左侧保存按键", "App Detail": "应用详情", "Chat Logs Tips": "日志会记录该应用的在线、分享和 API(需填写 chatId) 对话记录", @@ -219,6 +220,10 @@ "system": { "Help Document": "帮助文档" }, + "template": { + "Quote Content Tip": "该配置只有传入引用内容(知识库搜索)时生效。\n可以自定义引用内容的结构,以更好的适配不同场景。可以使用 {{q}}, {{a}}, {{source}} 来作为 “检索内容”、“预期内容”和“来源”,他们都是可选的,下面是默认值:\n{{default}}", + "Quote Prompt Tip": "该配置只有传入引用内容(知识库搜索)时生效。\n可以用 {{quote}} 来插入引用内容,使用 {{question}} 来插入问题。下面是默认值:\n{{default}}" + }, "user": { "Account": "账号", "Amount of earnings": "收益(¥)", diff --git a/client/src/components/ChatBox/index.tsx b/client/src/components/ChatBox/index.tsx index a766a377f..f1fad8a11 100644 --- a/client/src/components/ChatBox/index.tsx +++ b/client/src/components/ChatBox/index.tsx @@ -613,11 +613,6 @@ const ChatBox = ( flexDirection={'column'} alignItems={item.obj === 'Human' ? 'flex-end' : 'flex-start'} py={5} - _hover={{ - '& .control': { - display: item.status === 'finish' ? 'flex' : 'none' - } - }} > {item.obj === 'Human' && ( <> diff --git a/client/src/components/MyModal/index.tsx b/client/src/components/MyModal/index.tsx index 357ef1cc3..0d9cd734a 100644 --- a/client/src/components/MyModal/index.tsx +++ b/client/src/components/MyModal/index.tsx @@ -10,11 +10,10 @@ import { } from '@chakra-ui/react'; interface Props extends ModalContentProps { - showCloseBtn?: boolean; title?: any; isCentered?: boolean; isOpen: boolean; - onClose: () => void; + onClose?: () => void; } const MyModal = ({ @@ -22,14 +21,18 @@ const MyModal = ({ onClose, title, children, - showCloseBtn = true, isCentered, w = 'auto', maxW = ['90vw', '600px'], ...props }: Props) => { return ( - + onClose && onClose()} + autoFocus={false} + isCentered={isCentered} + > {!!title && {title}} - {showCloseBtn && } + {onClose && } {children} diff --git a/client/src/constants/flow/ModuleTemplate.ts b/client/src/constants/flow/ModuleTemplate.ts index baf7c83b2..4d8300fec 100644 --- a/client/src/constants/flow/ModuleTemplate.ts +++ b/client/src/constants/flow/ModuleTemplate.ts @@ -163,19 +163,23 @@ export const ChatModule: FlowModuleTemplateType = { value: '' }, { - key: 'limitPrompt', - type: FlowInputItemTypeEnum.textarea, + key: 'quoteTemplate', + type: FlowInputItemTypeEnum.hidden, + label: '引用内容模板', + valueType: FlowValueTypeEnum.string, + value: '' + }, + { + key: 'quotePrompt', + type: FlowInputItemTypeEnum.hidden, + label: '引用内容提示词', valueType: FlowValueTypeEnum.string, - label: '限定词', - max: 500, - description: ChatModelLimitTip, - placeholder: ChatModelLimitTip, value: '' }, Input_Template_TFSwitch, { key: 'quoteQA', - type: FlowInputItemTypeEnum.target, + type: FlowInputItemTypeEnum.custom, label: '引用内容', description: "对象数组格式,结构:\n [{q:'问题',a:'回答'}]", valueType: FlowValueTypeEnum.kbQuote @@ -664,19 +668,6 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = value: '', connected: true }, - { - key: 'limitPrompt', - type: 'textarea', - valueType: 'string', - label: '限定词', - max: 500, - description: - '限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"', - placeholder: - '限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"', - value: '', - connected: true - }, { key: 'switch', type: 'target', @@ -1013,18 +1004,6 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = value: '', connected: true }, - { - key: 'limitPrompt', - type: 'textarea', - valueType: 'string', - label: '限定词', - description: - '限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"', - placeholder: - '限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"', - value: '', - connected: true - }, { key: 'switch', type: 'target', @@ -1319,18 +1298,6 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = value: '', connected: true }, - { - key: 'limitPrompt', - type: 'textarea', - valueType: 'string', - label: '限定词', - description: - '限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"', - placeholder: - '限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"', - value: '将我的问题直接翻译成英语{{language}}', - connected: true - }, { key: 'switch', type: 'target', @@ -1703,19 +1670,6 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = value: '知识库是关于 laf 的内容。', connected: true }, - { - key: 'limitPrompt', - type: 'textarea', - valueType: 'string', - label: '限定词', - description: - '限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"', - placeholder: - '限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"', - value: - '我的问题都是关于 laf 的。根据知识库回答我的问题,与 laf 无关问题,直接回复:“我不清楚,我仅能回答 laf 相关的问题。”。', - connected: true - }, { key: 'switch', type: 'target', diff --git a/client/src/pages/account/components/PayModal.tsx b/client/src/pages/account/components/PayModal.tsx index 9579731fb..30765a562 100644 --- a/client/src/pages/account/components/PayModal.tsx +++ b/client/src/pages/account/components/PayModal.tsx @@ -64,16 +64,7 @@ const PayModal = ({ onClose }: { onClose: () => void }) => { ); return ( - { - if (payId) return; - onClose(); - }} - title={t('user.Pay')} - isCentered - showCloseBtn={!payId} - > + {!payId && ( <> diff --git a/client/src/pages/api/admin/initv4.ts b/client/src/pages/api/admin/initv4.ts deleted file mode 100644 index a4cdd155f..000000000 --- a/client/src/pages/api/admin/initv4.ts +++ /dev/null @@ -1,446 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from 'next'; -import { jsonRes } from '@/service/response'; -import { authUser } from '@/service/utils/auth'; -import { connectToDatabase, App } from '@/service/mongo'; -import { FlowModuleTypeEnum, SpecialInputKeyEnum } from '@/constants/flow'; -import { TaskResponseKeyEnum } from '@/constants/chat'; -import { FlowInputItemType } from '@/types/flow'; - -const chatModelInput = ({ - model, - temperature, - maxToken, - systemPrompt, - limitPrompt, - kbList -}: { - model: string; - temperature: number; - maxToken: number; - systemPrompt: string; - limitPrompt: string; - kbList: { kbId: string }[]; -}): FlowInputItemType[] => [ - { - key: 'model', - value: model, - type: 'custom', - label: '对话模型', - connected: true - }, - { - key: 'temperature', - value: temperature, - label: '温度', - type: 'slider', - connected: true - }, - { - key: 'maxToken', - value: maxToken, - type: 'custom', - label: '回复上限', - connected: true - }, - { - key: 'systemPrompt', - value: systemPrompt, - type: 'textarea', - label: '系统提示词', - connected: true - }, - { - key: 'limitPrompt', - label: '限定词', - type: 'textarea', - value: limitPrompt, - connected: true - }, - { - key: 'switch', - type: 'target', - label: '触发器', - connected: kbList.length > 0 - }, - { - key: 'quoteQA', - type: 'target', - label: '引用内容', - connected: kbList.length > 0 - }, - { - key: 'history', - type: 'target', - label: '聊天记录', - connected: true - }, - { - key: 'userChatInput', - type: 'target', - label: '用户问题', - connected: true - } -]; -const chatTemplate = ({ - model, - temperature, - maxToken, - systemPrompt, - limitPrompt -}: { - model: string; - temperature: number; - maxToken: number; - systemPrompt: string; - limitPrompt: string; -}) => { - return [ - { - flowType: FlowModuleTypeEnum.questionInput, - inputs: [ - { - key: 'userChatInput', - connected: true - } - ], - outputs: [ - { - key: 'userChatInput', - targets: [ - { - moduleId: 'chatModule', - key: 'userChatInput' - } - ] - } - ], - position: { - x: 464.32198615344566, - y: 1602.2698463081606 - }, - moduleId: 'userChatInput' - }, - { - flowType: FlowModuleTypeEnum.historyNode, - inputs: [ - { - key: 'maxContext', - value: 10, - connected: true - }, - { - key: 'history', - connected: true - } - ], - outputs: [ - { - key: 'history', - targets: [ - { - moduleId: 'chatModule', - key: 'history' - } - ] - } - ], - position: { - x: 452.5466249541586, - y: 1276.3930310334215 - }, - moduleId: 'history' - }, - { - flowType: FlowModuleTypeEnum.chatNode, - inputs: chatModelInput({ - model, - temperature, - maxToken, - systemPrompt, - limitPrompt, - kbList: [] - }), - outputs: [ - { - key: TaskResponseKeyEnum.answerText, - targets: [] - } - ], - position: { - x: 981.9682828103937, - y: 890.014595014464 - }, - moduleId: 'chatModule' - } - ]; -}; -const kbTemplate = ({ - model, - temperature, - maxToken, - systemPrompt, - limitPrompt, - kbList = [], - searchSimilarity, - searchLimit, - searchEmptyText -}: { - model: string; - temperature: number; - maxToken: number; - systemPrompt: string; - limitPrompt: string; - kbList: { kbId: string }[]; - searchSimilarity: number; - searchLimit: number; - searchEmptyText: string; -}) => { - return [ - { - flowType: FlowModuleTypeEnum.questionInput, - inputs: [ - { - key: 'userChatInput', - connected: true - } - ], - outputs: [ - { - key: 'userChatInput', - targets: [ - { - moduleId: 'chatModule', - key: 'userChatInput' - }, - { - moduleId: 'kbSearch', - key: 'userChatInput' - } - ] - } - ], - position: { - x: 464.32198615344566, - y: 1602.2698463081606 - }, - moduleId: 'userChatInput' - }, - { - flowType: FlowModuleTypeEnum.historyNode, - inputs: [ - { - key: 'maxContext', - value: 10, - connected: true - }, - { - key: 'history', - connected: true - } - ], - outputs: [ - { - key: 'history', - targets: [ - { - moduleId: 'chatModule', - key: 'history' - } - ] - } - ], - position: { - x: 452.5466249541586, - y: 1276.3930310334215 - }, - moduleId: 'history' - }, - { - flowType: FlowModuleTypeEnum.kbSearchNode, - inputs: [ - { - key: 'kbList', - value: kbList, - connected: true - }, - { - key: 'similarity', - value: searchSimilarity, - connected: true - }, - { - key: 'limit', - value: searchLimit, - connected: true - }, - { - key: 'switch', - connected: false - }, - { - key: 'userChatInput', - connected: true - } - ], - outputs: [ - { - key: 'isEmpty', - targets: searchEmptyText - ? [ - { - moduleId: 'emptyText', - key: 'switch' - } - ] - : [ - { - moduleId: 'chatModule', - key: 'switch' - } - ] - }, - { - key: 'unEmpty', - targets: [ - { - moduleId: 'chatModule', - key: 'switch' - } - ] - }, - { - key: 'quoteQA', - targets: [ - { - moduleId: 'chatModule', - key: 'quoteQA' - } - ] - } - ], - position: { - x: 956.0838440206068, - y: 887.462827870246 - }, - moduleId: 'kbSearch' - }, - ...(searchEmptyText - ? [ - { - flowType: FlowModuleTypeEnum.answerNode, - inputs: [ - { - key: 'switch', - connected: true - }, - { - key: SpecialInputKeyEnum.answerText, - value: searchEmptyText, - connected: true - } - ], - outputs: [], - position: { - x: 1553.5815811529146, - y: 637.8753731306779 - }, - moduleId: 'emptyText' - } - ] - : []), - { - flowType: FlowModuleTypeEnum.chatNode, - inputs: chatModelInput({ model, temperature, maxToken, systemPrompt, limitPrompt, kbList }), - outputs: [ - { - key: TaskResponseKeyEnum.answerText, - targets: [] - } - ], - position: { - x: 1551.71405495818, - y: 977.4911578918461 - }, - moduleId: 'chatModule' - } - ]; -}; - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - await authUser({ req, authRoot: true }); - await connectToDatabase(); - - const { limit = 1000 } = req.body as { limit: number }; - let skip = 0; - const total = await App.countDocuments(); - let promise = Promise.resolve(); - console.log(total); - - for (let i = 0; i < total; i += limit) { - const skipVal = skip; - skip += limit; - promise = promise - .then(() => init(limit, skipVal)) - .then(() => { - console.log(skipVal); - }); - } - - await promise; - - jsonRes(res, {}); - } catch (error) { - jsonRes(res, { - code: 500, - error - }); - } -} - -async function init(limit: number, skip: number) { - // 遍历 app - const apps = await App.find( - { - chat: { $ne: null }, - modules: { $exists: false } - // userId: '63f9a14228d2a688d8dc9e1b' - }, - '_id chat' - ).limit(limit); - - return Promise.all( - apps.map(async (app) => { - if (!app.chat) return app; - const modules = (() => { - if (app.chat.relatedKbs.length === 0) { - return chatTemplate({ - model: app.chat.chatModel, - temperature: app.chat.temperature, - maxToken: app.chat.maxToken, - systemPrompt: app.chat.systemPrompt, - limitPrompt: app.chat.limitPrompt - }); - } else { - return kbTemplate({ - model: app.chat.chatModel, - temperature: app.chat.temperature, - maxToken: app.chat.maxToken, - systemPrompt: app.chat.systemPrompt, - limitPrompt: app.chat.limitPrompt, - kbList: app.chat.relatedKbs.map((id) => ({ kbId: id })), - searchEmptyText: app.chat.searchEmptyText, - searchLimit: app.chat.searchLimit, - searchSimilarity: app.chat.searchSimilarity - }); - } - })(); - - await App.findByIdAndUpdate(app.id, { - modules - }); - return modules; - }) - ); -} diff --git a/client/src/pages/api/openapi/v1/chat/completions.ts b/client/src/pages/api/openapi/v1/chat/completions.ts index c56a7b44f..eeb84f0cf 100644 --- a/client/src/pages/api/openapi/v1/chat/completions.ts +++ b/client/src/pages/api/openapi/v1/chat/completions.ts @@ -31,6 +31,7 @@ import { SystemInputEnum } from '@/constants/app'; import { getSystemTime } from '@/utils/user'; import { authOutLinkChat } from '@/service/support/outLink/auth'; import requestIp from 'request-ip'; +import { replaceVariable } from '@/utils/common/tools/text'; export type MessageItemType = ChatCompletionRequestMessage & { dataId?: string }; type FastGptWebChatProps = { @@ -424,10 +425,7 @@ function loadModules( } // variables replace - const replacedVal = item.value.replace( - /{{(.*?)}}/g, - (match, key) => variables[key.trim()] || match - ); + const replacedVal = replaceVariable(item.value, variables); return { key: item.key, diff --git a/client/src/pages/app/detail/components/AIChatSettingsModal.tsx b/client/src/pages/app/detail/components/AIChatSettingsModal.tsx new file mode 100644 index 000000000..859fdd1fe --- /dev/null +++ b/client/src/pages/app/detail/components/AIChatSettingsModal.tsx @@ -0,0 +1,112 @@ +import React from 'react'; +import MyModal from '@/components/MyModal'; +import { useTranslation } from 'react-i18next'; +import { EditFormType } from '@/utils/app'; +import { useForm } from 'react-hook-form'; +import { + Box, + BoxProps, + Button, + Flex, + Link, + ModalBody, + ModalFooter, + Textarea +} from '@chakra-ui/react'; +import MyTooltip from '@/components/MyTooltip'; +import { QuestionOutlineIcon } from '@chakra-ui/icons'; +import { defaultQuotePrompt, defaultQuoteTemplate } from '@/prompts/core/AIChat'; +import { feConfigs } from '@/store/static'; + +const AIChatSettingsModal = ({ + onClose, + onSuccess, + defaultData +}: { + onClose: () => void; + onSuccess: (e: EditFormType['chatModel']) => void; + defaultData: EditFormType['chatModel']; +}) => { + const { t } = useTranslation(); + + const { register, handleSubmit } = useForm({ + defaultValues: defaultData + }); + + const LabelStyles: BoxProps = { + fontWeight: 'bold', + mb: 1, + fontSize: ['sm', 'md'] + }; + + return ( + + {t('app.Quote Prompt Settings')} + {feConfigs?.show_doc && ( + + 查看说明 + + )} + + } + w={'700px'} + > + + + + 引用内容模板 + + + + + - - - 限定词 - - - - - - {/* kb */} @@ -483,6 +485,10 @@ const Settings = ({ appId }: { appId: string }) => { 参数 + + + 提示词 + 相似度: {getValues('kb.searchSimilarity')}, 单次搜索数量: {getValues('kb.searchLimit')}, @@ -548,6 +554,16 @@ const Settings = ({ appId }: { appId: string }) => { }} /> )} + {isOpenAIChatSetting && ( + { + setValue('chatModel', e); + onCloseAIChatSetting(); + }} + defaultData={getValues('chatModel')} + /> + )} {isOpenKbSelect && ( ({ diff --git a/client/src/pages/app/detail/components/InfoModal.tsx b/client/src/pages/app/detail/components/InfoModal.tsx index c86686900..5e87b53dd 100644 --- a/client/src/pages/app/detail/components/InfoModal.tsx +++ b/client/src/pages/app/detail/components/InfoModal.tsx @@ -55,7 +55,6 @@ const InfoModal = ({ name: data.name, avatar: data.avatar, intro: data.intro, - chat: data.chat, share: data.share }); }, diff --git a/client/src/pages/app/detail/components/OutLink.tsx b/client/src/pages/app/detail/components/OutLink.tsx index f6c4c0bd3..156b50b04 100644 --- a/client/src/pages/app/detail/components/OutLink.tsx +++ b/client/src/pages/app/detail/components/OutLink.tsx @@ -282,8 +282,6 @@ export function EditLinkModal({ return ( {}} title={isEdit ? titleMap.current.edit[type] : titleMap.current.create[type]} > diff --git a/client/src/pages/kb/detail/components/InputDataModal.tsx b/client/src/pages/kb/detail/components/InputDataModal.tsx index 45dd0d66c..fbb9b1f6d 100644 --- a/client/src/pages/kb/detail/components/InputDataModal.tsx +++ b/client/src/pages/kb/detail/components/InputDataModal.tsx @@ -168,7 +168,7 @@ const InputDataModal = ({ - {'预期答案'} + {'补充内容'} @@ -177,9 +177,8 @@ const InputDataModal = ({