fix: replay compact traces after route switches

This commit is contained in:
Codex Agent
2026-06-06 00:46:32 +08:00
parent ee2dae894f
commit 3b04a0cf5b
2 changed files with 20 additions and 4 deletions
@@ -46,3 +46,16 @@ test("conversation panel asks trace panels to collapse after final response appe
assert.match(source, /collapseWhenFinalResponse=\{hasFinalResponse\}/u);
});
test("conversation panel does not consume replay opportunity before timer fires", async () => {
const source = await Bun.file(new URL("./ConversationPanel.tsx", import.meta.url)).text();
const effectStart = source.indexOf("const replayRequestedTraceRef = useRef<string | null>(null);");
const timerStart = source.indexOf("const timer = window.setTimeout", effectStart);
const markRequested = source.indexOf("replayRequestedTraceRef.current = traceId", effectStart);
const replayCall = source.indexOf("onReplayTrace();", effectStart);
assert.ok(effectStart > 0, "replay guard ref exists");
assert.ok(timerStart > effectStart, "auto replay uses delayed timer");
assert.ok(markRequested > timerStart, "route changes that cancel the timer must not mark replay as already requested");
assert.ok(replayCall > markRequested, "replay is marked requested only immediately before dispatching replay");
});
@@ -130,12 +130,15 @@ const HISTORICAL_TRACE_REPLAY_DELAY_MS = 4500;
function MessageCard({ message, firstScreenHistory, codeAgentTimeoutMs, onCancel, onRetry, onReplayTrace }: { message: ChatMessage; firstScreenHistory: boolean; codeAgentTimeoutMs: number; onCancel(): void; onRetry(): void; onReplayTrace(): void }): ReactElement {
const traceKey = `hwlab.workbench.trace-open.${message.traceId ?? message.id}`;
const replayRequestedRef = useRef(false);
const replayRequestedTraceRef = useRef<string | null>(null);
useEffect(() => {
if (replayRequestedRef.current) return;
const traceId = message.traceId ?? message.runnerTrace?.traceId ?? null;
if (traceId && replayRequestedTraceRef.current === traceId) return;
if (!shouldAutoReplayTrace(message)) return;
replayRequestedRef.current = true;
const timer = window.setTimeout(() => onReplayTrace(), HISTORICAL_TRACE_REPLAY_DELAY_MS);
const timer = window.setTimeout(() => {
replayRequestedTraceRef.current = traceId;
onReplayTrace();
}, HISTORICAL_TRACE_REPLAY_DELAY_MS);
return () => window.clearTimeout(timer);
}, [message, onReplayTrace]);
if (message.role === "agent") {