- 深链 ?taskId=&goPath=*-A 透传 taskId 进会商,按 taskId 隔离存取草稿(一个 taskId 多条、可新建);
后端新增 GET /api/roundtable-drafts/by-task/{id} 列表 + RoundtableJobRepository.status_map_by_drafts 富化。
- 第三步生成 md 报告后自动结构化输出流程图(仅 taskId 模式):有报告基于报告、无报告基于各席位交付,
整段内联数据来源逐条抽取;层级优先用业务链总控提示词写明的层级,否则用 stages 的 goal。
- 流程图节点加 group(层级名)标签 + detail(条目名称+理由);强 prompt 压制 coordinatorPrompt 报告锚定,
禁阶段编号节点;FLOW_STRUCTURE_RULE 精确画法(根=任务、每层每条成节点、按对应关系串分支、排除汇总段落)。
- flow-graph 解析容错:JSON.parse 失败退回正则逐字段抽取,兼容裸换行/尾逗号,避免节点被整体丢弃。
- 修:重开第二步后第三步基于新一轮分析重新生成(复位 step3 闸门 + 中断旧三流)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
133 lines
4.9 KiB
TypeScript
133 lines
4.9 KiB
TypeScript
/**
|
|
* Step 3 主面板 —— 方案结果展示。
|
|
*
|
|
* 当前是 `HighFidelityReport` 的薄壳;放它在这里只是为了让 Step 1 / Step 2 /
|
|
* Step 3 三步在主页面里以同样的导入风格出现,方便阅读。
|
|
*
|
|
* Step 3 真实逻辑请改 `HighFidelityReport.tsx` —— 包括各席位 artifact
|
|
* 拉取 / 文本类预览 / window.open 下载 / 「重新起草」按钮等。
|
|
*/
|
|
import { HighFidelityReport } from "@/roundtable-planning/components/HighFidelityReport";
|
|
import type {
|
|
DraftStep3Snapshot,
|
|
DraftStep3SummarySnapshot,
|
|
} from "@/roundtable-planning/api/drafts";
|
|
import type { ModelOption } from "@/roundtable-planning/components/Step3ReportMode";
|
|
import type { Step2Dialogue } from "@/roundtable-planning/hooks/useStep2Orchestration";
|
|
import type { UseStep3DashboardReturn } from "@/roundtable-planning/hooks/useStep3Dashboard";
|
|
import type { ReportIntent, UseStep3ReportReturn } from "@/roundtable-planning/hooks/useStep3Report";
|
|
import type { UseStep3SummaryReturn } from "@/roundtable-planning/hooks/useStep3Summary";
|
|
import type { ThreadIdMap } from "@/roundtable-planning/api/multi-agent";
|
|
import { stripReasoning } from "@/roundtable-planning/lib/reasoning";
|
|
import { useMemo } from "react";
|
|
|
|
export interface Step3PanelProps {
|
|
threadIds: ThreadIdMap | null;
|
|
coordinatorName: string | null;
|
|
consensusText: string;
|
|
hasConsensus: boolean;
|
|
step2RoundtableDialogues: Step2Dialogue[];
|
|
agentNameToRole: Record<
|
|
string,
|
|
{ speakerId: number; avatarType: string; displayName: string }
|
|
>;
|
|
/** Step 1 结构化意图 + 当前模型 —— 透传给「结果绘制」的方案可视化智能体。 */
|
|
intentReady: ReportIntent | null;
|
|
selectedModel: string;
|
|
/** 可选模型列表 + 加载态 + 切换器 —— 透传给「结果绘制」的模型选择。 */
|
|
availableModels: ReadonlyArray<ModelOption>;
|
|
modelsLoading: boolean;
|
|
setSelectedModel: (model: string) => void;
|
|
/** 草稿里已存的上次绘制结果 + 完成回调 —— 透传给「结果绘制」做持久化。 */
|
|
savedReport?: DraftStep3Snapshot | null;
|
|
onReportSaved?: (snapshot: DraftStep3Snapshot) => void;
|
|
/** 业务链写给总控的编排提示 —— 注入「总结报告」智能体。 */
|
|
coordinatorPrompt?: string | null;
|
|
/** 草稿里已存的上次总结结果 + 完成回调 —— 透传给「总结报告」做持久化。 */
|
|
savedSummary?: DraftStep3SummarySnapshot | null;
|
|
onSummarySaved?: (snapshot: DraftStep3SummarySnapshot) => void;
|
|
/** 页面层常驻的三个 Step3 生成流(2026-06-13 提升:切走不断流,进入续看)。 */
|
|
summaryFlow: UseStep3SummaryReturn;
|
|
reportFlow: UseStep3ReportReturn;
|
|
dashboardFlow: UseStep3DashboardReturn;
|
|
onReset: () => void;
|
|
/** Step 2 沙箱预览产出文件(与第二步相同)。 */
|
|
openArtifactPreview: (threadId: string, path: string) => void;
|
|
seatStubMessages: Record<string, unknown[]>;
|
|
}
|
|
|
|
export function Step3Panel(props: Step3PanelProps) {
|
|
const {
|
|
threadIds,
|
|
coordinatorName,
|
|
consensusText,
|
|
hasConsensus,
|
|
step2RoundtableDialogues,
|
|
agentNameToRole,
|
|
intentReady,
|
|
selectedModel,
|
|
availableModels,
|
|
modelsLoading,
|
|
setSelectedModel,
|
|
savedReport,
|
|
onReportSaved,
|
|
coordinatorPrompt,
|
|
savedSummary,
|
|
onSummarySaved,
|
|
summaryFlow,
|
|
reportFlow,
|
|
dashboardFlow,
|
|
onReset,
|
|
openArtifactPreview,
|
|
seatStubMessages,
|
|
} = props;
|
|
|
|
const seatDeliveries = useMemo(
|
|
() =>
|
|
step2RoundtableDialogues
|
|
.filter((d) => d.confidence === "子智能体交付")
|
|
.map((d) => ({
|
|
sender: String(d.sender ?? ""),
|
|
avatarType: String(d.avatarType ?? "blue"),
|
|
// 交付内容只保留模型生成的主体输出,剥离 `<think>...</think>` 推理过程
|
|
// —— 既用于渲染各席位交付卡片,也会喂给总结/报告模型,避免推理噪声污染。
|
|
content: stripReasoning(String(d.content ?? "")),
|
|
})),
|
|
[step2RoundtableDialogues],
|
|
);
|
|
|
|
const seatNameMap = useMemo(
|
|
() => Object.fromEntries(
|
|
Object.entries(agentNameToRole).map(([k, v]) => [k, v.displayName]),
|
|
),
|
|
[agentNameToRole],
|
|
);
|
|
|
|
return (
|
|
<HighFidelityReport
|
|
threadIds={threadIds}
|
|
coordinatorName={coordinatorName}
|
|
consensusText={consensusText}
|
|
hasConsensus={hasConsensus}
|
|
seatDeliveries={seatDeliveries}
|
|
seatNameMap={seatNameMap}
|
|
intentReady={intentReady}
|
|
selectedModel={selectedModel}
|
|
availableModels={availableModels}
|
|
modelsLoading={modelsLoading}
|
|
setSelectedModel={setSelectedModel}
|
|
savedReport={savedReport}
|
|
onReportSaved={onReportSaved}
|
|
coordinatorPrompt={coordinatorPrompt}
|
|
savedSummary={savedSummary}
|
|
onSummarySaved={onSummarySaved}
|
|
summaryFlow={summaryFlow}
|
|
reportFlow={reportFlow}
|
|
dashboardFlow={dashboardFlow}
|
|
onReset={onReset}
|
|
openArtifactPreview={openArtifactPreview}
|
|
seatStubMessages={seatStubMessages}
|
|
/>
|
|
);
|
|
}
|