fix: keep replay cancellation honest

This commit is contained in:
lda
2026-07-09 09:21:39 +07:00 Verified
parent cf3cac1fc8
commit 7db9f5e0b1
4 changed files with 57 additions and 4 deletions
@@ -89,4 +89,25 @@ describe("useTimelineAgent", () => {
const { result } = renderHook(() => useTimelineAgent(demo, "live"));
expect(result.current.canRun).toBe(false);
});
it("does not advance replay cancellation into the submitted recording branch", async () => {
const cancelReview = vi.fn(async () => {});
const next = vi.fn(async () => {});
const demo = demoController({
state: { ...initialDemoTimelineState, mode: "replay", phase: "review" },
cancelReview,
next,
});
const { result } = renderHook(() => useTimelineAgent(demo, "replay"));
await act(async () => result.current.cancelReview());
expect(cancelReview).toHaveBeenCalledWith("Cancelled by operator.");
expect(next).not.toHaveBeenCalled();
expect(result.current.messages.at(-1)?.parts).toEqual(
expect.arrayContaining([
expect.objectContaining({ type: "tool-result" }),
]),
);
});
});
@@ -88,7 +88,11 @@ export const useTimelineAgent = (
const cancelReview = useCallback(async () => {
await demo.cancelReview("Cancelled by operator.");
await demo.next();
// In replay the canonical recording only contains the submitted branch.
// Do not call next() or the UI would falsely advance into submitted evidence.
if (demo.state.mode === "live") {
await demo.next();
}
setMessages((current) => appendToolMessage(
current,
"timeline-agent-cancel",