From 8155b10e798016ca59f6e79c5e7da4195ab83ae0 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 13 Dec 2024 19:50:05 +0800 Subject: [PATCH] Enhance Neo chat functionality by adding message type support; update ChatItem and NeoContent components to handle new message types, including error handling. Refactor useAIChat hook to manage message state more effectively and improve error display in the UI. This update aims to provide a more robust chat experience and better user feedback during interactions. --- .../Neo/components/ChatItem/index.tsx | 4 +-- .../layouts/components/Neo/hooks/useAIChat.ts | 21 +++++++++++++-- packages/xgen/types/app.ts | 13 ++++++++++ packages/xgen/widgets/NeoContent/index.less | 26 +++++++++++-------- packages/xgen/widgets/NeoContent/index.tsx | 17 +++++++++--- 5 files changed, 63 insertions(+), 18 deletions(-) diff --git a/packages/xgen/layouts/components/Neo/components/ChatItem/index.tsx b/packages/xgen/layouts/components/Neo/components/ChatItem/index.tsx index 3b94b902..fc92d38a 100644 --- a/packages/xgen/layouts/components/Neo/components/ChatItem/index.tsx +++ b/packages/xgen/layouts/components/Neo/components/ChatItem/index.tsx @@ -16,7 +16,7 @@ import type { App } from '@/types' const Index = (props: IPropsNeoChatItem) => { const { context, chat_info, callback } = props const { is_neo, text } = chat_info as App.ChatHuman - const { confirm, actions } = chat_info as App.ChatAI + const { confirm, actions, type } = chat_info as App.ChatAI const locale = getLocale() const onAction = useAction() const is_cn = locale === 'zh-CN' @@ -52,7 +52,7 @@ const Index = (props: IPropsNeoChatItem) => {
- +
diff --git a/packages/xgen/layouts/components/Neo/hooks/useAIChat.ts b/packages/xgen/layouts/components/Neo/hooks/useAIChat.ts index 336f5170..0b957536 100644 --- a/packages/xgen/layouts/components/Neo/hooks/useAIChat.ts +++ b/packages/xgen/layouts/components/Neo/hooks/useAIChat.ts @@ -52,13 +52,21 @@ export default ({ chat_id }: Args) => { const formated_data = ntry(() => JSON.parse(data)) as App.ChatAI if (!formated_data) return - const { text, confirm, actions, done, command } = formated_data + const { text, confirm, type, actions, done } = formated_data const current_answer = messages[messages.length - 1] as App.ChatAI if (done) { + if (text) { + current_answer.text = text + } + if (type) { + current_answer.type = type + } current_answer.confirm = confirm current_answer.actions = actions setMessages([...messages]) - return setLoading(false) + setLoading(false) + es.close() // Close the EventSource if the AI is done + return } if (!text) return @@ -75,6 +83,15 @@ export default ({ chat_id }: Args) => { } es.onerror = () => { + const message_new = [ + ...messages, + { + text: 'Network error, please try again later', + type: 'error', + is_neo: true + } + ] + setMessages(message_new) setLoading(false) es.close() } diff --git a/packages/xgen/types/app.ts b/packages/xgen/types/app.ts index 2bec0b86..a588c6b2 100644 --- a/packages/xgen/types/app.ts +++ b/packages/xgen/types/app.ts @@ -3,6 +3,18 @@ import type { Action, Common } from '@/types' export declare namespace App { type Theme = 'light' | 'dark' + type ChatMessageType = + | 'text' + | 'image' + | 'audio' + | 'video' + | 'file' + | 'link' + | 'error' + | 'progress' + | 'page' + | 'widget' + type ChatCmd = { id: string name: string @@ -18,6 +30,7 @@ export declare namespace App { type ChatAI = { is_neo: boolean text: string + type?: ChatMessageType done: boolean confirm?: boolean actions?: Array diff --git a/packages/xgen/widgets/NeoContent/index.less b/packages/xgen/widgets/NeoContent/index.less index 4529e032..739a3e27 100644 --- a/packages/xgen/widgets/NeoContent/index.less +++ b/packages/xgen/widgets/NeoContent/index.less @@ -1,14 +1,18 @@ ._local { :global { - ._newline{ - margin-bottom: 12px !important; - } + ._newline { + margin-bottom: 12px !important; + } + + .error { + color: var(--color_danger); + } p { - padding: 0 !important; - margin: 0 !important; - margin-block: 0 !important; - line-height: 24px; + padding: 0 !important; + margin: 0 !important; + margin-block: 0 !important; + line-height: 24px; } table { @@ -24,13 +28,13 @@ white-space: nowrap; } - ._newline{ - display: none; - } + ._newline { + display: none; + } } pre { - margin: 0; + margin: 0; } } } diff --git a/packages/xgen/widgets/NeoContent/index.tsx b/packages/xgen/widgets/NeoContent/index.tsx index a59dffd2..1c8d1f71 100644 --- a/packages/xgen/widgets/NeoContent/index.tsx +++ b/packages/xgen/widgets/NeoContent/index.tsx @@ -13,20 +13,27 @@ import { useMDXComponents } from '@mdx-js/react' import components from './components' import styles from './index.less' +import { App } from '@/types' interface IProps { source: string + type?: App.ChatMessageType callback?: () => void } const Index = (props: IProps) => { - const { source, callback } = props + const { source, type, callback } = props const [target, setTarget] = useState() const mdx_components = useMDXComponents(components) useAsyncEffect(async () => { - const vfile = new VFile(source) + // If there is an error, display the error message + if (type === 'error') { + setTarget(
{source}
) + return + } + const vfile = new VFile(source) const [err, compiled_source] = await to( compile(vfile, { format: 'md', @@ -67,8 +74,12 @@ const Index = (props: IProps) => { }) ) - if (!compiled_source) return + if (err) { + setTarget(
{err.message}
) + return + } + if (!compiled_source) return compiled_source.value = (compiled_source.value as string).replaceAll('%7B', '{') const { default: Content } = await run(compiled_source, {