MCPcopy
hub / github.com/Zleap-AI/SAG / ConversationWorkspace

Function ConversationWorkspace

web/src/App.tsx:1636–1773  ·  view source on GitHub ↗
(props: {
  project: SourceRecord | null;
  detail: McpSessionDetail | null;
  input: string;
  isRunning: boolean;
  pendingUserMessage: string;
  streamingAssistantText: string;
  runningMcpSearches: RunningMcpSearch[];
  onInputChange: (value: string) => void;
  onClearSession: () => void;
  onDeleteSession: () => void;
  onOpenCitation: (citation: AnswerCitation) => void;
  onStop: () => void;
  onSend: () => void;
})

Source from the content-addressed store, hash-verified

1634}
1635
1636function ConversationWorkspace(props: {
1637 project: SourceRecord | null;
1638 detail: McpSessionDetail | null;
1639 input: string;
1640 isRunning: boolean;
1641 pendingUserMessage: string;
1642 streamingAssistantText: string;
1643 runningMcpSearches: RunningMcpSearch[];
1644 onInputChange: (value: string) => void;
1645 onClearSession: () => void;
1646 onDeleteSession: () => void;
1647 onOpenCitation: (citation: AnswerCitation) => void;
1648 onStop: () => void;
1649 onSend: () => void;
1650}) {
1651 const { t } = useI18n();
1652 const scrollAnchorRef = useRef<HTMLDivElement | null>(null);
1653
1654 useEffect(() => {
1655 scrollAnchorRef.current?.scrollIntoView({ block: "end" });
1656 }, [props.detail?.messages.length, props.pendingUserMessage, props.streamingAssistantText, props.isRunning, props.runningMcpSearches.length]);
1657
1658 if (!props.project) {
1659 return (
1660 <section className="flex min-h-0 flex-1 items-center justify-center px-6">
1661 <EmptyState title={t("先创建项目", "Create a project first")} description={t("项目是文档、切片、事件、实体和 MCP 对话的共同归属。", "A project contains documents, chunks, events, entities, and MCP chats.")} />
1662 </section>
1663 );
1664 }
1665
1666 return (
1667 <section className="flex min-h-0 flex-1 flex-col">
1668 <div className="flex shrink-0 flex-wrap items-start justify-between gap-3 border-b border-border px-4 py-3 md:flex-nowrap md:items-center md:px-6">
1669 <div className="min-w-0">
1670 <h1 className="truncate text-base font-semibold">{props.detail?.session.title ?? t("新对话", "New chat")}</h1>
1671 <p className="truncate text-xs text-muted-foreground">
1672 {props.detail ? `${formatModelName(props.detail.session.model, t)} · ${shortId(props.detail.session.id)}` : t("新建会话后开始测试 MCP 工具", "Create a chat to test MCP tools")}
1673 </p>
1674 </div>
1675 <div className="flex min-w-0 flex-wrap items-center justify-end gap-2">
1676 <Button variant="outline" size="sm" onClick={props.onClearSession} disabled={!props.detail || props.isRunning}>
1677 <RotateCcw className="h-4 w-4" />
1678 {t("清空记录", "Clear history")}
1679 </Button>
1680 <Button variant="outline" size="sm" onClick={props.onDeleteSession} disabled={!props.detail || props.isRunning}>
1681 <Trash2 className="h-4 w-4" />
1682 {t("删除对话", "Delete chat")}
1683 </Button>
1684 </div>
1685 </div>
1686
1687 <div className="min-h-0 flex-1 overflow-y-auto px-4 py-4 md:px-6">
1688 <div className="mx-auto flex max-w-3xl flex-col gap-3">
1689 {!props.detail || props.detail.messages.length === 0 ? (
1690 <EmptyState title={t("还没有对话", "No conversation yet")} description={t("输入问题后,系统会通过 MCP 工具检索当前项目资料。", "Ask a question and the system will retrieve current project documents through MCP tools.")} />
1691 ) : props.detail.messages.map((message) => {
1692 const citations = getMessageCitations(message);
1693 return (

Callers

nothing calls this directly

Calls 9

useI18nFunction · 0.90
shortIdFunction · 0.90
cnFunction · 0.90
formatDateFunction · 0.90
tFunction · 0.85
formatModelNameFunction · 0.85
getMessageCitationsFunction · 0.85
formatMessageRoleFunction · 0.85
formatMessageContentFunction · 0.85

Tested by

no test coverage detected