mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-11 22:09:44 +00:00
feat: edit chat_dashboard style logic
This commit is contained in:
@@ -15,7 +15,7 @@ export const ChatEn = {
|
||||
copy_success: 'Copy success',
|
||||
copy_failed: 'Copy failed',
|
||||
file_tip: 'File cannot be changed after upload',
|
||||
assistant: 'DataFun Assistant',
|
||||
assistant: 'Platform Assistant', // DataFun Assistant
|
||||
model_tip: 'Model selection is not supported for the current application',
|
||||
temperature_tip: 'The current application does not support temperature configuration',
|
||||
extend_tip: 'Extended configuration is not supported for the current application',
|
||||
|
@@ -24,7 +24,7 @@ export const ChatZh: Resources['translation'] = {
|
||||
copy_nothing: '内容复制为空',
|
||||
file_tip: '文件上传后无法更改',
|
||||
chat_online: '在线对话',
|
||||
assistant: '灵数平台小助手',
|
||||
assistant: '平台小助手', // 灵数平台小助手
|
||||
model_tip: '当前应用暂不支持模型选择',
|
||||
temperature_tip: '当前应用暂不支持温度配置',
|
||||
extend_tip: '当前应用暂不支持拓展配置',
|
||||
|
298
web_new/pages/chat/index-new.tsx
Normal file
298
web_new/pages/chat/index-new.tsx
Normal file
@@ -0,0 +1,298 @@
|
||||
import ChatContentContainer from '@/ant-components/chat/ChatContentContainer';
|
||||
import ChatDefault from '@/ant-components/chat/content/ChatDefault';
|
||||
import ChatInputPanel from '@/ant-components/chat/input/ChatInputPanel';
|
||||
import ChatSider from '@/ant-components/chat/sider/ChatSider';
|
||||
import { ChatContext } from '@/app/chat-context';
|
||||
import { apiInterceptors, getAppInfo, getChatHistory, getDialogueList } from '@/client/api';
|
||||
import useChat from '@/hooks/use-chat';
|
||||
import { IApp } from '@/types/app';
|
||||
import { ChartData, ChatHistoryResponse, IChatDialogueSchema } from '@/types/chat';
|
||||
import { getInitMessage } from '@/utils';
|
||||
import { useAsyncEffect, useRequest } from 'ahooks';
|
||||
import { Flex, Layout, Spin } from 'antd';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
const { Content } = Layout;
|
||||
|
||||
interface ChatContentProps {
|
||||
history: ChatHistoryResponse; // 会话记录列表
|
||||
replyLoading: boolean; // 对话回复loading
|
||||
scrollRef: React.RefObject<HTMLDivElement>; // 会话内容可滚动dom
|
||||
canAbort: boolean; // 是否能中断回复
|
||||
chartsData: ChartData[];
|
||||
agent: string;
|
||||
currentDialogue: IChatDialogueSchema; // 当前选择的会话
|
||||
appInfo: IApp;
|
||||
temperatureValue: any;
|
||||
resourceValue: any;
|
||||
modelValue: string;
|
||||
setModelValue: React.Dispatch<React.SetStateAction<string>>;
|
||||
setTemperatureValue: React.Dispatch<React.SetStateAction<any>>;
|
||||
setResourceValue: React.Dispatch<React.SetStateAction<any>>;
|
||||
setAppInfo: React.Dispatch<React.SetStateAction<IApp>>;
|
||||
setAgent: React.Dispatch<React.SetStateAction<string>>;
|
||||
setCanAbort: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setReplyLoading: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
handleChat: (content: string, data?: Record<string, any>) => Promise<void>; // 处理会话请求逻辑函数
|
||||
refreshDialogList: () => void;
|
||||
refreshHistory: () => void;
|
||||
refreshAppInfo: () => void;
|
||||
setHistory: React.Dispatch<React.SetStateAction<ChatHistoryResponse>>;
|
||||
}
|
||||
export const ChatContentContext = createContext<ChatContentProps>({
|
||||
history: [],
|
||||
replyLoading: false,
|
||||
scrollRef: { current: null },
|
||||
canAbort: false,
|
||||
chartsData: [],
|
||||
agent: '',
|
||||
currentDialogue: {} as any,
|
||||
appInfo: {} as any,
|
||||
temperatureValue: 0.5,
|
||||
resourceValue: {},
|
||||
modelValue: '',
|
||||
setModelValue: () => {},
|
||||
setResourceValue: () => {},
|
||||
setTemperatureValue: () => {},
|
||||
setAppInfo: () => {},
|
||||
setAgent: () => {},
|
||||
setCanAbort: () => {},
|
||||
setReplyLoading: () => {},
|
||||
refreshDialogList: () => {},
|
||||
refreshHistory: () => {},
|
||||
refreshAppInfo: () => {},
|
||||
setHistory: () => {},
|
||||
handleChat: () => Promise.resolve(),
|
||||
});
|
||||
|
||||
const Chat: React.FC = () => {
|
||||
const { model, currentDialogInfo } = useContext(ChatContext);
|
||||
const { chat, ctrl } = useChat({ app_code: currentDialogInfo.app_code || '' });
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
const chatId = searchParams?.get('id') ?? '';
|
||||
const scene = searchParams?.get('scene') ?? '';
|
||||
const knowledgeId = searchParams?.get('knowledge_id') ?? '';
|
||||
const dbName = searchParams?.get('db_name') ?? '';
|
||||
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const order = useRef<number>(1);
|
||||
|
||||
const [history, setHistory] = useState<ChatHistoryResponse>([]);
|
||||
const [chartsData, setChartsData] = useState<Array<ChartData>>();
|
||||
const [replyLoading, setReplyLoading] = useState<boolean>(false);
|
||||
const [canAbort, setCanAbort] = useState<boolean>(false);
|
||||
const [agent, setAgent] = useState<string>('');
|
||||
const [appInfo, setAppInfo] = useState<IApp>({} as IApp);
|
||||
const [temperatureValue, setTemperatureValue] = useState();
|
||||
const [resourceValue, setResourceValue] = useState<any>();
|
||||
const [modelValue, setModelValue] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
setTemperatureValue(appInfo?.param_need?.filter((item) => item.type === 'temperature')[0]?.value || 0.5);
|
||||
setModelValue(appInfo?.param_need?.filter((item) => item.type === 'model')[0]?.value || model);
|
||||
setResourceValue(Number(knowledgeId) || dbName || appInfo?.param_need?.filter((item) => item.type === 'resource')[0]?.bind_value);
|
||||
}, [appInfo, dbName, knowledgeId, model]);
|
||||
|
||||
// 是否是默认小助手
|
||||
const isChatDefault = useMemo(() => {
|
||||
return !chatId && !scene;
|
||||
}, [chatId, scene]);
|
||||
|
||||
// 获取会话列表
|
||||
const {
|
||||
data: dialogueList = [],
|
||||
refresh: refreshDialogList,
|
||||
loading: listLoading,
|
||||
} = useRequest(async () => {
|
||||
return await apiInterceptors(getDialogueList());
|
||||
});
|
||||
|
||||
// 获取应用详情
|
||||
const { run: queryAppInfo, refresh: refreshAppInfo } = useRequest(
|
||||
async () =>
|
||||
await apiInterceptors(
|
||||
getAppInfo({
|
||||
...currentDialogInfo,
|
||||
}),
|
||||
),
|
||||
{
|
||||
manual: true,
|
||||
onSuccess: (data) => {
|
||||
const [, res] = data;
|
||||
setAppInfo(res || ({} as IApp));
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// 列表当前活跃对话
|
||||
const currentDialogue = useMemo(() => {
|
||||
const [, list] = dialogueList;
|
||||
return list?.find((item) => item.conv_uid === chatId) || ({} as IChatDialogueSchema);
|
||||
}, [chatId, dialogueList]);
|
||||
|
||||
useEffect(() => {
|
||||
const initMessage = getInitMessage();
|
||||
if (currentDialogInfo.chat_scene === scene && !isChatDefault && !(initMessage && initMessage.message)) {
|
||||
queryAppInfo();
|
||||
}
|
||||
}, [chatId, currentDialogInfo, isChatDefault, queryAppInfo, scene]);
|
||||
|
||||
// 获取会话历史记录
|
||||
const {
|
||||
run: getHistory,
|
||||
loading: historyLoading,
|
||||
refresh: refreshHistory,
|
||||
} = useRequest(async () => await apiInterceptors(getChatHistory(chatId)), {
|
||||
manual: true,
|
||||
onSuccess: (data) => {
|
||||
const [, res] = data;
|
||||
const viewList = res?.filter((item) => item.role === 'view');
|
||||
if (viewList && viewList.length > 0) {
|
||||
order.current = viewList[viewList.length - 1].order + 1;
|
||||
}
|
||||
setHistory(res || []);
|
||||
},
|
||||
});
|
||||
|
||||
// 会话提问
|
||||
const handleChat = useCallback(
|
||||
(content: string, data?: Record<string, any>) => {
|
||||
return new Promise<void>((resolve) => {
|
||||
const initMessage = getInitMessage();
|
||||
const ctrl = new AbortController();
|
||||
setReplyLoading(true);
|
||||
if (history && history.length > 0) {
|
||||
const viewList = history?.filter((item) => item.role === 'view');
|
||||
const humanList = history?.filter((item) => item.role === 'human');
|
||||
order.current = (viewList[viewList.length - 1]?.order || humanList[humanList.length - 1]?.order) + 1;
|
||||
}
|
||||
const tempHistory: ChatHistoryResponse = [
|
||||
...(initMessage && initMessage.id === chatId ? [] : history),
|
||||
{ role: 'human', context: content, model_name: data?.model_name || modelValue, order: order.current, time_stamp: 0 },
|
||||
{ role: 'view', context: '', model_name: data?.model_name || modelValue, order: order.current, time_stamp: 0, thinking: true },
|
||||
];
|
||||
const index = tempHistory.length - 1;
|
||||
setHistory([...tempHistory]);
|
||||
chat({
|
||||
data: {
|
||||
chat_mode: scene,
|
||||
model_name: modelValue,
|
||||
user_input: content,
|
||||
...data,
|
||||
},
|
||||
ctrl,
|
||||
chatId,
|
||||
onMessage: (message) => {
|
||||
setCanAbort(true);
|
||||
if (data?.incremental) {
|
||||
tempHistory[index].context += message;
|
||||
tempHistory[index].thinking = false;
|
||||
} else {
|
||||
tempHistory[index].context = message;
|
||||
tempHistory[index].thinking = false;
|
||||
}
|
||||
setHistory([...tempHistory]);
|
||||
},
|
||||
onDone: () => {
|
||||
setReplyLoading(false);
|
||||
setCanAbort(false);
|
||||
resolve();
|
||||
},
|
||||
onClose: () => {
|
||||
setReplyLoading(false);
|
||||
setCanAbort(false);
|
||||
resolve();
|
||||
},
|
||||
onError: (message) => {
|
||||
setReplyLoading(false);
|
||||
setCanAbort(false);
|
||||
tempHistory[index].context = message;
|
||||
tempHistory[index].thinking = false;
|
||||
setHistory([...tempHistory]);
|
||||
resolve();
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
[chatId, history, modelValue, chat, scene],
|
||||
);
|
||||
|
||||
useAsyncEffect(async () => {
|
||||
// 如果是默认小助手,不获取历史记录
|
||||
if (isChatDefault) {
|
||||
return;
|
||||
}
|
||||
const initMessage = getInitMessage();
|
||||
if (initMessage && initMessage.id === chatId) {
|
||||
return;
|
||||
}
|
||||
await getHistory();
|
||||
}, [chatId, scene, getHistory]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isChatDefault) {
|
||||
order.current = 1;
|
||||
setHistory([]);
|
||||
}
|
||||
}, [isChatDefault]);
|
||||
|
||||
return (
|
||||
<ChatContentContext.Provider
|
||||
value={{
|
||||
history,
|
||||
replyLoading,
|
||||
scrollRef,
|
||||
canAbort,
|
||||
chartsData: chartsData || [],
|
||||
agent,
|
||||
currentDialogue,
|
||||
appInfo,
|
||||
temperatureValue,
|
||||
resourceValue,
|
||||
modelValue,
|
||||
setModelValue,
|
||||
setResourceValue,
|
||||
setTemperatureValue,
|
||||
setAppInfo,
|
||||
setAgent,
|
||||
setCanAbort,
|
||||
setReplyLoading,
|
||||
handleChat,
|
||||
refreshDialogList,
|
||||
refreshHistory,
|
||||
refreshAppInfo,
|
||||
setHistory,
|
||||
}}
|
||||
>
|
||||
<Flex flex={1}>
|
||||
<Layout className="bg-gradient-light bg-cover bg-center dark:bg-gradient-dark">
|
||||
<ChatSider
|
||||
refresh={refreshDialogList}
|
||||
dialogueList={dialogueList}
|
||||
listLoading={listLoading}
|
||||
historyLoading={historyLoading}
|
||||
order={order}
|
||||
/>
|
||||
<Layout className="bg-transparent">
|
||||
{isChatDefault ? (
|
||||
<Content>
|
||||
<ChatDefault />
|
||||
</Content>
|
||||
) : (
|
||||
<Spin spinning={historyLoading} className="w-full h-full m-auto">
|
||||
<Content className="flex flex-col h-screen">
|
||||
<ChatContentContainer ref={scrollRef} />
|
||||
<ChatInputPanel ctrl={ctrl} />
|
||||
</Content>
|
||||
</Spin>
|
||||
)}
|
||||
</Layout>
|
||||
</Layout>
|
||||
</Flex>
|
||||
</ChatContentContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default Chat;
|
@@ -1,298 +1,27 @@
|
||||
import ChatContentContainer from '@/ant-components/chat/ChatContentContainer';
|
||||
import ChatDefault from '@/ant-components/chat/content/ChatDefault';
|
||||
import ChatInputPanel from '@/ant-components/chat/input/ChatInputPanel';
|
||||
import ChatSider from '@/ant-components/chat/sider/ChatSider';
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { ChatContext } from '@/app/chat-context';
|
||||
import { apiInterceptors, getAppInfo, getChatHistory, getDialogueList } from '@/client/api';
|
||||
import useChat from '@/hooks/use-chat';
|
||||
import { IApp } from '@/types/app';
|
||||
import { ChartData, ChatHistoryResponse, IChatDialogueSchema } from '@/types/chat';
|
||||
import { getInitMessage } from '@/utils';
|
||||
import { useAsyncEffect, useRequest } from 'ahooks';
|
||||
import { Flex, Layout, Spin } from 'antd';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
const { Content } = Layout;
|
||||
const DbEditor = dynamic(() => import('@/components/chat/db-editor'), { ssr: false });
|
||||
const ChatContainer = dynamic(() => import('@/components/chat/chat-container'), { ssr: false });
|
||||
|
||||
interface ChatContentProps {
|
||||
history: ChatHistoryResponse; // 会话记录列表
|
||||
replyLoading: boolean; // 对话回复loading
|
||||
scrollRef: React.RefObject<HTMLDivElement>; // 会话内容可滚动dom
|
||||
canAbort: boolean; // 是否能中断回复
|
||||
chartsData: ChartData[];
|
||||
agent: string;
|
||||
currentDialogue: IChatDialogueSchema; // 当前选择的会话
|
||||
appInfo: IApp;
|
||||
temperatureValue: any;
|
||||
resourceValue: any;
|
||||
modelValue: string;
|
||||
setModelValue: React.Dispatch<React.SetStateAction<string>>;
|
||||
setTemperatureValue: React.Dispatch<React.SetStateAction<any>>;
|
||||
setResourceValue: React.Dispatch<React.SetStateAction<any>>;
|
||||
setAppInfo: React.Dispatch<React.SetStateAction<IApp>>;
|
||||
setAgent: React.Dispatch<React.SetStateAction<string>>;
|
||||
setCanAbort: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setReplyLoading: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
handleChat: (content: string, data?: Record<string, any>) => Promise<void>; // 处理会话请求逻辑函数
|
||||
refreshDialogList: () => void;
|
||||
refreshHistory: () => void;
|
||||
refreshAppInfo: () => void;
|
||||
setHistory: React.Dispatch<React.SetStateAction<ChatHistoryResponse>>;
|
||||
function Chat() {
|
||||
const {
|
||||
query: { id, scene },
|
||||
} = useRouter();
|
||||
const { isContract, setIsContract, setIsMenuExpand } = useContext(ChatContext);
|
||||
|
||||
useEffect(() => {
|
||||
// 仅初始化执行,防止dashboard页面无法切换状态
|
||||
setIsMenuExpand(scene !== 'chat_dashboard');
|
||||
// 路由变了要取消Editor模式,再进来是默认的Preview模式
|
||||
if (id && scene) {
|
||||
setIsContract(false);
|
||||
}
|
||||
}, [id, scene]);
|
||||
|
||||
return <>{isContract ? <DbEditor /> : <ChatContainer />}</>;
|
||||
}
|
||||
export const ChatContentContext = createContext<ChatContentProps>({
|
||||
history: [],
|
||||
replyLoading: false,
|
||||
scrollRef: { current: null },
|
||||
canAbort: false,
|
||||
chartsData: [],
|
||||
agent: '',
|
||||
currentDialogue: {} as any,
|
||||
appInfo: {} as any,
|
||||
temperatureValue: 0.5,
|
||||
resourceValue: {},
|
||||
modelValue: '',
|
||||
setModelValue: () => {},
|
||||
setResourceValue: () => {},
|
||||
setTemperatureValue: () => {},
|
||||
setAppInfo: () => {},
|
||||
setAgent: () => {},
|
||||
setCanAbort: () => {},
|
||||
setReplyLoading: () => {},
|
||||
refreshDialogList: () => {},
|
||||
refreshHistory: () => {},
|
||||
refreshAppInfo: () => {},
|
||||
setHistory: () => {},
|
||||
handleChat: () => Promise.resolve(),
|
||||
});
|
||||
|
||||
const Chat: React.FC = () => {
|
||||
const { model, currentDialogInfo } = useContext(ChatContext);
|
||||
const { chat, ctrl } = useChat({ app_code: currentDialogInfo.app_code || '' });
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
const chatId = searchParams?.get('id') ?? '';
|
||||
const scene = searchParams?.get('scene') ?? '';
|
||||
const knowledgeId = searchParams?.get('knowledge_id') ?? '';
|
||||
const dbName = searchParams?.get('db_name') ?? '';
|
||||
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const order = useRef<number>(1);
|
||||
|
||||
const [history, setHistory] = useState<ChatHistoryResponse>([]);
|
||||
const [chartsData, setChartsData] = useState<Array<ChartData>>();
|
||||
const [replyLoading, setReplyLoading] = useState<boolean>(false);
|
||||
const [canAbort, setCanAbort] = useState<boolean>(false);
|
||||
const [agent, setAgent] = useState<string>('');
|
||||
const [appInfo, setAppInfo] = useState<IApp>({} as IApp);
|
||||
const [temperatureValue, setTemperatureValue] = useState();
|
||||
const [resourceValue, setResourceValue] = useState<any>();
|
||||
const [modelValue, setModelValue] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
setTemperatureValue(appInfo?.param_need?.filter((item) => item.type === 'temperature')[0]?.value || 0.5);
|
||||
setModelValue(appInfo?.param_need?.filter((item) => item.type === 'model')[0]?.value || model);
|
||||
setResourceValue(Number(knowledgeId) || dbName || appInfo?.param_need?.filter((item) => item.type === 'resource')[0]?.bind_value);
|
||||
}, [appInfo, dbName, knowledgeId, model]);
|
||||
|
||||
// 是否是默认小助手
|
||||
const isChatDefault = useMemo(() => {
|
||||
return !chatId && !scene;
|
||||
}, [chatId, scene]);
|
||||
|
||||
// 获取会话列表
|
||||
const {
|
||||
data: dialogueList = [],
|
||||
refresh: refreshDialogList,
|
||||
loading: listLoading,
|
||||
} = useRequest(async () => {
|
||||
return await apiInterceptors(getDialogueList());
|
||||
});
|
||||
|
||||
// 获取应用详情
|
||||
const { run: queryAppInfo, refresh: refreshAppInfo } = useRequest(
|
||||
async () =>
|
||||
await apiInterceptors(
|
||||
getAppInfo({
|
||||
...currentDialogInfo,
|
||||
}),
|
||||
),
|
||||
{
|
||||
manual: true,
|
||||
onSuccess: (data) => {
|
||||
const [, res] = data;
|
||||
setAppInfo(res || ({} as IApp));
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// 列表当前活跃对话
|
||||
const currentDialogue = useMemo(() => {
|
||||
const [, list] = dialogueList;
|
||||
return list?.find((item) => item.conv_uid === chatId) || ({} as IChatDialogueSchema);
|
||||
}, [chatId, dialogueList]);
|
||||
|
||||
useEffect(() => {
|
||||
const initMessage = getInitMessage();
|
||||
if (currentDialogInfo.chat_scene === scene && !isChatDefault && !(initMessage && initMessage.message)) {
|
||||
queryAppInfo();
|
||||
}
|
||||
}, [chatId, currentDialogInfo, isChatDefault, queryAppInfo, scene]);
|
||||
|
||||
// 获取会话历史记录
|
||||
const {
|
||||
run: getHistory,
|
||||
loading: historyLoading,
|
||||
refresh: refreshHistory,
|
||||
} = useRequest(async () => await apiInterceptors(getChatHistory(chatId)), {
|
||||
manual: true,
|
||||
onSuccess: (data) => {
|
||||
const [, res] = data;
|
||||
const viewList = res?.filter((item) => item.role === 'view');
|
||||
if (viewList && viewList.length > 0) {
|
||||
order.current = viewList[viewList.length - 1].order + 1;
|
||||
}
|
||||
setHistory(res || []);
|
||||
},
|
||||
});
|
||||
|
||||
// 会话提问
|
||||
const handleChat = useCallback(
|
||||
(content: string, data?: Record<string, any>) => {
|
||||
return new Promise<void>((resolve) => {
|
||||
const initMessage = getInitMessage();
|
||||
const ctrl = new AbortController();
|
||||
setReplyLoading(true);
|
||||
if (history && history.length > 0) {
|
||||
const viewList = history?.filter((item) => item.role === 'view');
|
||||
const humanList = history?.filter((item) => item.role === 'human');
|
||||
order.current = (viewList[viewList.length - 1]?.order || humanList[humanList.length - 1]?.order) + 1;
|
||||
}
|
||||
const tempHistory: ChatHistoryResponse = [
|
||||
...(initMessage && initMessage.id === chatId ? [] : history),
|
||||
{ role: 'human', context: content, model_name: data?.model_name || modelValue, order: order.current, time_stamp: 0 },
|
||||
{ role: 'view', context: '', model_name: data?.model_name || modelValue, order: order.current, time_stamp: 0, thinking: true },
|
||||
];
|
||||
const index = tempHistory.length - 1;
|
||||
setHistory([...tempHistory]);
|
||||
chat({
|
||||
data: {
|
||||
chat_mode: scene,
|
||||
model_name: modelValue,
|
||||
user_input: content,
|
||||
...data,
|
||||
},
|
||||
ctrl,
|
||||
chatId,
|
||||
onMessage: (message) => {
|
||||
setCanAbort(true);
|
||||
if (data?.incremental) {
|
||||
tempHistory[index].context += message;
|
||||
tempHistory[index].thinking = false;
|
||||
} else {
|
||||
tempHistory[index].context = message;
|
||||
tempHistory[index].thinking = false;
|
||||
}
|
||||
setHistory([...tempHistory]);
|
||||
},
|
||||
onDone: () => {
|
||||
setReplyLoading(false);
|
||||
setCanAbort(false);
|
||||
resolve();
|
||||
},
|
||||
onClose: () => {
|
||||
setReplyLoading(false);
|
||||
setCanAbort(false);
|
||||
resolve();
|
||||
},
|
||||
onError: (message) => {
|
||||
setReplyLoading(false);
|
||||
setCanAbort(false);
|
||||
tempHistory[index].context = message;
|
||||
tempHistory[index].thinking = false;
|
||||
setHistory([...tempHistory]);
|
||||
resolve();
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
[chatId, history, modelValue, chat, scene],
|
||||
);
|
||||
|
||||
useAsyncEffect(async () => {
|
||||
// 如果是默认小助手,不获取历史记录
|
||||
if (isChatDefault) {
|
||||
return;
|
||||
}
|
||||
const initMessage = getInitMessage();
|
||||
if (initMessage && initMessage.id === chatId) {
|
||||
return;
|
||||
}
|
||||
await getHistory();
|
||||
}, [chatId, scene, getHistory]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isChatDefault) {
|
||||
order.current = 1;
|
||||
setHistory([]);
|
||||
}
|
||||
}, [isChatDefault]);
|
||||
|
||||
return (
|
||||
<ChatContentContext.Provider
|
||||
value={{
|
||||
history,
|
||||
replyLoading,
|
||||
scrollRef,
|
||||
canAbort,
|
||||
chartsData: chartsData || [],
|
||||
agent,
|
||||
currentDialogue,
|
||||
appInfo,
|
||||
temperatureValue,
|
||||
resourceValue,
|
||||
modelValue,
|
||||
setModelValue,
|
||||
setResourceValue,
|
||||
setTemperatureValue,
|
||||
setAppInfo,
|
||||
setAgent,
|
||||
setCanAbort,
|
||||
setReplyLoading,
|
||||
handleChat,
|
||||
refreshDialogList,
|
||||
refreshHistory,
|
||||
refreshAppInfo,
|
||||
setHistory,
|
||||
}}
|
||||
>
|
||||
<Flex flex={1}>
|
||||
<Layout className="bg-gradient-light bg-cover bg-center dark:bg-gradient-dark">
|
||||
<ChatSider
|
||||
refresh={refreshDialogList}
|
||||
dialogueList={dialogueList}
|
||||
listLoading={listLoading}
|
||||
historyLoading={historyLoading}
|
||||
order={order}
|
||||
/>
|
||||
<Layout className="bg-transparent">
|
||||
{isChatDefault ? (
|
||||
<Content>
|
||||
<ChatDefault />
|
||||
</Content>
|
||||
) : (
|
||||
<Spin spinning={historyLoading} className="w-full h-full m-auto">
|
||||
<Content className="flex flex-col h-screen">
|
||||
<ChatContentContainer ref={scrollRef} />
|
||||
<ChatInputPanel ctrl={ctrl} />
|
||||
</Content>
|
||||
</Spin>
|
||||
)}
|
||||
</Layout>
|
||||
</Layout>
|
||||
</Flex>
|
||||
</ChatContentContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default Chat;
|
||||
|
@@ -381,21 +381,6 @@ export default function AppContent() {
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'admin',
|
||||
label: (
|
||||
<span
|
||||
className="flex flex-1"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setAdminOpen(true);
|
||||
setCurApp(item);
|
||||
}}
|
||||
>
|
||||
权限管理
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'del',
|
||||
label: (
|
||||
|
@@ -270,7 +270,9 @@ function Flow() {
|
||||
rightTopHover={false}
|
||||
Tags={
|
||||
<div>
|
||||
<Tag color="green">{flow.source}</Tag>
|
||||
<Tag color={flow.source === 'DBGPT-WEB' ? 'green' : 'blue'}>{flow.source}</Tag>
|
||||
<Tag color={flow.editable ? 'green' : 'gray'}>{flow.editable ? 'Editable' : 'Can not Edit'}</Tag>
|
||||
<Tag color={flow.state === 'load_failed' ? 'red' : flow.state === 'running' ? 'green' : 'blue'}>{flow.state}</Tag>
|
||||
</div>
|
||||
}
|
||||
LeftBottom={
|
||||
|
@@ -257,6 +257,7 @@ const AddOrEditPrompt: React.FC = () => {
|
||||
},
|
||||
onmessage: (event) => {
|
||||
let message = event.data;
|
||||
if (!message) return;
|
||||
try {
|
||||
message = JSON.parse(message).vis;
|
||||
} catch (e) {
|
||||
|
Reference in New Issue
Block a user