From 62e0f58d2d7108274d2a95a4253c11aed5bda2e6 Mon Sep 17 00:00:00 2001 From: Exotic209093 <134711311+Exotic209093@users.noreply.github.com> Date: Sun, 13 Sep 2026 18:57:27 +0100 Subject: [PATCH] fix(client-runtime): map cancelled and interrupted subagent terminal statuses Codex subagents that complete with 'cancelled' or 'interrupted' status were falling through to 'running' because TASK_COMPLETED_STATUS only covered completed, failed, and stopped. Add both missing entries so the fold correctly marks them as terminal. Fixes #11164 --- .../src/state/subagentRuntime.test.ts | 32 +++++++++++++++++++ .../src/state/subagentRuntime.ts | 2 ++ 2 files changed, 34 insertions(+) diff --git a/packages/client-runtime/src/state/subagentRuntime.test.ts b/packages/client-runtime/src/state/subagentRuntime.test.ts index d366d7f0d4ee..cf65cc4385fa 100644 --- a/packages/client-runtime/src/state/subagentRuntime.test.ts +++ b/packages/client-runtime/src/state/subagentRuntime.test.ts @@ -181,6 +181,38 @@ describe("foldSubagentActivities", () => { expect(agents[0]!.completedAt).toBe("2026-08-01T11:00:00.000Z"); }); + it("maps cancelled status to a terminal cancelled state", () => { + const agents = fold([ + activity("task.started", { taskId: "task-cancelled", taskType: "local_agent" }), + activity("task.completed", { + taskId: "task-cancelled", + status: "cancelled", + summary: "user cancelled", + }), + ]); + expect(agents).toHaveLength(1); + const agent = agents[0]!; + expect(agent.status).toBe("cancelled"); + expect(agent.result).toBe("user cancelled"); + expect(agent.completedAt).not.toBeNull(); + }); + + it("maps interrupted status to a terminal interrupted state", () => { + const agents = fold([ + activity("task.started", { taskId: "task-interrupted", taskType: "local_agent" }), + activity("task.completed", { + taskId: "task-interrupted", + status: "interrupted", + summary: "context window exceeded", + }), + ]); + expect(agents).toHaveLength(1); + const agent = agents[0]!; + expect(agent.status).toBe("interrupted"); + expect(agent.result).toBe("context window exceeded"); + expect(agent.completedAt).not.toBeNull(); + }); + it("reactivation increments the run count and clears result/error", () => { const agents = fold([ activity("task.started", { taskId: "task-4", taskType: "local_agent" }), diff --git a/packages/client-runtime/src/state/subagentRuntime.ts b/packages/client-runtime/src/state/subagentRuntime.ts index e441de32db48..962d74d003ca 100644 --- a/packages/client-runtime/src/state/subagentRuntime.ts +++ b/packages/client-runtime/src/state/subagentRuntime.ts @@ -430,6 +430,8 @@ const TASK_COMPLETED_STATUS: ReadonlyMap = new Ma ["completed", "completed"], ["failed", "failed"], ["stopped", "interrupted"], + ["cancelled", "cancelled"], + ["interrupted", "interrupted"], ]); const KNOWN_STATUSES: ReadonlySet = new Set([