Files
deerflow-code/frontend-web/src/report-collaboration/hooks/useReportCollaborationMessages.ts
T
董宏凯 438772f0b7 feat(frontend): 上线报告协作与多轮 RAG 消息聚合体验
功能说明:\n- 新增报告协作页(Report Collaboration)核心状态层、消息适配与会话面板,支持按节点/阶段选择和协作上下文展示\n- 补齐 report-collaboration API 与类型定义,并接入页面路由/构建路径,形成可运行的协作链路\n- 重构多轮 RAG 与 write/artefact 消息分组逻辑,优化 AgentChat 与 DeepResearch 场景下的消息展示顺序与可读性\n- 新增/更新 DeepResearch 前端页面(Workbench、报告配置、沙箱联动)以承接报告生成与复用能力\n- 增加报表协作相关单测,覆盖事件归并、消息适配与关键 reducer 行为
2026-09-04 23:18:27 +08:00

71 lines
2.7 KiB
TypeScript

/**
* 消息组装 hook:状态 → 聚焦过滤 → LangGraph Message[] → BaseStream 外观。
*
* - 并行执行中只显示当前成员;结束后把各成员收成普通聊天记录,不重拉不改写。
* - 虚拟业务卡(方案组 / 命令确认 / 报告入口)由页面以 extraCards 传入,
* 经 MessageList 的 businessCardSlot 渲染。
*/
import { useMemo } from "react";
import type { Message } from "@langchain/langgraph-sdk";
import type { BaseStream } from "@langchain/langgraph-sdk/react";
import type { AgentThreadState } from "@/core/threads";
import type { CollaborationMessage } from "@/report-collaboration/api/types";
import type { CollaborationState } from "@/report-collaboration/state/event-reducer";
import {
buildBaseStreamFacade,
buildReportWriteFileMessages,
reportWriteFileBelongsToFocus,
toLangGraphMessages,
} from "@/report-collaboration/state/message-adapter";
import {
selectConversationMessages,
selectHeadReportVersion,
selectOrderedVisibleMessages,
selectWriterAgentRun,
} from "@/report-collaboration/state/selectors";
export interface UseReportCollaborationMessagesResult {
visibleMessages: CollaborationMessage[];
focusedMessages: CollaborationMessage[];
displayMessages: Message[];
displayThread: BaseStream<AgentThreadState>;
/** 存在未完成消息(流式中)。 */
streaming: boolean;
}
export function useReportCollaborationMessages(
state: CollaborationState,
focusedAgentRunId: string | null,
extraCards: Message[],
extraLoading: boolean,
): UseReportCollaborationMessagesResult {
return useMemo(() => {
const visibleMessages = selectOrderedVisibleMessages(state);
const focusedMessages = selectConversationMessages(state, focusedAgentRunId);
const base = toLangGraphMessages(focusedMessages);
const writeFiles = reportWriteFileBelongsToFocus(
buildReportWriteFileMessages({
sessionId: state.sessionId,
markdown: state.reportDraft?.markdown || selectHeadReportVersion(state)?.markdown || "",
writing: Boolean(state.reportDraft),
writer: selectWriterAgentRun(state),
}),
focusedAgentRunId,
);
const displayMessages =
extraCards.length > 0 || writeFiles.length > 0
? [...base, ...writeFiles, ...extraCards]
: base;
const streamSource = focusedAgentRunId ? focusedMessages : visibleMessages;
const streaming =
streamSource.some((message) => !message.completed_at && message.role !== "human") ||
Boolean(state.reportDraft) ||
extraLoading;
const displayThread = buildBaseStreamFacade(displayMessages, streaming);
return { visibleMessages, focusedMessages, displayMessages, displayThread, streaming };
}, [extraCards, extraLoading, focusedAgentRunId, state]);
}