diff --git a/datacenter/app/agents/[agentId]/page.tsx b/datacenter/app/chat/page.tsx similarity index 100% rename from datacenter/app/agents/[agentId]/page.tsx rename to datacenter/app/chat/page.tsx diff --git a/datacenter/app/page.tsx b/datacenter/app/page.tsx index 6e425be64..e1d3bbea5 100644 --- a/datacenter/app/page.tsx +++ b/datacenter/app/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useRequest } from 'ahooks'; import { useState } from 'react'; -import { Button, Input, useColorScheme, Box, buttonClasses } from '@/lib/mui'; +import { Button, Input, Box, buttonClasses } from '@/lib/mui'; import IconButton from '@mui/joy/IconButton'; import SendRoundedIcon from '@mui/icons-material/SendRounded'; import { zodResolver } from '@hookform/resolvers/zod'; @@ -13,7 +13,6 @@ import { useRouter } from 'next/navigation'; export default function Home() { const Schema = z.object({ query: z.string().min(1) }); const router = useRouter(); - const { mode } = useColorScheme(); const [isLoading, setIsLoading] = useState(false); const methods = useForm>({ resolver: zodResolver(Schema), @@ -29,7 +28,7 @@ export default function Home() { chat_mode: 'chat_normal' }); if (res?.success && res?.data?.conv_uid) { - router.push(`/agents/${res?.data?.conv_uid}?initMessage=${query}`); + router.push(`/chat?id=${res?.data?.conv_uid}&initMessage=${query}`); } } catch (err) { } finally { @@ -67,7 +66,7 @@ export default function Home() { chat_mode: scene['chat_scene'] }); if (res?.success && res?.data?.conv_uid) { - router.push(`/agents/${res?.data?.conv_uid}?scene=${scene['chat_scene']}`); + router.push(`/chat?id=${res?.data?.conv_uid}&scene=${scene['chat_scene']}`); } }} > diff --git a/datacenter/components/agentPage.tsx b/datacenter/components/agentPage.tsx index 55286c734..ac2541e58 100644 --- a/datacenter/components/agentPage.tsx +++ b/datacenter/components/agentPage.tsx @@ -2,14 +2,12 @@ import { useRequest } from 'ahooks'; import { sendGetRequest, sendPostRequest } from '@/utils/request'; import useAgentChat from '@/hooks/useAgentChat'; -import ChatBoxComp from '@/components/chatBox'; +import ChatBoxComp from '@/components/chatBoxTemp'; import { useDialogueContext } from '@/app/context/dialogue'; const AgentPage = (props: { - params: { - agentId?: string; - }, searchParams: { + id?: string; scene?: string; initMessage?: string; } @@ -17,26 +15,28 @@ const AgentPage = (props: { const { refreshDialogList } = useDialogueContext(); const { data: historyList } = useRequest(async () => await sendGetRequest('/v1/chat/dialogue/messages/history', { - con_uid: props.params?.agentId + con_uid: props.searchParams?.id }), { - ready: !!props.params?.agentId + ready: !!props.searchParams?.id, + refreshDeps: [props.searchParams?.id] }); const { data: paramsList } = useRequest(async () => await sendPostRequest(`/v1/chat/mode/params/list?chat_mode=${props.searchParams?.scene}`), { - ready: !!props.searchParams?.scene + ready: !!props.searchParams?.scene, + refreshDeps: [props.searchParams?.scene] }); const { history, handleChatSubmit } = useAgentChat({ queryAgentURL: `/v1/chat/completions`, queryBody: { - conv_uid: props.params?.agentId, + conv_uid: props.searchParams?.id, chat_mode: props.searchParams?.scene || 'chat_normal', }, initHistory: historyList?.data }); return ( -
+ <> { @@ -46,7 +46,7 @@ const AgentPage = (props: { onSubmit={handleChatSubmit} paramsList={paramsList?.data} /> -
+ ) } diff --git a/datacenter/components/chatBox.tsx b/datacenter/components/chatBox.tsx index 682ec9e09..ab642a2e0 100644 --- a/datacenter/components/chatBox.tsx +++ b/datacenter/components/chatBox.tsx @@ -96,168 +96,171 @@ const ChatBoxComp = ({ }, [paramsList]); return ( - +
- {firstMsg && ( - - {firstMsg?.context} - - )} - - {messages.filter(item => ['view', 'human'].includes(item.role)).map((each, index) => ( - + + {firstMsg && ( ({ - px: 2, - 'ol, ul': { - my: 0, - pl: 2, - }, - ol: { - listStyle: 'numeric', - }, - ul: { - listStyle: 'disc', - mb: 2, - }, - li: { - my: 1, - }, - a: { - textDecoration: 'underline', - }, - })} + color={'primary'} + className="message-agent" + sx={{ + mr: 'auto', + ml: 'none', + whiteSpace: 'pre-wrap', + }} > - - {each.context?.replaceAll('\\n', '\n')} - + {firstMsg?.context} - - ))} - - {isLoading && ( - - )} - - {!readOnly && ( -
{ - e.stopPropagation(); - methods.handleSubmit(submit)(e); - }} - > - {(Object.keys(paramsList || {}).length > 0) && ( -
- - - - -
)} - - - - } - {...methods.register('query')} - /> - - )} -
+ {messages.filter(item => ['view', 'human'].includes(item.role)).map((each, index) => ( + + ({ + px: 2, + 'ol, ul': { + my: 0, + pl: 2, + }, + ol: { + listStyle: 'numeric', + }, + ul: { + listStyle: 'disc', + mb: 2, + }, + li: { + my: 1, + }, + a: { + textDecoration: 'underline', + }, + })} + > + + {each.context?.replaceAll('\\n', '\n')} + + + + ))} + + {isLoading && ( + + )} + + {!readOnly && ( +
{ + e.stopPropagation(); + methods.handleSubmit(submit)(e); + }} + > + {(Object.keys(paramsList || {}).length > 0) && ( +
+ + + + +
+ )} + + + + + } + {...methods.register('query')} + /> + + )} + +
+ ); } diff --git a/datacenter/components/chatBoxTemp.tsx b/datacenter/components/chatBoxTemp.tsx new file mode 100644 index 000000000..56f4762a7 --- /dev/null +++ b/datacenter/components/chatBoxTemp.tsx @@ -0,0 +1,252 @@ +import { zodResolver } from '@hookform/resolvers/zod'; +import SendRoundedIcon from '@mui/icons-material/SendRounded'; +import { Card, CircularProgress, IconButton, Input, Stack, Select, Option, Tooltip, Box, useColorScheme } from '@/lib/mui'; +import React, { useState } from 'react'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { Message } from '@/types'; +import FaceRetouchingNaturalOutlinedIcon from '@mui/icons-material/FaceRetouchingNaturalOutlined'; +import SmartToyOutlinedIcon from '@mui/icons-material/SmartToyOutlined'; +import Markdown from 'markdown-to-jsx'; +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { okaidia } from 'react-syntax-highlighter/dist/esm/styles/prism'; + +type Props = { + messages: Message[]; + onSubmit: (message: string, otherQueryBody?: any) => Promise; + initialMessage?: string; + readOnly?: boolean; + paramsList?: { [key: string]: string }; + clearIntialMessage?: () => void; +}; + +const Schema = z.object({ query: z.string().min(1) }); + +const ChatBoxComp = ({ + messages, + onSubmit, + initialMessage, + readOnly, + paramsList, + clearIntialMessage +}: Props) => { + const { mode } = useColorScheme(); + const scrollableRef = React.useRef(null); + const [isLoading, setIsLoading] = useState(false); + const [currentParam, setCurrentParam] = useState(); + + const methods = useForm>({ + resolver: zodResolver(Schema), + defaultValues: {}, + }); + + const submit = async ({ query }: z.infer) => { + try { + setIsLoading(true); + methods.reset(); + await onSubmit(query, { + select_param: paramsList?.[currentParam] + }); + } catch (err) { + } finally { + setIsLoading(false); + } + }; + + const handleInitMessage = async () => { + try { + const searchParams = new URLSearchParams(window.location.search); + searchParams.delete('initMessage'); + window.history.replaceState(null, null, `?${searchParams.toString()}`); + await submit({ query: (initialMessage as string) }); + } catch (err) { + console.log(err); + } finally { + clearIntialMessage?.(); + } + } + + const options = { + overrides: { + code: ({ children }) => ( + + {children} + + ), + }, + }; + + React.useEffect(() => { + if (!scrollableRef.current) { + return; + } + + scrollableRef.current.scrollTo(0, scrollableRef.current.scrollHeight); + }, [messages?.length]); + + React.useEffect(() => { + if (initialMessage && messages.length <= 0) { + handleInitMessage(); + } + }, [initialMessage]); + + React.useEffect(() => { + if (paramsList && Object.keys(paramsList || {})?.length > 0) { + setCurrentParam(Object.keys(paramsList || {})?.[0]); + } + }, [paramsList]); + + return ( +
+ + + {messages.filter(item => ['view', 'human'].includes(item.role))?.map((each, index) => { + return ( + + ({ + background: each.role === 'view' ? 'var(--joy-palette-primary-softBg, var(--joy-palette-primary-100, #DDF1FF))': 'unset', + border: 'unset', + borderRadius: 'unset', + padding: '24px 0 26px 0', + lineHeight: '24px', + })} + > + +
+ {each.role === 'view' ? ( + + ) : ( + + )} +
+
+ + {each.context?.replaceAll('\\n', '\n')} + +
+
+
+
+ ) + })} + {isLoading && ( + + )} +
+ {!readOnly && ( + +
{ + e.stopPropagation(); + methods.handleSubmit(submit)(e); + }} + > + {(Object.keys(paramsList || {}).length > 0) && ( +
+ + +
+ )} + + + + + } + {...methods.register('query')} + /> + +
+ )} +
+
+ ); +} + +export default ChatBoxComp; diff --git a/datacenter/components/leftSider.tsx b/datacenter/components/leftSider.tsx index 359b660ba..0dc412907 100644 --- a/datacenter/components/leftSider.tsx +++ b/datacenter/components/leftSider.tsx @@ -1,6 +1,6 @@ "use client"; import React, { useEffect, useMemo } from 'react'; -import { usePathname, useRouter } from 'next/navigation'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; import Link from 'next/link'; import { Modal } from 'antd'; import { Box, List, ListItem, ListItemButton, ListItemDecorator, ListItemContent, Typography, Button, useColorScheme, IconButton } from '@/lib/mui'; @@ -15,6 +15,7 @@ import { sendPostRequest } from '@/utils/request'; const LeftSider = () => { const pathname = usePathname(); + const searchParams = useSearchParams(); const router = useRouter(); const { dialogueList, queryDialogueList, refreshDialogList } = useDialogueContext(); const { mode, setMode } = useColorScheme(); @@ -44,7 +45,7 @@ const LeftSider = () => { return ( <> -