From d82f6a602463e5c43119070646d4979c7e05d9cf Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 12 May 2026 13:13:18 +0900 Subject: [PATCH] fix(background-agent): refresh stale todo state --- .../background-agent/manager.polling.test.ts | 41 +++++++++++++++++++ src/features/background-agent/manager.ts | 4 +- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/features/background-agent/manager.polling.test.ts b/src/features/background-agent/manager.polling.test.ts index 3f6eb759d..bbd84d41c 100644 --- a/src/features/background-agent/manager.polling.test.ts +++ b/src/features/background-agent/manager.polling.test.ts @@ -345,6 +345,47 @@ describe("BackgroundManager pollRunningTasks", () => { expect(task.status).toBe("completed") expect(todoCallCount).toBe(0) }) + + test("#when cached incomplete todos become complete before idle polling #then refreshes todos and completes", async () => { + //#given + let todoCallCount = 0 + const manager = createManagerWithClient({ + status: async () => ({ data: { "ses-idle-stale-todos": { type: "idle" } } }), + todo: async () => { + todoCallCount += 1 + return { + data: [ + { content: "compile result", status: "completed", priority: "high" }, + ], + } + }, + }) + const task = createRunningTask("ses-idle-stale-todos") + injectTask(manager, task) + + manager.handleEvent({ + type: "message.part.updated", + properties: { sessionID: "ses-idle-stale-todos", type: "text" }, + }) + manager.handleEvent({ + type: "todo.updated", + properties: { + sessionID: "ses-idle-stale-todos", + todos: [ + { content: "compile result", status: "in_progress", priority: "high" }, + ], + }, + }) + + //#when + const poll = manager["pollRunningTasks"] + await poll.call(manager) + manager.shutdown() + + //#then + expect(task.status).toBe("completed") + expect(todoCallCount).toBe(1) + }) }) describe("#given a running task whose session status is busy", () => { diff --git a/src/features/background-agent/manager.ts b/src/features/background-agent/manager.ts index fdfa5849d..efb812eb0 100644 --- a/src/features/background-agent/manager.ts +++ b/src/features/background-agent/manager.ts @@ -1220,8 +1220,8 @@ The fallback retry session is now created and can be inspected directly. private async checkSessionTodos(sessionID: string): Promise { const observedIncompleteTodos = this.observedIncompleteTodosBySession.get(sessionID) - if (observedIncompleteTodos !== undefined) { - return observedIncompleteTodos + if (observedIncompleteTodos === false) { + return false } try {