guide node
This commit is contained in:
parent
d346d38677
commit
f9d83c481f
@ -1,3 +0,0 @@
|
|||||||
[ZoneTransfer]
|
|
||||||
ZoneId=3
|
|
||||||
HostUrl=about:internet
|
|
||||||
BIN
client/public/imgs/module/variable.png
Normal file
BIN
client/public/imgs/module/variable.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
3
client/src/api/response/chat.d.ts
vendored
3
client/src/api/response/chat.d.ts
vendored
@ -3,7 +3,7 @@ import type { ChatItemType } from '@/types/chat';
|
|||||||
import { VariableItemType } from '@/types/app';
|
import { VariableItemType } from '@/types/app';
|
||||||
|
|
||||||
export interface InitChatResponse {
|
export interface InitChatResponse {
|
||||||
historyId: string;
|
chatId: string;
|
||||||
appId: string;
|
appId: string;
|
||||||
app: {
|
app: {
|
||||||
variableModules?: VariableItemType[];
|
variableModules?: VariableItemType[];
|
||||||
@ -13,6 +13,7 @@ export interface InitChatResponse {
|
|||||||
intro: string;
|
intro: string;
|
||||||
canUse: boolean;
|
canUse: boolean;
|
||||||
};
|
};
|
||||||
|
customTitle?: string;
|
||||||
title: string;
|
title: string;
|
||||||
variables: Record<string, any>;
|
variables: Record<string, any>;
|
||||||
history: ChatItemType[];
|
history: ChatItemType[];
|
||||||
|
|||||||
@ -22,8 +22,8 @@ import Avatar from '@/components/Avatar';
|
|||||||
|
|
||||||
import { adaptChatItem_openAI } from '@/utils/plugin/openai';
|
import { adaptChatItem_openAI } from '@/utils/plugin/openai';
|
||||||
import { useMarkdown } from '@/hooks/useMarkdown';
|
import { useMarkdown } from '@/hooks/useMarkdown';
|
||||||
import { VariableItemType } from '@/types/app';
|
import { AppModuleItemType, VariableItemType } from '@/types/app';
|
||||||
import { VariableInputEnum } from '@/constants/app';
|
import { SystemInputEnum, VariableInputEnum } from '@/constants/app';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import MySelect from '@/components/Select';
|
import MySelect from '@/components/Select';
|
||||||
import { MessageItemType } from '@/pages/api/openapi/v1/chat/completions';
|
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 styles from './index.module.scss';
|
||||||
import { QuoteItemType } from '@/pages/api/app/modules/kb/search';
|
import { QuoteItemType } from '@/pages/api/app/modules/kb/search';
|
||||||
|
import { FlowModuleTypeEnum } from '@/constants/flow';
|
||||||
|
|
||||||
const textareaMinH = '22px';
|
const textareaMinH = '22px';
|
||||||
export type StartChatFnProps = {
|
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)[];
|
||||||
|
}) => <Avatar src={src} w={['24px', '34px']} h={['24px', '34px']} order={order} ml={ml} mr={mr} />;
|
||||||
|
|
||||||
const ChatBox = (
|
const ChatBox = (
|
||||||
{
|
{
|
||||||
showEmptyIntro = false,
|
showEmptyIntro = false,
|
||||||
@ -375,80 +388,79 @@ const ChatBox = (
|
|||||||
w: '100%'
|
w: '100%'
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasVariableInput = useMemo(
|
const showEmpty = useMemo(
|
||||||
() => variableModules || welcomeText,
|
() => showEmptyIntro && chatHistory.length === 0 && !(variableModules || welcomeText),
|
||||||
[variableModules, welcomeText]
|
[chatHistory.length, showEmptyIntro, variableModules, welcomeText]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex flexDirection={'column'} h={'100%'}>
|
<Flex flexDirection={'column'} h={'100%'}>
|
||||||
<Box ref={ChatBoxRef} flex={'1 0 0'} h={0} overflow={'overlay'} px={[2, 5, 8]} py={[0, 5]}>
|
<Box ref={ChatBoxRef} flex={'1 0 0'} h={0} overflow={'overlay'} px={[2, 5, 7]} py={[0, 5]}>
|
||||||
<Box maxW={['100%', '1000px', '1200px']} h={'100%'} mx={'auto'}>
|
<Box maxW={['100%', '1000px', '1200px']} h={'100%'} mx={'auto'}>
|
||||||
{/* variable input */}
|
{!!welcomeText && (
|
||||||
{hasVariableInput && (
|
|
||||||
<Flex alignItems={'flex-start'} py={2}>
|
<Flex alignItems={'flex-start'} py={2}>
|
||||||
{/* avatar */}
|
{/* avatar */}
|
||||||
<Avatar
|
<ChatAvatar src={appAvatar} order={1} mr={['6px', 2]} />
|
||||||
src={appAvatar}
|
|
||||||
w={['24px', '34px']}
|
|
||||||
h={['24px', '34px']}
|
|
||||||
order={1}
|
|
||||||
mr={['6px', 2]}
|
|
||||||
/>
|
|
||||||
{/* message */}
|
{/* message */}
|
||||||
<Flex order={2} pt={2} maxW={`calc(100% - ${isLargeWidth ? '75px' : '58px'})`}>
|
<Flex order={2} pt={2} maxW={`calc(100% - ${isLargeWidth ? '75px' : '58px'})`}>
|
||||||
<Card bg={'white'} px={4} py={3} borderRadius={'0 8px 8px 8px'}>
|
<Card bg={'white'} px={4} py={3} borderRadius={'0 8px 8px 8px'}>
|
||||||
{welcomeText && (
|
{welcomeText}
|
||||||
<Box mb={2} pb={2} borderBottom={theme.borders.base}>
|
</Card>
|
||||||
{welcomeText}
|
</Flex>
|
||||||
</Box>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
{variableModules && (
|
{/* variable input */}
|
||||||
<Box>
|
{variableModules && (
|
||||||
{variableModules.map((item) => (
|
<Flex alignItems={'flex-start'} py={2}>
|
||||||
<Box w={'min(100%,300px)'} key={item.id} mb={4}>
|
{/* avatar */}
|
||||||
<VariableLabel required={item.required}>{item.label}</VariableLabel>
|
<ChatAvatar src={appAvatar} order={1} mr={['6px', 2]} />
|
||||||
{item.type === VariableInputEnum.input && (
|
{/* message */}
|
||||||
<Input
|
<Flex order={2} pt={2} maxW={`calc(100% - ${isLargeWidth ? '75px' : '58px'})`}>
|
||||||
isDisabled={variableIsFinish}
|
<Card bg={'white'} px={4} py={3} borderRadius={'0 8px 8px 8px'}>
|
||||||
{...register(item.key, {
|
<Box>
|
||||||
required: item.required
|
{variableModules.map((item) => (
|
||||||
})}
|
<Box w={'min(100%,300px)'} key={item.id} mb={4}>
|
||||||
/>
|
<VariableLabel required={item.required}>{item.label}</VariableLabel>
|
||||||
)}
|
{item.type === VariableInputEnum.input && (
|
||||||
{item.type === VariableInputEnum.select && (
|
<Input
|
||||||
<MySelect
|
isDisabled={variableIsFinish}
|
||||||
width={'100%'}
|
{...register(item.key, {
|
||||||
isDisabled={variableIsFinish}
|
required: item.required
|
||||||
list={(item.enums || []).map((item) => ({
|
})}
|
||||||
label: item.value,
|
/>
|
||||||
value: item.value
|
)}
|
||||||
}))}
|
{item.type === VariableInputEnum.select && (
|
||||||
value={getValues(item.key)}
|
<MySelect
|
||||||
onchange={(e) => {
|
width={'100%'}
|
||||||
setValue(item.key, e);
|
isDisabled={variableIsFinish}
|
||||||
setRefresh(!refresh);
|
list={(item.enums || []).map((item) => ({
|
||||||
}}
|
label: item.value,
|
||||||
/>
|
value: item.value
|
||||||
)}
|
}))}
|
||||||
</Box>
|
value={getValues(item.key)}
|
||||||
))}
|
onchange={(e) => {
|
||||||
{!variableIsFinish && (
|
setValue(item.key, e);
|
||||||
<Button
|
setRefresh(!refresh);
|
||||||
leftIcon={<MyIcon name={'chatFill'} w={'16px'} />}
|
}}
|
||||||
size={'sm'}
|
/>
|
||||||
maxW={'100px'}
|
)}
|
||||||
borderRadius={'lg'}
|
</Box>
|
||||||
onClick={handleSubmit((data) => {
|
))}
|
||||||
onUpdateVariable?.(data);
|
{!variableIsFinish && (
|
||||||
setVariables(data);
|
<Button
|
||||||
})}
|
leftIcon={<MyIcon name={'chatFill'} w={'16px'} />}
|
||||||
>
|
size={'sm'}
|
||||||
{'开始对话'}
|
maxW={'100px'}
|
||||||
</Button>
|
borderRadius={'lg'}
|
||||||
)}
|
onClick={handleSubmit((data) => {
|
||||||
</Box>
|
onUpdateVariable?.(data);
|
||||||
)}
|
setVariables(data);
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{'开始对话'}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
</Card>
|
</Card>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -469,10 +481,8 @@ const ChatBox = (
|
|||||||
>
|
>
|
||||||
{item.obj === 'Human' && <Box flex={1} />}
|
{item.obj === 'Human' && <Box flex={1} />}
|
||||||
{/* avatar */}
|
{/* avatar */}
|
||||||
<Avatar
|
<ChatAvatar
|
||||||
src={item.obj === 'Human' ? userInfo?.avatar || HUMAN_ICON : appAvatar}
|
src={item.obj === 'Human' ? userInfo?.avatar || HUMAN_ICON : appAvatar}
|
||||||
w={['24px', '34px']}
|
|
||||||
h={['24px', '34px']}
|
|
||||||
{...(item.obj === 'AI'
|
{...(item.obj === 'AI'
|
||||||
? {
|
? {
|
||||||
order: 1,
|
order: 1,
|
||||||
@ -597,7 +607,7 @@ const ChatBox = (
|
|||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{showEmptyIntro && chatHistory.length === 0 && !hasVariableInput && <Empty />}
|
{showEmpty && <Empty />}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
{/* input */}
|
{/* input */}
|
||||||
@ -770,3 +780,20 @@ export const useChatBox = () => {
|
|||||||
onExportChat
|
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
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import type { AppItemType } from '@/types/app';
|
|
||||||
import { rawSearchKey } from './chat';
|
|
||||||
|
|
||||||
/* app */
|
/* app */
|
||||||
export enum AppModuleItemTypeEnum {
|
export enum AppModuleItemTypeEnum {
|
||||||
'userGuide' = 'userGuide', // default chat input: userChatInput, history
|
'variable' = 'variable',
|
||||||
'initInput' = 'initInput', // default chat input: userChatInput, history
|
'userGuide' = 'userGuide',
|
||||||
|
'initInput' = 'initInput',
|
||||||
'http' = 'http', // send a http request
|
'http' = 'http', // send a http request
|
||||||
'switch' = 'switch', // one input and two outputs
|
'switch' = 'switch', // one input and two outputs
|
||||||
'answer' = 'answer' // redirect response
|
'answer' = 'answer' // redirect response
|
||||||
|
|||||||
@ -9,10 +9,28 @@ import {
|
|||||||
} from './inputTemplate';
|
} from './inputTemplate';
|
||||||
import { rawSearchKey } from '../chat';
|
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',
|
logo: '/imgs/module/userGuide.png',
|
||||||
name: '开场引导',
|
name: '用户引导',
|
||||||
intro: '可以在每个新对话开始前,给用户发送一段开场白,或要求用户填写一些内容作为本轮对话的变量。',
|
intro: '可以添加特殊的对话前后引导模块,更好的让用户进行对话',
|
||||||
type: AppModuleItemTypeEnum.userGuide,
|
type: AppModuleItemTypeEnum.userGuide,
|
||||||
flowType: FlowModuleTypeEnum.userGuide,
|
flowType: FlowModuleTypeEnum.userGuide,
|
||||||
inputs: [
|
inputs: [
|
||||||
@ -20,12 +38,6 @@ export const VariableInputModule: AppModuleTemplateItemType = {
|
|||||||
key: SystemInputEnum.welcomeText,
|
key: SystemInputEnum.welcomeText,
|
||||||
type: FlowInputItemTypeEnum.input,
|
type: FlowInputItemTypeEnum.input,
|
||||||
label: '开场白'
|
label: '开场白'
|
||||||
},
|
|
||||||
{
|
|
||||||
key: SystemInputEnum.variables,
|
|
||||||
type: FlowInputItemTypeEnum.systemInput,
|
|
||||||
label: '变量输入',
|
|
||||||
value: []
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
outputs: []
|
outputs: []
|
||||||
@ -350,20 +362,16 @@ export const ClassifyQuestionModule: AppModuleTemplateItemType = {
|
|||||||
export const ModuleTemplates = [
|
export const ModuleTemplates = [
|
||||||
{
|
{
|
||||||
label: '输入模块',
|
label: '输入模块',
|
||||||
list: [UserInputModule, HistoryModule, VariableInputModule]
|
list: [UserInputModule, HistoryModule, VariableModule, UserGuideModule]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '对话模块',
|
label: '内容生成',
|
||||||
list: [ChatModule]
|
list: [ChatModule, AnswerModule]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '知识库模块',
|
label: '知识库模块',
|
||||||
list: [KBSearchModule]
|
list: [KBSearchModule]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '工具',
|
|
||||||
list: [AnswerModule]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Agent',
|
label: 'Agent',
|
||||||
list: [ClassifyQuestionModule]
|
list: [ClassifyQuestionModule]
|
||||||
@ -1105,7 +1113,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
|
|||||||
moduleId: 'xj0c9p'
|
moduleId: 'xj0c9p'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...VariableInputModule,
|
...VariableModule,
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
key: 'welcomeText',
|
key: 'welcomeText',
|
||||||
|
|||||||
@ -19,6 +19,7 @@ export enum FlowOutputItemTypeEnum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum FlowModuleTypeEnum {
|
export enum FlowModuleTypeEnum {
|
||||||
|
variable = 'variable',
|
||||||
userGuide = 'userGuide',
|
userGuide = 'userGuide',
|
||||||
questionInputNode = 'questionInput',
|
questionInputNode = 'questionInput',
|
||||||
historyNode = 'historyNode',
|
historyNode = 'historyNode',
|
||||||
|
|||||||
@ -7,18 +7,17 @@ import { ChatItemType } from '@/types/chat';
|
|||||||
import { authApp } from '@/service/utils/auth';
|
import { authApp } from '@/service/utils/auth';
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import type { AppSchema, ChatSchema } from '@/types/mongoSchema';
|
import type { AppSchema, ChatSchema } from '@/types/mongoSchema';
|
||||||
import { FlowModuleTypeEnum } from '@/constants/flow';
|
|
||||||
import { SystemInputEnum } from '@/constants/app';
|
|
||||||
import { quoteLenKey, rawSearchKey } from '@/constants/chat';
|
import { quoteLenKey, rawSearchKey } from '@/constants/chat';
|
||||||
|
import { getSpecialModule } from '@/components/ChatBox';
|
||||||
|
|
||||||
/* 初始化我的聊天框,需要身份验证 */
|
/* 初始化我的聊天框,需要身份验证 */
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
try {
|
try {
|
||||||
const { userId } = await authUser({ req, authToken: true });
|
const { userId } = await authUser({ req, authToken: true });
|
||||||
|
|
||||||
let { appId, historyId } = req.query as {
|
let { appId, chatId } = req.query as {
|
||||||
appId: '' | string;
|
appId: '' | string;
|
||||||
historyId: '' | string;
|
chatId: '' | string;
|
||||||
};
|
};
|
||||||
|
|
||||||
await connectToDatabase();
|
await connectToDatabase();
|
||||||
@ -53,10 +52,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
// 历史记录
|
// 历史记录
|
||||||
const { chat, history = [] }: { chat?: ChatSchema; history?: ChatItemType[] } =
|
const { chat, history = [] }: { chat?: ChatSchema; history?: ChatItemType[] } =
|
||||||
await (async () => {
|
await (async () => {
|
||||||
if (historyId) {
|
if (chatId) {
|
||||||
// auth historyId
|
// auth historyId
|
||||||
const chat = await Chat.findOne({
|
const chat = await Chat.findOne({
|
||||||
_id: historyId,
|
_id: chatId,
|
||||||
userId
|
userId
|
||||||
});
|
});
|
||||||
if (!chat) {
|
if (!chat) {
|
||||||
@ -66,7 +65,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
const history = await Chat.aggregate([
|
const history = await Chat.aggregate([
|
||||||
{
|
{
|
||||||
$match: {
|
$match: {
|
||||||
_id: new mongoose.Types.ObjectId(historyId),
|
_id: new mongoose.Types.ObjectId(chatId),
|
||||||
userId: new mongoose.Types.ObjectId(userId)
|
userId: new mongoose.Types.ObjectId(userId)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -96,20 +95,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
|
|
||||||
jsonRes<InitChatResponse>(res, {
|
jsonRes<InitChatResponse>(res, {
|
||||||
data: {
|
data: {
|
||||||
historyId,
|
chatId,
|
||||||
appId,
|
appId,
|
||||||
app: {
|
app: {
|
||||||
variableModules: app.modules
|
...getSpecialModule(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,
|
|
||||||
name: app.name,
|
name: app.name,
|
||||||
avatar: app.avatar,
|
avatar: app.avatar,
|
||||||
intro: app.intro,
|
intro: app.intro,
|
||||||
canUse: app.share.isShare || isOwner
|
canUse: app.share.isShare || isOwner
|
||||||
},
|
},
|
||||||
|
customTitle: chat?.customTitle,
|
||||||
title: chat?.title || '新对话',
|
title: chat?.title || '新对话',
|
||||||
variables: chat?.variables || {},
|
variables: chat?.variables || {},
|
||||||
history
|
history
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { hashPassword } from '@/service/utils/tools';
|
|||||||
import { HUMAN_ICON } from '@/constants/chat';
|
import { HUMAN_ICON } from '@/constants/chat';
|
||||||
import { FlowModuleTypeEnum } from '@/constants/flow';
|
import { FlowModuleTypeEnum } from '@/constants/flow';
|
||||||
import { SystemInputEnum } from '@/constants/app';
|
import { SystemInputEnum } from '@/constants/app';
|
||||||
|
import { getSpecialModule } from '@/components/ChatBox';
|
||||||
|
|
||||||
/* 初始化我的聊天框,需要身份验证 */
|
/* 初始化我的聊天框,需要身份验证 */
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
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)
|
?.find((item) => item.flowType === FlowModuleTypeEnum.historyNode)
|
||||||
?.inputs?.find((item) => item.key === 'maxContext')?.value || 0,
|
?.inputs?.find((item) => item.key === 'maxContext')?.value || 0,
|
||||||
app: {
|
app: {
|
||||||
variableModules: app.modules
|
...getSpecialModule(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,
|
|
||||||
name: app.name,
|
name: app.name,
|
||||||
avatar: app.avatar,
|
avatar: app.avatar,
|
||||||
intro: app.intro
|
intro: app.intro
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const Settings = ({ appId }: { appId: string }) => {
|
|||||||
content: '确认删除该应用?'
|
content: '确认删除该应用?'
|
||||||
});
|
});
|
||||||
const [settingAppInfo, setSettingAppInfo] = useState<AppSchema>();
|
const [settingAppInfo, setSettingAppInfo] = useState<AppSchema>();
|
||||||
const [fullScreen, setFullScreen] = useState(false);
|
const [fullScreen, setFullScreen] = useState(true);
|
||||||
|
|
||||||
/* 点击删除 */
|
/* 点击删除 */
|
||||||
const handleDelModel = useCallback(async () => {
|
const handleDelModel = useCallback(async () => {
|
||||||
|
|||||||
@ -11,12 +11,13 @@ import React, {
|
|||||||
import { Box, Flex, IconButton, useOutsideClick } from '@chakra-ui/react';
|
import { Box, Flex, IconButton, useOutsideClick } from '@chakra-ui/react';
|
||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
import { FlowModuleTypeEnum } from '@/constants/flow';
|
import { FlowModuleTypeEnum } from '@/constants/flow';
|
||||||
import { SystemInputEnum } from '@/constants/app';
|
|
||||||
import { streamFetch } from '@/api/fetch';
|
import { streamFetch } from '@/api/fetch';
|
||||||
import MyTooltip from '@/components/MyTooltip';
|
import MyTooltip from '@/components/MyTooltip';
|
||||||
import ChatBox, { type ComponentRef, type StartChatFnProps } from '@/components/ChatBox';
|
import ChatBox, {
|
||||||
import { useToast } from '@/hooks/useToast';
|
getSpecialModule,
|
||||||
import { getErrText } from '@/utils/tools';
|
type ComponentRef,
|
||||||
|
type StartChatFnProps
|
||||||
|
} from '@/components/ChatBox';
|
||||||
|
|
||||||
export type ChatTestComponentRef = {
|
export type ChatTestComponentRef = {
|
||||||
resetChatTest: () => void;
|
resetChatTest: () => void;
|
||||||
@ -36,24 +37,8 @@ const ChatTest = (
|
|||||||
) => {
|
) => {
|
||||||
const BoxRef = useRef(null);
|
const BoxRef = useRef(null);
|
||||||
const ChatBoxRef = useRef<ComponentRef>(null);
|
const ChatBoxRef = useRef<ComponentRef>(null);
|
||||||
const { toast } = useToast();
|
|
||||||
const isOpen = useMemo(() => modules && modules.length > 0, [modules]);
|
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(
|
const startChat = useCallback(
|
||||||
async ({ messages, controller, generatingMessage, variables }: StartChatFnProps) => {
|
async ({ messages, controller, generatingMessage, variables }: StartChatFnProps) => {
|
||||||
const historyMaxLen =
|
const historyMaxLen =
|
||||||
@ -137,8 +122,7 @@ const ChatTest = (
|
|||||||
<ChatBox
|
<ChatBox
|
||||||
ref={ChatBoxRef}
|
ref={ChatBoxRef}
|
||||||
appAvatar={app.avatar}
|
appAvatar={app.avatar}
|
||||||
variableModules={variableModules}
|
{...getSpecialModule(modules)}
|
||||||
welcomeText={welcomeText}
|
|
||||||
onStartChat={startChat}
|
onStartChat={startChat}
|
||||||
onDelMessage={() => {}}
|
onDelMessage={() => {}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NodeProps } from 'reactflow';
|
import { NodeProps } from 'reactflow';
|
||||||
import NodeCard from './modules/NodeCard';
|
import NodeCard from '../modules/NodeCard';
|
||||||
import { FlowModuleItemType } from '@/types/flow';
|
import { FlowModuleItemType } from '@/types/flow';
|
||||||
import Divider from './modules/Divider';
|
import Divider from '../modules/Divider';
|
||||||
import Container from './modules/Container';
|
import Container from '../modules/Container';
|
||||||
import RenderInput from './render/RenderInput';
|
import RenderInput from '../render/RenderInput';
|
||||||
|
|
||||||
const NodeAnswer = ({
|
const NodeAnswer = ({
|
||||||
data: { moduleId, inputs, outputs, onChangeNode, ...props }
|
data: { moduleId, inputs, outputs, onChangeNode, ...props }
|
||||||
@ -1,11 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NodeProps } from 'reactflow';
|
import { NodeProps } from 'reactflow';
|
||||||
import { Box, Input, Button, Flex } from '@chakra-ui/react';
|
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 { FlowModuleItemType } from '@/types/flow';
|
||||||
import Divider from './modules/Divider';
|
import Divider from '../modules/Divider';
|
||||||
import Container from './modules/Container';
|
import Container from '../modules/Container';
|
||||||
import RenderInput from './render/RenderInput';
|
import RenderInput from '../render/RenderInput';
|
||||||
import type { ClassifyQuestionAgentItemType } from '@/types/app';
|
import type { ClassifyQuestionAgentItemType } from '@/types/app';
|
||||||
import { Handle, Position } from 'reactflow';
|
import { Handle, Position } from 'reactflow';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
@ -13,7 +13,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 4);
|
|||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
import { FlowOutputItemTypeEnum } from '@/constants/flow';
|
import { FlowOutputItemTypeEnum } from '@/constants/flow';
|
||||||
|
|
||||||
const NodeRINode = ({
|
const NodeCQNode = ({
|
||||||
data: { moduleId, inputs, outputs, onChangeNode, ...props }
|
data: { moduleId, inputs, outputs, onChangeNode, ...props }
|
||||||
}: NodeProps<FlowModuleItemType>) => {
|
}: NodeProps<FlowModuleItemType>) => {
|
||||||
return (
|
return (
|
||||||
@ -133,4 +133,4 @@ const NodeRINode = ({
|
|||||||
</NodeCard>
|
</NodeCard>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default React.memo(NodeRINode);
|
export default React.memo(NodeCQNode);
|
||||||
@ -1,11 +1,11 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { NodeProps } from 'reactflow';
|
import { NodeProps } from 'reactflow';
|
||||||
import NodeCard from './modules/NodeCard';
|
import NodeCard from '../modules/NodeCard';
|
||||||
import { FlowModuleItemType } from '@/types/flow';
|
import { FlowModuleItemType } from '@/types/flow';
|
||||||
import Divider from './modules/Divider';
|
import Divider from '../modules/Divider';
|
||||||
import Container from './modules/Container';
|
import Container from '../modules/Container';
|
||||||
import RenderInput from './render/RenderInput';
|
import RenderInput from '../render/RenderInput';
|
||||||
import RenderOutput from './render/RenderOutput';
|
import RenderOutput from '../render/RenderOutput';
|
||||||
import { FlowOutputItemTypeEnum } from '@/constants/flow';
|
import { FlowOutputItemTypeEnum } from '@/constants/flow';
|
||||||
import MySelect from '@/components/Select';
|
import MySelect from '@/components/Select';
|
||||||
import { chatModelList } from '@/store/static';
|
import { chatModelList } from '@/store/static';
|
||||||
@ -1,11 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NodeProps } from 'reactflow';
|
import { NodeProps } from 'reactflow';
|
||||||
import NodeCard from './modules/NodeCard';
|
import NodeCard from '../modules/NodeCard';
|
||||||
import { FlowModuleItemType } from '@/types/flow';
|
import { FlowModuleItemType } from '@/types/flow';
|
||||||
import Divider from './modules/Divider';
|
import Divider from '../modules/Divider';
|
||||||
import Container from './modules/Container';
|
import Container from '../modules/Container';
|
||||||
import RenderInput from './render/RenderInput';
|
import RenderInput from '../render/RenderInput';
|
||||||
import RenderOutput from './render/RenderOutput';
|
import RenderOutput from '../render/RenderOutput';
|
||||||
|
|
||||||
const NodeHistory = ({
|
const NodeHistory = ({
|
||||||
data: { inputs, outputs, onChangeNode, ...props }
|
data: { inputs, outputs, onChangeNode, ...props }
|
||||||
@ -1,12 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NodeProps } from 'reactflow';
|
import { NodeProps } from 'reactflow';
|
||||||
import NodeCard from './modules/NodeCard';
|
import NodeCard from '../modules/NodeCard';
|
||||||
import { FlowModuleItemType } from '@/types/flow';
|
import { FlowModuleItemType } from '@/types/flow';
|
||||||
import Divider from './modules/Divider';
|
import Divider from '../modules/Divider';
|
||||||
import Container from './modules/Container';
|
import Container from '../modules/Container';
|
||||||
import RenderInput from './render/RenderInput';
|
import RenderInput from '../render/RenderInput';
|
||||||
import RenderOutput from './render/RenderOutput';
|
import RenderOutput from '../render/RenderOutput';
|
||||||
import KBSelect from './Plugins/KBSelect';
|
import KBSelect from '../Plugins/KBSelect';
|
||||||
|
|
||||||
const NodeKbSearch = ({
|
const NodeKbSearch = ({
|
||||||
data: { moduleId, inputs, outputs, onChangeNode, ...props }
|
data: { moduleId, inputs, outputs, onChangeNode, ...props }
|
||||||
@ -1,9 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Handle, Position, NodeProps } from 'reactflow';
|
import { Handle, Position, NodeProps } from 'reactflow';
|
||||||
import { Box } from '@chakra-ui/react';
|
import { Box } from '@chakra-ui/react';
|
||||||
import NodeCard from './modules/NodeCard';
|
import NodeCard from '../modules/NodeCard';
|
||||||
import { FlowModuleItemType } from '@/types/flow';
|
import { FlowModuleItemType } from '@/types/flow';
|
||||||
import Container from './modules/Container';
|
import Container from '../modules/Container';
|
||||||
import { SystemInputEnum } from '@/constants/app';
|
import { SystemInputEnum } from '@/constants/app';
|
||||||
|
|
||||||
const QuestionInputNode = ({
|
const QuestionInputNode = ({
|
||||||
@ -1,16 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Handle, Position, NodeProps } from 'reactflow';
|
import { Handle, Position, NodeProps } from 'reactflow';
|
||||||
import { Flex, Box } from '@chakra-ui/react';
|
import { Flex, Box } from '@chakra-ui/react';
|
||||||
import NodeCard from './modules/NodeCard';
|
import NodeCard from '../modules/NodeCard';
|
||||||
import { SystemInputEnum } from '@/constants/app';
|
import { SystemInputEnum } from '@/constants/app';
|
||||||
import { FlowModuleItemType } from '@/types/flow';
|
import { FlowModuleItemType } from '@/types/flow';
|
||||||
import Divider from './modules/Divider';
|
import Divider from '../modules/Divider';
|
||||||
import Container from './modules/Container';
|
import Container from '../modules/Container';
|
||||||
import Label from './modules/Label';
|
import Label from '../modules/Label';
|
||||||
|
|
||||||
const NodeTFSwitch = ({ data: { inputs, outputs, ...props } }: NodeProps<FlowModuleItemType>) => {
|
const NodeTFSwitch = ({ data: { inputs, outputs, ...props } }: NodeProps<FlowModuleItemType>) => {
|
||||||
return (
|
return (
|
||||||
<NodeCard minW={'220px'} logo={'/icon/logo.png'} name={'TF 开关'} {...props}>
|
<NodeCard minW={'220px'} {...props}>
|
||||||
<Divider text="输入输出" />
|
<Divider text="输入输出" />
|
||||||
<Container h={'100px'} py={0} px={0} display={'flex'} alignItems={'center'}>
|
<Container h={'100px'} py={0} px={0} display={'flex'} alignItems={'center'}>
|
||||||
<Box flex={1} pl={'12px'}>
|
<Box flex={1} pl={'12px'}>
|
||||||
@ -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<FlowModuleItemType>) => {
|
||||||
|
const welcomeText = useMemo(
|
||||||
|
() => inputs.find((item) => item.key === SystemInputEnum.welcomeText)?.value,
|
||||||
|
[inputs]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<NodeCard minW={'300px'} {...props}>
|
||||||
|
<Container borderTop={'2px solid'} borderTopColor={'myGray.200'}>
|
||||||
|
<>
|
||||||
|
<Flex mb={1} alignItems={'center'}>
|
||||||
|
<MyIcon name={'welcomeText'} mr={2} w={'16px'} color={'#E74694'} />
|
||||||
|
<Box>开场白</Box>
|
||||||
|
<MyTooltip label={welcomePlaceholder}>
|
||||||
|
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
|
||||||
|
</MyTooltip>
|
||||||
|
</Flex>
|
||||||
|
<Textarea
|
||||||
|
className="nodrag"
|
||||||
|
rows={6}
|
||||||
|
resize={'both'}
|
||||||
|
defaultValue={welcomeText}
|
||||||
|
bg={'myWhite.500'}
|
||||||
|
placeholder={welcomePlaceholder}
|
||||||
|
onChange={(e) => {
|
||||||
|
onChangeNode({
|
||||||
|
moduleId: props.moduleId,
|
||||||
|
key: SystemInputEnum.welcomeText,
|
||||||
|
type: 'inputs',
|
||||||
|
value: e.target.value
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
</Container>
|
||||||
|
</NodeCard>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default React.memo(NodeUserGuide);
|
||||||
@ -27,13 +27,12 @@ import {
|
|||||||
useDisclosure,
|
useDisclosure,
|
||||||
useTheme,
|
useTheme,
|
||||||
Grid,
|
Grid,
|
||||||
FormControl,
|
FormControl
|
||||||
Textarea
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons';
|
import { AddIcon, SmallAddIcon } from '@chakra-ui/icons';
|
||||||
import NodeCard from './modules/NodeCard';
|
import NodeCard from '../modules/NodeCard';
|
||||||
import { FlowModuleItemType } from '@/types/flow';
|
import { FlowModuleItemType } from '@/types/flow';
|
||||||
import Container from './modules/Container';
|
import Container from '../modules/Container';
|
||||||
import { SystemInputEnum, VariableInputEnum } from '@/constants/app';
|
import { SystemInputEnum, VariableInputEnum } from '@/constants/app';
|
||||||
import type { VariableItemType } from '@/types/app';
|
import type { VariableItemType } from '@/types/app';
|
||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
@ -41,8 +40,6 @@ import { useForm } from 'react-hook-form';
|
|||||||
import { useFieldArray } from 'react-hook-form';
|
import { useFieldArray } from 'react-hook-form';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
||||||
import { Label } from './render/RenderInput';
|
|
||||||
import MyTooltip from '@/components/MyTooltip';
|
|
||||||
|
|
||||||
const VariableTypeList = [
|
const VariableTypeList = [
|
||||||
{ label: '文本', icon: 'settingLight', key: VariableInputEnum.input },
|
{ label: '文本', icon: 'settingLight', key: VariableInputEnum.input },
|
||||||
@ -118,91 +115,60 @@ const NodeUserGuide = ({
|
|||||||
<>
|
<>
|
||||||
<NodeCard minW={'300px'} {...props}>
|
<NodeCard minW={'300px'} {...props}>
|
||||||
<Container borderTop={'2px solid'} borderTopColor={'myGray.200'}>
|
<Container borderTop={'2px solid'} borderTopColor={'myGray.200'}>
|
||||||
<>
|
<TableContainer>
|
||||||
<Flex mb={1} alignItems={'center'}>
|
<Table>
|
||||||
<MyIcon name={'welcomeText'} mr={2} w={'16px'} color={'#E74694'} />
|
<Thead>
|
||||||
<Box>对话开场白</Box>
|
<Tr>
|
||||||
</Flex>
|
<Th>变量名</Th>
|
||||||
<Textarea
|
<Th>变量 key</Th>
|
||||||
className="nodrag"
|
<Th>必填</Th>
|
||||||
rows={3}
|
<Th></Th>
|
||||||
resize={'both'}
|
</Tr>
|
||||||
defaultValue={welcomeText}
|
</Thead>
|
||||||
bg={'myWhite.600'}
|
<Tbody>
|
||||||
onChange={(e) => {
|
{variables.map((item, index) => (
|
||||||
onChangeNode({
|
<Tr key={index}>
|
||||||
moduleId: props.moduleId,
|
<Td>{item.label} </Td>
|
||||||
key: SystemInputEnum.welcomeText,
|
<Td>{item.key}</Td>
|
||||||
type: 'inputs',
|
<Td>{item.required ? '✔' : ''}</Td>
|
||||||
value: e.target.value
|
<Td>
|
||||||
});
|
<MyIcon
|
||||||
}}
|
mr={3}
|
||||||
/>
|
name={'settingLight'}
|
||||||
</>
|
w={'16px'}
|
||||||
<Box mt={4}>
|
cursor={'pointer'}
|
||||||
<Flex alignItems={'center'}>
|
onClick={() => {
|
||||||
<MyIcon name={'variable'} mr={2} w={'20px'} color={'#FF8A4C'} />
|
onOpen();
|
||||||
<Box>变量</Box>
|
reset({ variable: item });
|
||||||
<MyTooltip
|
}}
|
||||||
label={`变量会在开始对话前输入,仅会在本次对话中生效。\n你可以在任何字符串模块(系统提示词、限定词等)中使用 {{变量key}} 来代表变量输入。`}
|
/>
|
||||||
>
|
<MyIcon
|
||||||
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
|
name={'delete'}
|
||||||
</MyTooltip>
|
w={'16px'}
|
||||||
</Flex>
|
cursor={'pointer'}
|
||||||
<TableContainer>
|
onClick={() =>
|
||||||
<Table>
|
updateVariables(variables.filter((variable) => variable.id !== item.id))
|
||||||
<Thead>
|
}
|
||||||
<Tr>
|
/>
|
||||||
<Th>变量名</Th>
|
</Td>
|
||||||
<Th>变量 key</Th>
|
|
||||||
<Th>必填</Th>
|
|
||||||
<Th></Th>
|
|
||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
))}
|
||||||
<Tbody>
|
</Tbody>
|
||||||
{variables.map((item, index) => (
|
</Table>
|
||||||
<Tr key={index}>
|
</TableContainer>
|
||||||
<Td>{item.label} </Td>
|
<Box mt={2} textAlign={'right'}>
|
||||||
<Td>{item.key}</Td>
|
<Button
|
||||||
<Td>{item.required ? '✔' : ''}</Td>
|
variant={'base'}
|
||||||
<Td>
|
leftIcon={<AddIcon fontSize={'10px'} />}
|
||||||
<MyIcon
|
onClick={() => {
|
||||||
mr={3}
|
const newVariable = { ...defaultVariable, id: nanoid() };
|
||||||
name={'settingLight'}
|
updateVariables(variables.concat(newVariable));
|
||||||
w={'16px'}
|
reset({ variable: newVariable });
|
||||||
cursor={'pointer'}
|
onOpen();
|
||||||
onClick={() => {
|
}}
|
||||||
onOpen();
|
>
|
||||||
reset({ variable: item });
|
新增
|
||||||
}}
|
</Button>
|
||||||
/>
|
|
||||||
<MyIcon
|
|
||||||
name={'delete'}
|
|
||||||
w={'16px'}
|
|
||||||
cursor={'pointer'}
|
|
||||||
onClick={() =>
|
|
||||||
updateVariables(variables.filter((variable) => variable.id !== item.id))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Td>
|
|
||||||
</Tr>
|
|
||||||
))}
|
|
||||||
</Tbody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
<Box mt={2} textAlign={'right'}>
|
|
||||||
<Button
|
|
||||||
variant={'base'}
|
|
||||||
onClick={() => {
|
|
||||||
const newVariable = { ...defaultVariable, id: nanoid() };
|
|
||||||
updateVariables(variables.concat(newVariable));
|
|
||||||
reset({ variable: newVariable });
|
|
||||||
onOpen();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
+ 新增
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Container>
|
</Container>
|
||||||
</NodeCard>
|
</NodeCard>
|
||||||
@ -74,7 +74,7 @@ const ModuleStoreList = ({
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Avatar src={item.logo} w={'34px'} borderRadius={'0'} />
|
<Avatar src={item.logo} w={'34px'} objectFit={'contain'} borderRadius={'0'} />
|
||||||
<Box ml={5} flex={'1 0 0'}>
|
<Box ml={5} flex={'1 0 0'}>
|
||||||
<Box color={'black'}>{item.name}</Box>
|
<Box color={'black'}>{item.name}</Box>
|
||||||
<Box color={'myGray.500'} fontSize={'sm'}>
|
<Box color={'myGray.500'} fontSize={'sm'}>
|
||||||
|
|||||||
@ -31,7 +31,7 @@ const NodeCard = ({
|
|||||||
return (
|
return (
|
||||||
<Box minW={minW} bg={'white'} border={theme.borders.md} borderRadius={'md'} boxShadow={'sm'}>
|
<Box minW={minW} bg={'white'} border={theme.borders.md} borderRadius={'md'} boxShadow={'sm'}>
|
||||||
<Flex className="custom-drag-handle" px={4} py={3} alignItems={'center'}>
|
<Flex className="custom-drag-handle" px={4} py={3} alignItems={'center'}>
|
||||||
<Avatar src={logo} borderRadius={'md'} w={'30px'} h={'30px'} />
|
<Avatar src={logo} borderRadius={'md'} objectFit={'contain'} w={'30px'} h={'30px'} />
|
||||||
<Box ml={3} fontSize={'lg'} color={'myGray.600'}>
|
<Box ml={3} fontSize={'lg'} color={'myGray.600'}>
|
||||||
{name}
|
{name}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -31,28 +31,31 @@ import MyTooltip from '@/components/MyTooltip';
|
|||||||
import TemplateList from './components/TemplateList';
|
import TemplateList from './components/TemplateList';
|
||||||
import ChatTest, { type ChatTestComponentRef } from './components/ChatTest';
|
import ChatTest, { type ChatTestComponentRef } from './components/ChatTest';
|
||||||
|
|
||||||
const NodeChat = dynamic(() => import('./components/NodeChat'), {
|
const NodeChat = dynamic(() => import('./components/Nodes/NodeChat'), {
|
||||||
ssr: false
|
ssr: false
|
||||||
});
|
});
|
||||||
const NodeKbSearch = dynamic(() => import('./components/NodeKbSearch'), {
|
const NodeKbSearch = dynamic(() => import('./components/Nodes/NodeKbSearch'), {
|
||||||
ssr: false
|
ssr: false
|
||||||
});
|
});
|
||||||
const NodeHistory = dynamic(() => import('./components/NodeHistory'), {
|
const NodeHistory = dynamic(() => import('./components/Nodes/NodeHistory'), {
|
||||||
ssr: false
|
ssr: false
|
||||||
});
|
});
|
||||||
const NodeTFSwitch = dynamic(() => import('./components/NodeTFSwitch'), {
|
const NodeTFSwitch = dynamic(() => import('./components/Nodes/NodeTFSwitch'), {
|
||||||
ssr: false
|
ssr: false
|
||||||
});
|
});
|
||||||
const NodeAnswer = dynamic(() => import('./components/NodeAnswer'), {
|
const NodeAnswer = dynamic(() => import('./components/Nodes/NodeAnswer'), {
|
||||||
ssr: false
|
ssr: false
|
||||||
});
|
});
|
||||||
const NodeQuestionInput = dynamic(() => import('./components/NodeQuestionInput'), {
|
const NodeQuestionInput = dynamic(() => import('./components/Nodes/NodeQuestionInput'), {
|
||||||
ssr: false
|
ssr: false
|
||||||
});
|
});
|
||||||
const NodeRINode = dynamic(() => import('./components/NodeRINode'), {
|
const NodeCQNode = dynamic(() => import('./components/Nodes/NodeCQNode'), {
|
||||||
ssr: false
|
ssr: false
|
||||||
});
|
});
|
||||||
const NodeUserGuide = dynamic(() => import('./components/NodeUserGuide'), {
|
const NodeVariable = dynamic(() => import('./components/Nodes/NodeVariable'), {
|
||||||
|
ssr: false
|
||||||
|
});
|
||||||
|
const NodeUserGuide = dynamic(() => import('./components/Nodes/NodeUserGuide'), {
|
||||||
ssr: false
|
ssr: false
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -64,13 +67,14 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
|
|||||||
|
|
||||||
const nodeTypes = {
|
const nodeTypes = {
|
||||||
[FlowModuleTypeEnum.userGuide]: NodeUserGuide,
|
[FlowModuleTypeEnum.userGuide]: NodeUserGuide,
|
||||||
|
[FlowModuleTypeEnum.variable]: NodeVariable,
|
||||||
[FlowModuleTypeEnum.questionInputNode]: NodeQuestionInput,
|
[FlowModuleTypeEnum.questionInputNode]: NodeQuestionInput,
|
||||||
[FlowModuleTypeEnum.historyNode]: NodeHistory,
|
[FlowModuleTypeEnum.historyNode]: NodeHistory,
|
||||||
[FlowModuleTypeEnum.chatNode]: NodeChat,
|
[FlowModuleTypeEnum.chatNode]: NodeChat,
|
||||||
[FlowModuleTypeEnum.kbSearchNode]: NodeKbSearch,
|
[FlowModuleTypeEnum.kbSearchNode]: NodeKbSearch,
|
||||||
[FlowModuleTypeEnum.tfSwitchNode]: NodeTFSwitch,
|
[FlowModuleTypeEnum.tfSwitchNode]: NodeTFSwitch,
|
||||||
[FlowModuleTypeEnum.answerNode]: NodeAnswer,
|
[FlowModuleTypeEnum.answerNode]: NodeAnswer,
|
||||||
[FlowModuleTypeEnum.classifyQuestion]: NodeRINode
|
[FlowModuleTypeEnum.classifyQuestion]: NodeCQNode
|
||||||
};
|
};
|
||||||
const edgeTypes = {
|
const edgeTypes = {
|
||||||
buttonedge: ButtonEdge
|
buttonedge: ButtonEdge
|
||||||
|
|||||||
@ -161,7 +161,7 @@ const ChatHistorySlider = ({
|
|||||||
{item.top ? '取消置顶' : '置顶'}
|
{item.top ? '取消置顶' : '置顶'}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{/* {onUpdateTitle && (
|
{onUpdateTitle && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -174,7 +174,7 @@ const ChatHistorySlider = ({
|
|||||||
<MyIcon mr={2} name={'customTitle'} w={'16px'}></MyIcon>
|
<MyIcon mr={2} name={'customTitle'} w={'16px'}></MyIcon>
|
||||||
自定义标题
|
自定义标题
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)} */}
|
)}
|
||||||
<MenuItem
|
<MenuItem
|
||||||
_hover={{ color: 'red.500' }}
|
_hover={{ color: 'red.500' }}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
|||||||
@ -301,9 +301,7 @@ const Chat = () => {
|
|||||||
appAvatar={chatData.app.avatar}
|
appAvatar={chatData.app.avatar}
|
||||||
variableModules={chatData.app.variableModules}
|
variableModules={chatData.app.variableModules}
|
||||||
welcomeText={chatData.app.welcomeText}
|
welcomeText={chatData.app.welcomeText}
|
||||||
onUpdateVariable={(e) => {
|
onUpdateVariable={(e) => {}}
|
||||||
console.log(e);
|
|
||||||
}}
|
|
||||||
onStartChat={startChat}
|
onStartChat={startChat}
|
||||||
onDelMessage={delOneHistoryItem}
|
onDelMessage={delOneHistoryItem}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user