From 2327eba341b78f59170a2f2f14416f0ae1b74a5c Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 28 May 2026 18:41:29 +0900 Subject: [PATCH] fix(delegate-task): read messages after status errors --- ...ync-session-poller.status-fallback.test.ts | 51 +++++++++++++++++++ .../delegate-task/sync-session-poller.ts | 12 ++--- 2 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 src/tools/delegate-task/sync-session-poller.status-fallback.test.ts diff --git a/src/tools/delegate-task/sync-session-poller.status-fallback.test.ts b/src/tools/delegate-task/sync-session-poller.status-fallback.test.ts new file mode 100644 index 000000000..8a13d496c --- /dev/null +++ b/src/tools/delegate-task/sync-session-poller.status-fallback.test.ts @@ -0,0 +1,51 @@ +/// +import { afterEach, describe, expect, test } from "bun:test" +import { unsafeTestValue } from "../../../test-support/unsafe-test-value" +import { pollSyncSession } from "./sync-session-poller" +import { __resetTimingConfig, __setTimingConfig } from "./timing" +import type { OpencodeClient, ToolContextWithMetadata } from "./types" + +const toolContext: ToolContextWithMetadata = { + sessionID: "ses_parent", + messageID: "msg_parent", + agent: "sisyphus", + abort: new AbortController().signal, +} + +describe("pollSyncSession status fallback", () => { + afterEach(() => { + __resetTimingConfig() + }) + + test("#given status API is unavailable but assistant text exists #when polling #then messages complete the sync task", async () => { + // given + __setTimingConfig({ + POLL_INTERVAL_MS: 1, + MAX_POLL_TIME_MS: 50, + }) + const client = unsafeTestValue({ + session: { + messages: async () => ({ + data: [ + { + info: { role: "assistant" }, + parts: [{ type: "text", text: "done" }], + }, + ], + }), + abort: async () => ({ data: {} }), + }, + }) + + // when + const result = await pollSyncSession(toolContext, client, { + sessionID: "ses_missing_status", + agentToUse: "sisyphus", + toastManager: null, + taskId: undefined, + }, 50) + + // then + expect(result).toBeNull() + }) +}) diff --git a/src/tools/delegate-task/sync-session-poller.ts b/src/tools/delegate-task/sync-session-poller.ts index 97ae7c1a1..62fc507f3 100644 --- a/src/tools/delegate-task/sync-session-poller.ts +++ b/src/tools/delegate-task/sync-session-poller.ts @@ -142,15 +142,15 @@ export async function pollSyncSession( await wait(syncTiming.POLL_INTERVAL_MS) pollCount++ - let statusResult: { data?: Record } + let sessionStatus: { type: string } | undefined try { - statusResult = await client.session.status() + const statusResult = await client.session.status() + const allStatuses = normalizeSDKResponse(statusResult, {} as Record) + sessionStatus = allStatuses[input.sessionID] } catch (error) { - log("[task] Poll status fetch failed, retrying", { sessionID: input.sessionID, error: String(error) }) - continue + const errorMessage = error instanceof Error ? error.message : String(error) + log("[task] Poll status fetch failed, checking messages", { sessionID: input.sessionID, error: errorMessage }) } - const allStatuses = normalizeSDKResponse(statusResult, {} as Record) - const sessionStatus = allStatuses[input.sessionID] if (pollCount % 10 === 0) { log("[task] Poll status", {