diff --git a/client/public/imgs/module/db.png:Zone.Identifier b/client/public/imgs/module/db.png:Zone.Identifier deleted file mode 100644 index 053d1127c..000000000 --- a/client/public/imgs/module/db.png:Zone.Identifier +++ /dev/null @@ -1,3 +0,0 @@ -[ZoneTransfer] -ZoneId=3 -HostUrl=about:internet diff --git a/client/public/imgs/module/variable.png b/client/public/imgs/module/variable.png new file mode 100644 index 000000000..15a9f01d7 Binary files /dev/null and b/client/public/imgs/module/variable.png differ diff --git a/client/src/api/response/chat.d.ts b/client/src/api/response/chat.d.ts index 60e5bea30..acb867144 100644 --- a/client/src/api/response/chat.d.ts +++ b/client/src/api/response/chat.d.ts @@ -3,7 +3,7 @@ import type { ChatItemType } from '@/types/chat'; import { VariableItemType } from '@/types/app'; export interface InitChatResponse { - historyId: string; + chatId: string; appId: string; app: { variableModules?: VariableItemType[]; @@ -13,6 +13,7 @@ export interface InitChatResponse { intro: string; canUse: boolean; }; + customTitle?: string; title: string; variables: Record; history: ChatItemType[]; diff --git a/client/src/components/ChatBox/index.tsx b/client/src/components/ChatBox/index.tsx index 23fc90242..4f6128793 100644 --- a/client/src/components/ChatBox/index.tsx +++ b/client/src/components/ChatBox/index.tsx @@ -22,8 +22,8 @@ import Avatar from '@/components/Avatar'; import { adaptChatItem_openAI } from '@/utils/plugin/openai'; import { useMarkdown } from '@/hooks/useMarkdown'; -import { VariableItemType } from '@/types/app'; -import { VariableInputEnum } from '@/constants/app'; +import { AppModuleItemType, VariableItemType } from '@/types/app'; +import { SystemInputEnum, VariableInputEnum } from '@/constants/app'; import { useForm } from 'react-hook-form'; import MySelect from '@/components/Select'; import { MessageItemType } from '@/pages/api/openapi/v1/chat/completions'; @@ -36,6 +36,7 @@ const QuoteModal = dynamic(() => import('./QuoteModal')); import styles from './index.module.scss'; import { QuoteItemType } from '@/pages/api/app/modules/kb/search'; +import { FlowModuleTypeEnum } from '@/constants/flow'; const textareaMinH = '22px'; export type StartChatFnProps = { @@ -94,6 +95,18 @@ const Empty = () => { ); }; +const ChatAvatar = ({ + src, + order, + ml, + mr +}: { + src: string; + order: number; + ml?: (string | number) | (string | number)[]; + mr?: (string | number) | (string | number)[]; +}) => ; + const ChatBox = ( { showEmptyIntro = false, @@ -375,80 +388,79 @@ const ChatBox = ( w: '100%' }; - const hasVariableInput = useMemo( - () => variableModules || welcomeText, - [variableModules, welcomeText] + const showEmpty = useMemo( + () => showEmptyIntro && chatHistory.length === 0 && !(variableModules || welcomeText), + [chatHistory.length, showEmptyIntro, variableModules, welcomeText] ); return ( - + - {/* variable input */} - {hasVariableInput && ( + {!!welcomeText && ( {/* avatar */} - + {/* message */} - {welcomeText && ( - - {welcomeText} - - )} - {variableModules && ( - - {variableModules.map((item) => ( - - {item.label} - {item.type === VariableInputEnum.input && ( - - )} - {item.type === VariableInputEnum.select && ( - ({ - label: item.value, - value: item.value - }))} - value={getValues(item.key)} - onchange={(e) => { - setValue(item.key, e); - setRefresh(!refresh); - }} - /> - )} - - ))} - {!variableIsFinish && ( - - )} - - )} + {welcomeText} + + + + )} + {/* variable input */} + {variableModules && ( + + {/* avatar */} + + {/* message */} + + + + {variableModules.map((item) => ( + + {item.label} + {item.type === VariableInputEnum.input && ( + + )} + {item.type === VariableInputEnum.select && ( + ({ + label: item.value, + value: item.value + }))} + value={getValues(item.key)} + onchange={(e) => { + setValue(item.key, e); + setRefresh(!refresh); + }} + /> + )} + + ))} + {!variableIsFinish && ( + + )} + @@ -469,10 +481,8 @@ const ChatBox = ( > {item.obj === 'Human' && } {/* avatar */} - - {showEmptyIntro && chatHistory.length === 0 && !hasVariableInput && } + {showEmpty && } {/* input */} @@ -770,3 +780,20 @@ export const useChatBox = () => { onExportChat }; }; + +export const getSpecialModule = (modules: AppModuleItemType[]) => { + const welcomeText: string = + modules + .find((item) => item.flowType === FlowModuleTypeEnum.userGuide) + ?.inputs?.find((item) => item.key === SystemInputEnum.welcomeText)?.value || ''; + + const variableModules: VariableItemType[] = + modules + .find((item) => item.flowType === FlowModuleTypeEnum.variable) + ?.inputs.find((item) => item.key === SystemInputEnum.variables)?.value || []; + + return { + welcomeText, + variableModules + }; +}; diff --git a/client/src/constants/app.ts b/client/src/constants/app.ts index ddd404b06..fab3520b6 100644 --- a/client/src/constants/app.ts +++ b/client/src/constants/app.ts @@ -1,10 +1,8 @@ -import type { AppItemType } from '@/types/app'; -import { rawSearchKey } from './chat'; - /* app */ export enum AppModuleItemTypeEnum { - 'userGuide' = 'userGuide', // default chat input: userChatInput, history - 'initInput' = 'initInput', // default chat input: userChatInput, history + 'variable' = 'variable', + 'userGuide' = 'userGuide', + 'initInput' = 'initInput', 'http' = 'http', // send a http request 'switch' = 'switch', // one input and two outputs 'answer' = 'answer' // redirect response diff --git a/client/src/constants/flow/ModuleTemplate.ts b/client/src/constants/flow/ModuleTemplate.ts index 000e94e4c..b7346113c 100644 --- a/client/src/constants/flow/ModuleTemplate.ts +++ b/client/src/constants/flow/ModuleTemplate.ts @@ -9,10 +9,28 @@ import { } from './inputTemplate'; import { rawSearchKey } from '../chat'; -export const VariableInputModule: AppModuleTemplateItemType = { +export const VariableModule: AppModuleTemplateItemType = { + logo: '/imgs/module/variable.png', + name: '全局变量', + intro: '可以在对话开始前,要求用户填写一些内容作为本轮对话的变量。该模块位于开场引导之后。', + description: + '全局变量可以通过 {{变量key}} 的形式注入到其他模块的文本中。目前支持:提示词、限定词。', + type: AppModuleItemTypeEnum.variable, + flowType: FlowModuleTypeEnum.variable, + inputs: [ + { + key: SystemInputEnum.variables, + type: FlowInputItemTypeEnum.systemInput, + label: '变量输入', + value: [] + } + ], + outputs: [] +}; +export const UserGuideModule: AppModuleTemplateItemType = { logo: '/imgs/module/userGuide.png', - name: '开场引导', - intro: '可以在每个新对话开始前,给用户发送一段开场白,或要求用户填写一些内容作为本轮对话的变量。', + name: '用户引导', + intro: '可以添加特殊的对话前后引导模块,更好的让用户进行对话', type: AppModuleItemTypeEnum.userGuide, flowType: FlowModuleTypeEnum.userGuide, inputs: [ @@ -20,12 +38,6 @@ export const VariableInputModule: AppModuleTemplateItemType = { key: SystemInputEnum.welcomeText, type: FlowInputItemTypeEnum.input, label: '开场白' - }, - { - key: SystemInputEnum.variables, - type: FlowInputItemTypeEnum.systemInput, - label: '变量输入', - value: [] } ], outputs: [] @@ -350,20 +362,16 @@ export const ClassifyQuestionModule: AppModuleTemplateItemType = { export const ModuleTemplates = [ { label: '输入模块', - list: [UserInputModule, HistoryModule, VariableInputModule] + list: [UserInputModule, HistoryModule, VariableModule, UserGuideModule] }, { - label: '对话模块', - list: [ChatModule] + label: '内容生成', + list: [ChatModule, AnswerModule] }, { label: '知识库模块', list: [KBSearchModule] }, - { - label: '工具', - list: [AnswerModule] - }, { label: 'Agent', list: [ClassifyQuestionModule] @@ -1105,7 +1113,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] = moduleId: 'xj0c9p' }, { - ...VariableInputModule, + ...VariableModule, inputs: [ { key: 'welcomeText', diff --git a/client/src/constants/flow/index.ts b/client/src/constants/flow/index.ts index a78ec5651..e5d482735 100644 --- a/client/src/constants/flow/index.ts +++ b/client/src/constants/flow/index.ts @@ -19,6 +19,7 @@ export enum FlowOutputItemTypeEnum { } export enum FlowModuleTypeEnum { + variable = 'variable', userGuide = 'userGuide', questionInputNode = 'questionInput', historyNode = 'historyNode', diff --git a/client/src/pages/api/chat/init.ts b/client/src/pages/api/chat/init.ts index 35014775f..261c8a8fe 100644 --- a/client/src/pages/api/chat/init.ts +++ b/client/src/pages/api/chat/init.ts @@ -7,18 +7,17 @@ import { ChatItemType } from '@/types/chat'; import { authApp } from '@/service/utils/auth'; import mongoose from 'mongoose'; import type { AppSchema, ChatSchema } from '@/types/mongoSchema'; -import { FlowModuleTypeEnum } from '@/constants/flow'; -import { SystemInputEnum } from '@/constants/app'; import { quoteLenKey, rawSearchKey } from '@/constants/chat'; +import { getSpecialModule } from '@/components/ChatBox'; /* 初始化我的聊天框,需要身份验证 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { const { userId } = await authUser({ req, authToken: true }); - let { appId, historyId } = req.query as { + let { appId, chatId } = req.query as { appId: '' | string; - historyId: '' | string; + chatId: '' | string; }; await connectToDatabase(); @@ -53,10 +52,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) // 历史记录 const { chat, history = [] }: { chat?: ChatSchema; history?: ChatItemType[] } = await (async () => { - if (historyId) { + if (chatId) { // auth historyId const chat = await Chat.findOne({ - _id: historyId, + _id: chatId, userId }); if (!chat) { @@ -66,7 +65,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) const history = await Chat.aggregate([ { $match: { - _id: new mongoose.Types.ObjectId(historyId), + _id: new mongoose.Types.ObjectId(chatId), userId: new mongoose.Types.ObjectId(userId) } }, @@ -96,20 +95,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) jsonRes(res, { data: { - historyId, + chatId, appId, app: { - variableModules: app.modules - .find((item) => item.flowType === FlowModuleTypeEnum.userGuide) - ?.inputs?.find((item) => item.key === SystemInputEnum.variables)?.value, - welcomeText: app.modules - .find((item) => item.flowType === FlowModuleTypeEnum.userGuide) - ?.inputs?.find((item) => item.key === SystemInputEnum.welcomeText)?.value, + ...getSpecialModule(app.modules), name: app.name, avatar: app.avatar, intro: app.intro, canUse: app.share.isShare || isOwner }, + customTitle: chat?.customTitle, title: chat?.title || '新对话', variables: chat?.variables || {}, history diff --git a/client/src/pages/api/chat/shareChat/init.ts b/client/src/pages/api/chat/shareChat/init.ts index cdc6cf68f..4043db705 100644 --- a/client/src/pages/api/chat/shareChat/init.ts +++ b/client/src/pages/api/chat/shareChat/init.ts @@ -7,6 +7,7 @@ import { hashPassword } from '@/service/utils/tools'; import { HUMAN_ICON } from '@/constants/chat'; import { FlowModuleTypeEnum } from '@/constants/flow'; import { SystemInputEnum } from '@/constants/app'; +import { getSpecialModule } from '@/components/ChatBox'; /* 初始化我的聊天框,需要身份验证 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { @@ -48,12 +49,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) ?.find((item) => item.flowType === FlowModuleTypeEnum.historyNode) ?.inputs?.find((item) => item.key === 'maxContext')?.value || 0, app: { - variableModules: app.modules - .find((item) => item.flowType === FlowModuleTypeEnum.userGuide) - ?.inputs?.find((item) => item.key === SystemInputEnum.variables)?.value, - welcomeText: app.modules - .find((item) => item.flowType === FlowModuleTypeEnum.userGuide) - ?.inputs?.find((item) => item.key === SystemInputEnum.welcomeText)?.value, + ...getSpecialModule(app.modules), name: app.name, avatar: app.avatar, intro: app.intro diff --git a/client/src/pages/app/detail/components/Settings.tsx b/client/src/pages/app/detail/components/Settings.tsx index e55370073..5f30924fe 100644 --- a/client/src/pages/app/detail/components/Settings.tsx +++ b/client/src/pages/app/detail/components/Settings.tsx @@ -28,7 +28,7 @@ const Settings = ({ appId }: { appId: string }) => { content: '确认删除该应用?' }); const [settingAppInfo, setSettingAppInfo] = useState(); - const [fullScreen, setFullScreen] = useState(false); + const [fullScreen, setFullScreen] = useState(true); /* 点击删除 */ const handleDelModel = useCallback(async () => { diff --git a/client/src/pages/app/detail/components/edit/components/ChatTest.tsx b/client/src/pages/app/detail/components/edit/components/ChatTest.tsx index d491e068b..572739105 100644 --- a/client/src/pages/app/detail/components/edit/components/ChatTest.tsx +++ b/client/src/pages/app/detail/components/edit/components/ChatTest.tsx @@ -11,12 +11,13 @@ import React, { import { Box, Flex, IconButton, useOutsideClick } from '@chakra-ui/react'; import MyIcon from '@/components/Icon'; import { FlowModuleTypeEnum } from '@/constants/flow'; -import { SystemInputEnum } from '@/constants/app'; import { streamFetch } from '@/api/fetch'; import MyTooltip from '@/components/MyTooltip'; -import ChatBox, { type ComponentRef, type StartChatFnProps } from '@/components/ChatBox'; -import { useToast } from '@/hooks/useToast'; -import { getErrText } from '@/utils/tools'; +import ChatBox, { + getSpecialModule, + type ComponentRef, + type StartChatFnProps +} from '@/components/ChatBox'; export type ChatTestComponentRef = { resetChatTest: () => void; @@ -36,24 +37,8 @@ const ChatTest = ( ) => { const BoxRef = useRef(null); const ChatBoxRef = useRef(null); - const { toast } = useToast(); const isOpen = useMemo(() => modules && modules.length > 0, [modules]); - const variableModules = useMemo( - () => - modules - .find((item) => item.flowType === FlowModuleTypeEnum.userGuide) - ?.inputs.find((item) => item.key === SystemInputEnum.variables)?.value, - [modules] - ); - const welcomeText = useMemo( - () => - modules - .find((item) => item.flowType === FlowModuleTypeEnum.userGuide) - ?.inputs?.find((item) => item.key === SystemInputEnum.welcomeText)?.value, - [modules] - ); - const startChat = useCallback( async ({ messages, controller, generatingMessage, variables }: StartChatFnProps) => { const historyMaxLen = @@ -137,8 +122,7 @@ const ChatTest = ( {}} /> diff --git a/client/src/pages/app/detail/components/edit/components/NodeAnswer.tsx b/client/src/pages/app/detail/components/edit/components/Nodes/NodeAnswer.tsx similarity index 74% rename from client/src/pages/app/detail/components/edit/components/NodeAnswer.tsx rename to client/src/pages/app/detail/components/edit/components/Nodes/NodeAnswer.tsx index af792470b..2f61524b0 100644 --- a/client/src/pages/app/detail/components/edit/components/NodeAnswer.tsx +++ b/client/src/pages/app/detail/components/edit/components/Nodes/NodeAnswer.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { NodeProps } from 'reactflow'; -import NodeCard from './modules/NodeCard'; +import NodeCard from '../modules/NodeCard'; import { FlowModuleItemType } from '@/types/flow'; -import Divider from './modules/Divider'; -import Container from './modules/Container'; -import RenderInput from './render/RenderInput'; +import Divider from '../modules/Divider'; +import Container from '../modules/Container'; +import RenderInput from '../render/RenderInput'; const NodeAnswer = ({ data: { moduleId, inputs, outputs, onChangeNode, ...props } diff --git a/client/src/pages/app/detail/components/edit/components/NodeRINode.tsx b/client/src/pages/app/detail/components/edit/components/Nodes/NodeCQNode.tsx similarity index 95% rename from client/src/pages/app/detail/components/edit/components/NodeRINode.tsx rename to client/src/pages/app/detail/components/edit/components/Nodes/NodeCQNode.tsx index 354339d5f..775f5715c 100644 --- a/client/src/pages/app/detail/components/edit/components/NodeRINode.tsx +++ b/client/src/pages/app/detail/components/edit/components/Nodes/NodeCQNode.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { NodeProps } from 'reactflow'; import { Box, Input, Button, Flex } from '@chakra-ui/react'; -import NodeCard from './modules/NodeCard'; +import NodeCard from '../modules/NodeCard'; import { FlowModuleItemType } from '@/types/flow'; -import Divider from './modules/Divider'; -import Container from './modules/Container'; -import RenderInput from './render/RenderInput'; +import Divider from '../modules/Divider'; +import Container from '../modules/Container'; +import RenderInput from '../render/RenderInput'; import type { ClassifyQuestionAgentItemType } from '@/types/app'; import { Handle, Position } from 'reactflow'; import { customAlphabet } from 'nanoid'; @@ -13,7 +13,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 4); import MyIcon from '@/components/Icon'; import { FlowOutputItemTypeEnum } from '@/constants/flow'; -const NodeRINode = ({ +const NodeCQNode = ({ data: { moduleId, inputs, outputs, onChangeNode, ...props } }: NodeProps) => { return ( @@ -133,4 +133,4 @@ const NodeRINode = ({ ); }; -export default React.memo(NodeRINode); +export default React.memo(NodeCQNode); diff --git a/client/src/pages/app/detail/components/edit/components/NodeChat.tsx b/client/src/pages/app/detail/components/edit/components/Nodes/NodeChat.tsx similarity index 94% rename from client/src/pages/app/detail/components/edit/components/NodeChat.tsx rename to client/src/pages/app/detail/components/edit/components/Nodes/NodeChat.tsx index 1adfcad79..5c7c1c32f 100644 --- a/client/src/pages/app/detail/components/edit/components/NodeChat.tsx +++ b/client/src/pages/app/detail/components/edit/components/Nodes/NodeChat.tsx @@ -1,11 +1,11 @@ import React, { useMemo } from 'react'; import { NodeProps } from 'reactflow'; -import NodeCard from './modules/NodeCard'; +import NodeCard from '../modules/NodeCard'; import { FlowModuleItemType } from '@/types/flow'; -import Divider from './modules/Divider'; -import Container from './modules/Container'; -import RenderInput from './render/RenderInput'; -import RenderOutput from './render/RenderOutput'; +import Divider from '../modules/Divider'; +import Container from '../modules/Container'; +import RenderInput from '../render/RenderInput'; +import RenderOutput from '../render/RenderOutput'; import { FlowOutputItemTypeEnum } from '@/constants/flow'; import MySelect from '@/components/Select'; import { chatModelList } from '@/store/static'; diff --git a/client/src/pages/app/detail/components/edit/components/NodeHistory.tsx b/client/src/pages/app/detail/components/edit/components/Nodes/NodeHistory.tsx similarity index 73% rename from client/src/pages/app/detail/components/edit/components/NodeHistory.tsx rename to client/src/pages/app/detail/components/edit/components/Nodes/NodeHistory.tsx index 08cbe7c67..0836a55c3 100644 --- a/client/src/pages/app/detail/components/edit/components/NodeHistory.tsx +++ b/client/src/pages/app/detail/components/edit/components/Nodes/NodeHistory.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { NodeProps } from 'reactflow'; -import NodeCard from './modules/NodeCard'; +import NodeCard from '../modules/NodeCard'; import { FlowModuleItemType } from '@/types/flow'; -import Divider from './modules/Divider'; -import Container from './modules/Container'; -import RenderInput from './render/RenderInput'; -import RenderOutput from './render/RenderOutput'; +import Divider from '../modules/Divider'; +import Container from '../modules/Container'; +import RenderInput from '../render/RenderInput'; +import RenderOutput from '../render/RenderOutput'; const NodeHistory = ({ data: { inputs, outputs, onChangeNode, ...props } diff --git a/client/src/pages/app/detail/components/edit/components/NodeKbSearch.tsx b/client/src/pages/app/detail/components/edit/components/Nodes/NodeKbSearch.tsx similarity index 79% rename from client/src/pages/app/detail/components/edit/components/NodeKbSearch.tsx rename to client/src/pages/app/detail/components/edit/components/Nodes/NodeKbSearch.tsx index 54dcd8580..f0526a6fb 100644 --- a/client/src/pages/app/detail/components/edit/components/NodeKbSearch.tsx +++ b/client/src/pages/app/detail/components/edit/components/Nodes/NodeKbSearch.tsx @@ -1,12 +1,12 @@ import React from 'react'; import { NodeProps } from 'reactflow'; -import NodeCard from './modules/NodeCard'; +import NodeCard from '../modules/NodeCard'; import { FlowModuleItemType } from '@/types/flow'; -import Divider from './modules/Divider'; -import Container from './modules/Container'; -import RenderInput from './render/RenderInput'; -import RenderOutput from './render/RenderOutput'; -import KBSelect from './Plugins/KBSelect'; +import Divider from '../modules/Divider'; +import Container from '../modules/Container'; +import RenderInput from '../render/RenderInput'; +import RenderOutput from '../render/RenderOutput'; +import KBSelect from '../Plugins/KBSelect'; const NodeKbSearch = ({ data: { moduleId, inputs, outputs, onChangeNode, ...props } diff --git a/client/src/pages/app/detail/components/edit/components/NodeQuestionInput.tsx b/client/src/pages/app/detail/components/edit/components/Nodes/NodeQuestionInput.tsx similarity index 91% rename from client/src/pages/app/detail/components/edit/components/NodeQuestionInput.tsx rename to client/src/pages/app/detail/components/edit/components/Nodes/NodeQuestionInput.tsx index 35f07bb22..e70f41fac 100644 --- a/client/src/pages/app/detail/components/edit/components/NodeQuestionInput.tsx +++ b/client/src/pages/app/detail/components/edit/components/Nodes/NodeQuestionInput.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { Handle, Position, NodeProps } from 'reactflow'; import { Box } from '@chakra-ui/react'; -import NodeCard from './modules/NodeCard'; +import NodeCard from '../modules/NodeCard'; import { FlowModuleItemType } from '@/types/flow'; -import Container from './modules/Container'; +import Container from '../modules/Container'; import { SystemInputEnum } from '@/constants/app'; const QuestionInputNode = ({ diff --git a/client/src/pages/app/detail/components/edit/components/NodeTFSwitch.tsx b/client/src/pages/app/detail/components/edit/components/Nodes/NodeTFSwitch.tsx similarity index 90% rename from client/src/pages/app/detail/components/edit/components/NodeTFSwitch.tsx rename to client/src/pages/app/detail/components/edit/components/Nodes/NodeTFSwitch.tsx index 154ed900e..0fc7f9639 100644 --- a/client/src/pages/app/detail/components/edit/components/NodeTFSwitch.tsx +++ b/client/src/pages/app/detail/components/edit/components/Nodes/NodeTFSwitch.tsx @@ -1,16 +1,16 @@ import React from 'react'; import { Handle, Position, NodeProps } from 'reactflow'; import { Flex, Box } from '@chakra-ui/react'; -import NodeCard from './modules/NodeCard'; +import NodeCard from '../modules/NodeCard'; import { SystemInputEnum } from '@/constants/app'; import { FlowModuleItemType } from '@/types/flow'; -import Divider from './modules/Divider'; -import Container from './modules/Container'; -import Label from './modules/Label'; +import Divider from '../modules/Divider'; +import Container from '../modules/Container'; +import Label from '../modules/Label'; const NodeTFSwitch = ({ data: { inputs, outputs, ...props } }: NodeProps) => { return ( - + diff --git a/client/src/pages/app/detail/components/edit/components/Nodes/NodeUserGuide.tsx b/client/src/pages/app/detail/components/edit/components/Nodes/NodeUserGuide.tsx new file mode 100644 index 000000000..9fd6d6d9b --- /dev/null +++ b/client/src/pages/app/detail/components/edit/components/Nodes/NodeUserGuide.tsx @@ -0,0 +1,59 @@ +import React, { useMemo } from 'react'; +import { NodeProps } from 'reactflow'; +import { Box, Flex, Textarea } from '@chakra-ui/react'; +import { QuestionOutlineIcon } from '@chakra-ui/icons'; +import NodeCard from '../modules/NodeCard'; +import { FlowModuleItemType } from '@/types/flow'; +import Container from '../modules/Container'; +import { SystemInputEnum } from '@/constants/app'; +import MyIcon from '@/components/Icon'; +import { customAlphabet } from 'nanoid'; +const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6); +import MyTooltip from '@/components/MyTooltip'; + +const welcomePlaceholder = + '每次对话开始前,发送一个初始内容。可使用的特殊标记:\n[快捷按键]: 用户点击后可以直接发送该问题'; + +const NodeUserGuide = ({ + data: { inputs, outputs, onChangeNode, ...props } +}: NodeProps) => { + const welcomeText = useMemo( + () => inputs.find((item) => item.key === SystemInputEnum.welcomeText)?.value, + [inputs] + ); + + return ( + <> + + + <> + + + 开场白 + + + + +