fix(roundtable): 第三步重新分析前复位入库状态,避免重分析后仍问是否入库

重跑总结/重新或修改流程图前整体复位 ingest 状态为 idle(隐藏旧产物的入库
询问卡/协助卡/手动入库按钮);流程图类重分析出新图后 runFlowExtract 在 idle
时重新询问,重新生成报告则在报告重写完成后(若已有流程图)重新询问是否入库。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
董宏凯andClaude Opus 4.8 committed 2026-06-21 20:43:06 +08:00
1 parent 6dd1f9c017
commit 545ec178b8
1 file changed
+32 -1
@@ -509,6 +509,14 @@ export function useStep3Summary(
useEffect(() => {
ingestStatusRef.current = ingestStatus;
}, [ingestStatus]);
// 重新分析(重跑总结 / 重新或修改流程图)前把入库状态整体复位为 idle —— 旧报告/旧流程图的
// 「是否入库」询问卡、入库协助卡、手动入库按钮全部初始化隐藏,避免「都重新分析了还问是否入库」
// 的歧义。流程图类重分析完成后 runFlowExtract 会在 idle 时重新发起入库询问。
const resetIngestState = useCallback(() => {
setIngestStatus("idle");
setPendingIngestClarification(null);
setPendingFlowForIngest(false);
}, []);
// 入库功能「有效可用」= 技能可用 **且** 处于深链(taskId)模式。
const ingestEnabled = !!ingestAvailable && !!ingestTaskId;
const ingestAvailableRef = useRef<boolean>(ingestEnabled);
@@ -1237,10 +1245,12 @@ export function useStep3Summary(
const regenerateFlow = useCallback(() => {
if (!currentMdRef.current.trim() && seatDeliveries.length === 0) return;
aborterRef.current?.abort();
// 重画流程图 = 重新分析 → 先复位入库状态(隐藏旧图的入库询问/按钮),新图生成完会重新询问。
resetIngestState();
const aborter = new AbortController();
aborterRef.current = aborter;
void runFlowExtract(aborter);
}, [runFlowExtract, seatDeliveries]);
}, [runFlowExtract, seatDeliveries, resetIngestState]);
/** Phase 3:画布手动改/删节点后回写图 + 持久化(序列化进草稿快照)。 */
const updateFlowGraph = useCallback(
@@ -1273,6 +1283,9 @@ export function useStep3Summary(
setSeatStubMessages({});
setFlowGraphState(null);
setFlowPhase("idle");
// 整体重跑(重试 / 重新生成)= 重新分析 → 复位入库状态,旧产物的入库询问/按钮先隐藏;
// 重跑出新流程图后 runFlowExtract 会重新询问是否入库。
resetIngestState();
const aborter = new AbortController();
aborterRef.current = aborter;
@@ -1330,6 +1343,7 @@ export function useStep3Summary(
finalizeDialogue,
streamOnce,
runFlowExtract,
resetIngestState,
]);
/**
@@ -1545,6 +1559,8 @@ export function useStep3Summary(
// 带附件时跳过分类(附件多用于报告 Q&A/改报告);澄清后用户点选则用 forcedIntent 跳过分类。
// reuseBubbleId:意图分类期间先建的「调度中」气泡,定了意图后由对应分支复用(不等接口返回、像第一步)。
let reuseBubbleId: number | null = null;
// 「重新生成报告」复位入库状态后,待报告重写完成、若已有流程图则重新询问是否入库。
let reaskIngestAfter = false;
if (text && !hasFiles) {
let intent: FlowIntent | undefined = opts?.forcedIntent;
let dispatchBubbleId: number | null = null;
@@ -1580,6 +1596,9 @@ export function useStep3Summary(
return;
}
if (intent === "regenerate_flow" || intent === "modify_flow") {
// 重新/修改流程图 = 重新分析 → 先复位入库状态(隐藏旧图入库询问/按钮),
// runFlowExtract 出新图后会在 idle 时重新询问是否入库。
resetIngestState();
const flowAborter = new AbortController();
aborterRef.current = flowAborter;
const cur = flowGraphRef.current;
@@ -1593,6 +1612,12 @@ export function useStep3Summary(
}
// regenerate_report | qa → 复用调度气泡走下方总结线程路径。
reuseBubbleId = dispatchBubbleId;
// 重新生成报告 = 重新分析 → 复位入库状态先隐藏旧的入库询问/按钮(qa 仅提问不复位);
// 报告重写完后若已有流程图,再重新询问是否入库(见 streamOnce 收尾后的 reaskIngestAfter)。
if (intent === "regenerate_report") {
resetIngestState();
reaskIngestAfter = true;
}
// intent === "regenerate_report" | "qa" → 落到下方总结线程续问路径:
// **追加**用户气泡 + 在原线程上让智能体重写报告 / 增量改 / 回答(**不清空历史**)。
// regenerate_report 不再走 run()(run 会 setDialogues([]) 清空,导致"覆盖聊天记录、
@@ -1688,6 +1713,11 @@ export function useStep3Summary(
flowRound,
});
}
if (aborter.signal.aborted) return;
// 报告重写完成、且入库可用 + 已有流程图 → 重新询问是否入库(复位后再问,针对新报告)。
if (reaskIngestAfter && ingestAvailableRef.current && flowGraphRef.current) {
setIngestStatus("asking");
}
} catch (err) {
if (aborter.signal.aborted) return;
const msg = err instanceof Error ? err.message : String(err);
@@ -1713,6 +1743,7 @@ export function useStep3Summary(
streamOnce,
runFlowExtract,
runIngest,
resetIngestState,
],
);