121 lines
5.1 KiB
TypeScript
121 lines
5.1 KiB
TypeScript
import { App as AntApp, Empty } from 'antd';
|
||
import type { DesktopViewport } from '../../../hooks/useDesktopViewport';
|
||
import { desktopViewportClass } from '../../../hooks/useDesktopViewport';
|
||
import type { ModelOverrides } from '../../../api';
|
||
import type { ChatPageLogicOutput } from '../ChatPageLogic';
|
||
import { markdownToPlainText } from '../utils/copy';
|
||
import AgentSidebar from './AgentSidebar';
|
||
import ChatBody from './ChatBody';
|
||
import ChatDrawers from './ChatDrawers';
|
||
import ChatHeader from './ChatHeader';
|
||
import ChatInput from './ChatInput';
|
||
import ChatOutline from './ChatOutline';
|
||
|
||
export interface ChatPageWebVariantProps {
|
||
logic: ChatPageLogicOutput;
|
||
viewport: DesktopViewport;
|
||
}
|
||
|
||
export default function ChatPageWebBase({ logic, viewport }: ChatPageWebVariantProps) {
|
||
const { message } = AntApp.useApp();
|
||
const { id, roomId, highlightId, historyDrawerOpen, mcpDrawerOpen, paramsDrawerOpen, tplDrawerOpen } = logic;
|
||
const { agent, agentList, messages, branches, bodyRef, sender, navigate, overrides } = logic;
|
||
const { setOverrides, setRoomId, setHighlightId, handleNewSession } = logic;
|
||
const { setHistoryDrawerOpen, setMcpDrawerOpen, setParamsDrawerOpen, setTplDrawerOpen } = logic;
|
||
|
||
return (
|
||
<div className={`chat-shell ${desktopViewportClass(viewport)}`}>
|
||
<AgentSidebar agentList={agentList} activeAgentId={id} onCreate={() => navigate('/agents/new')} onSelect={(aid) => navigate(`/chat/${aid}`)} />
|
||
|
||
<section className="chat-main">
|
||
{!agent ? (
|
||
<div className="chat-empty-state">
|
||
<Empty description="请在左侧选择一个智能体开始对话" />
|
||
</div>
|
||
) : (
|
||
<>
|
||
<ChatHeader
|
||
agent={agent}
|
||
useStream={sender.useStream}
|
||
setUseStream={sender.setUseStream}
|
||
onOpenHistory={() => setHistoryDrawerOpen(true)}
|
||
onOpenParams={() => setParamsDrawerOpen(true)}
|
||
onOpenMcp={() => setMcpDrawerOpen(true)}
|
||
onManageAgent={() => navigate(`/agents/${id}`)}
|
||
onClear={sender.handleClear}
|
||
/>
|
||
<div className="chat-content-row">
|
||
<ChatBody
|
||
bodyRef={bodyRef}
|
||
agent={agent}
|
||
agentList={agentList}
|
||
currentAgentId={id!}
|
||
messages={messages}
|
||
branches={branches}
|
||
highlightId={highlightId}
|
||
sending={sender.sending}
|
||
streaming={sender.streaming}
|
||
onRegenerate={sender.handleRegenerate}
|
||
onSwitchBranch={sender.handleSwitchBranch}
|
||
onCopy={(text, mode) => {
|
||
const content = mode === 'markdown' ? text : markdownToPlainText(text);
|
||
navigator.clipboard?.writeText(content).then(() => message.success(mode === 'markdown' ? '已复制(Markdown)' : '已复制(纯文本)'));
|
||
}}
|
||
/>
|
||
<ChatOutline messages={messages} activeId={highlightId} onJump={(msgId) => {
|
||
setHighlightId(msgId);
|
||
document.getElementById('msg-' + msgId)?.scrollIntoView({ block: 'start', behavior: 'smooth' });
|
||
}} />
|
||
</div>
|
||
<ChatInput
|
||
input={sender.input}
|
||
setInput={sender.setInput}
|
||
sending={sender.sending}
|
||
attachments={sender.attachments}
|
||
setAttachments={sender.setAttachments}
|
||
imageUrls={sender.imageUrls}
|
||
setImageUrls={sender.setImageUrls}
|
||
onSend={sender.handleSend}
|
||
onStop={sender.handleStop}
|
||
onAttach={sender.handleAttach}
|
||
onOpenTpl={() => setTplDrawerOpen(true)}
|
||
modelOptions={sender.modelOptions}
|
||
activeModelValue={sender.activeModelValue}
|
||
onChangeModel={(modelId) => {
|
||
const picked = sender.modelOptions.find((o) => o.value === modelId);
|
||
setOverrides((o: ModelOverrides) => ({ ...o, model_id: modelId, model: picked?.label ?? o.model }));
|
||
}}
|
||
agentList={agentList}
|
||
onInsertMention={() => {}}
|
||
onOpenHistory={() => setHistoryDrawerOpen(true)}
|
||
onNewSession={handleNewSession}
|
||
/>
|
||
</>
|
||
)}
|
||
</section>
|
||
|
||
<ChatDrawers
|
||
agentId={id}
|
||
agent={agent}
|
||
input={sender.input}
|
||
setInput={(updater) => sender.setInput(updater)}
|
||
overrides={overrides}
|
||
setOverrides={setOverrides}
|
||
roomId={roomId}
|
||
setRoomId={setRoomId}
|
||
setHighlightId={setHighlightId}
|
||
sessionRefresh={sender.sessionRefresh}
|
||
mcpDrawerOpen={mcpDrawerOpen}
|
||
setMcpDrawerOpen={setMcpDrawerOpen}
|
||
tplDrawerOpen={tplDrawerOpen}
|
||
setTplDrawerOpen={setTplDrawerOpen}
|
||
paramsDrawerOpen={paramsDrawerOpen}
|
||
setParamsDrawerOpen={setParamsDrawerOpen}
|
||
historyDrawerOpen={historyDrawerOpen}
|
||
setHistoryDrawerOpen={setHistoryDrawerOpen}
|
||
notify={{ success: (t) => message.success(t) }}
|
||
/>
|
||
</div>
|
||
);
|
||
}
|