| | |
| | | import AddCommentOutlinedIcon from "@mui/icons-material/AddCommentOutlined"; |
| | | import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined"; |
| | | import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; |
| | | import AutoDeleteOutlinedIcon from "@mui/icons-material/AutoDeleteOutlined"; |
| | | import HistoryOutlinedIcon from "@mui/icons-material/HistoryOutlined"; |
| | | import PushPinOutlinedIcon from "@mui/icons-material/PushPinOutlined"; |
| | | import PushPinIcon from "@mui/icons-material/PushPin"; |
| | | import SearchOutlinedIcon from "@mui/icons-material/SearchOutlined"; |
| | | import { getAiRuntime, getAiSessions, pinAiSession, removeAiSession, renameAiSession, streamAiChat } from "@/api/ai/chat"; |
| | | import { clearAiSessionMemory, getAiRuntime, getAiSessions, pinAiSession, removeAiSession, renameAiSession, retainAiSessionLatestRound, streamAiChat } from "@/api/ai/chat"; |
| | | |
| | | const DEFAULT_PROMPT_CODE = "home.default"; |
| | | |
| | |
| | | promptName: runtime?.promptName || "--", |
| | | model: runtime?.model || "--", |
| | | mountedMcpCount: runtime?.mountedMcpCount ?? 0, |
| | | recentMessageCount: runtime?.recentMessageCount ?? 0, |
| | | hasSummary: !!runtime?.memorySummary, |
| | | hasFacts: !!runtime?.memoryFacts, |
| | | }; |
| | | }, [runtime]); |
| | | |
| | |
| | | await loadSessions(sessionKeyword); |
| | | } catch (error) { |
| | | const message = error.message || "重命名会话失败"; |
| | | setDrawerError(message); |
| | | notify(message, { type: "error" }); |
| | | } |
| | | }; |
| | | |
| | | const handleClearMemory = async () => { |
| | | if (streaming || !sessionId) { |
| | | return; |
| | | } |
| | | try { |
| | | await clearAiSessionMemory(sessionId); |
| | | notify("会话记忆已清空"); |
| | | await Promise.all([ |
| | | loadRuntime(sessionId), |
| | | loadSessions(sessionKeyword), |
| | | ]); |
| | | } catch (error) { |
| | | const message = error.message || "清空会话记忆失败"; |
| | | setDrawerError(message); |
| | | notify(message, { type: "error" }); |
| | | } |
| | | }; |
| | | |
| | | const handleRetainLatestRound = async () => { |
| | | if (streaming || !sessionId) { |
| | | return; |
| | | } |
| | | try { |
| | | await retainAiSessionLatestRound(sessionId); |
| | | notify("已仅保留当前轮记忆"); |
| | | await Promise.all([ |
| | | loadRuntime(sessionId), |
| | | loadSessions(sessionKeyword), |
| | | ]); |
| | | } catch (error) { |
| | | const message = error.message || "保留当前轮记忆失败"; |
| | | setDrawerError(message); |
| | | notify(message, { type: "error" }); |
| | | } |
| | |
| | | <Chip size="small" label={`Model: ${runtimeSummary.model}`} /> |
| | | <Chip size="small" label={`MCP: ${runtimeSummary.mountedMcpCount}`} /> |
| | | <Chip size="small" label={`History: ${persistedMessages.length}`} /> |
| | | <Chip size="small" label={`Recent: ${runtimeSummary.recentMessageCount}`} /> |
| | | <Chip size="small" color={runtimeSummary.hasSummary ? "success" : "default"} label={runtimeSummary.hasSummary ? "有摘要" : "无摘要"} /> |
| | | <Chip size="small" color={runtimeSummary.hasFacts ? "info" : "default"} label={runtimeSummary.hasFacts ? "有事实" : "无事实"} /> |
| | | </Stack> |
| | | <Stack direction="row" spacing={1} mt={1.5} flexWrap="wrap" useFlexGap> |
| | | {quickLinks.map((item) => ( |
| | |
| | | {item.label} |
| | | </Button> |
| | | ))} |
| | | <Button |
| | | size="small" |
| | | variant="outlined" |
| | | startIcon={<HistoryOutlinedIcon />} |
| | | onClick={handleRetainLatestRound} |
| | | disabled={!sessionId || streaming} |
| | | > |
| | | 仅保留当前轮 |
| | | </Button> |
| | | <Button |
| | | size="small" |
| | | variant="outlined" |
| | | color="warning" |
| | | startIcon={<AutoDeleteOutlinedIcon />} |
| | | onClick={handleClearMemory} |
| | | disabled={!sessionId || streaming} |
| | | > |
| | | 清空记忆 |
| | | </Button> |
| | | </Stack> |
| | | {!!runtime?.memorySummary && ( |
| | | <Alert severity="info" sx={{ mt: 1.5 }}> |
| | | <Typography variant="body2" sx={{ whiteSpace: "pre-wrap" }}> |
| | | {runtime.memorySummary} |
| | | </Typography> |
| | | </Alert> |
| | | )} |
| | | {!!runtime?.memoryFacts && ( |
| | | <Alert severity="success" sx={{ mt: 1.5 }}> |
| | | <Typography variant="body2" sx={{ whiteSpace: "pre-wrap" }}> |
| | | {runtime.memoryFacts} |
| | | </Typography> |
| | | </Alert> |
| | | )} |
| | | {loadingRuntime && ( |
| | | <Typography variant="body2" color="text.secondary" mt={1}> |
| | | 正在加载 AI 运行时信息... |