Merge pull request #3916 from code-yeongyu/fix/delegate-inactivity-timeout

fix(delegate-task): clarify sync inactivity timeout
This commit is contained in:
YeonGyu-Kim
2026-05-10 16:00:26 +09:00
committed by GitHub
6 changed files with 31 additions and 10 deletions
@@ -75,7 +75,7 @@ describe("syncPollTimeoutMs threading", () => {
taskId: undefined,
}, 120_000)
expect(result).toBe("Poll timeout reached after 120000ms for session ses_custom")
expect(result).toBe("Poll inactivity timeout reached after 120000ms without active OpenCode status for session ses_custom")
expect(abortCount).toBe(1)
})
})
@@ -141,7 +141,7 @@ describe("syncPollTimeoutMs threading", () => {
taskId: undefined,
})
expect(result).toBe(`Poll timeout reached after ${MAX_POLL_TIME_MS}ms for session ses_default`)
expect(result).toBe(`Poll inactivity timeout reached after ${MAX_POLL_TIME_MS}ms without active OpenCode status for session ses_default`)
})
})
@@ -159,7 +159,7 @@ describe("syncPollTimeoutMs threading", () => {
taskId: undefined,
})
expect(result).toBe("Poll timeout reached after 120000ms for session ses_legacy")
expect(result).toBe("Poll inactivity timeout reached after 120000ms without active OpenCode status for session ses_legacy")
})
})
})
@@ -177,7 +177,7 @@ describe("syncPollTimeoutMs threading", () => {
taskId: undefined,
}, 10)
expect(result).toBe("Poll timeout reached after 50ms for session ses_guard")
expect(result).toBe("Poll inactivity timeout reached after 50ms without active OpenCode status for session ses_guard")
})
})
})
@@ -100,7 +100,7 @@ describe("pollSyncSession", () => {
}, 50)
// then: times out (ignores stale error)
expect(result).toContain("Poll timeout reached")
expect(result).toContain("Poll inactivity timeout reached")
})
test("detects completion when assistant message has terminal finish reason", async () => {
@@ -459,7 +459,7 @@ describe("pollSyncSession", () => {
}, 0)
// then: returns timeout error
expect(result).toBe("Poll timeout reached after 50ms for session ses_timeout")
expect(result).toBe("Poll inactivity timeout reached after 50ms without active OpenCode status for session ses_timeout")
expect(abortCount).toBe(1)
})
})
@@ -214,9 +214,11 @@ export async function pollSyncSession(
}
if (timedOut) {
log("[task] Poll timeout reached", { sessionID: input.sessionID, pollCount })
log("[task] Poll inactivity timeout reached", { sessionID: input.sessionID, pollCount })
abortSyncSession(client, input.sessionID, "poll_timeout")
}
return timedOut ? `Poll timeout reached after ${maxPollTimeMs}ms for session ${input.sessionID}` : null
return timedOut
? `Poll inactivity timeout reached after ${maxPollTimeMs}ms without active OpenCode status for session ${input.sessionID}`
: null
}
+2 -2
View File
@@ -3,7 +3,7 @@ const { describe, expect, test } = require("bun:test")
import { __resetTimingConfig, __setTimingConfig, getDefaultSyncPollTimeoutMs, getTimingConfig } from "./timing"
describe("timing sync poll timeout defaults", () => {
test("default sync timeout is 30 minutes", () => {
test("default sync inactivity timeout is 30 minutes", () => {
// #given
__resetTimingConfig()
@@ -14,7 +14,7 @@ describe("timing sync poll timeout defaults", () => {
expect(timeout).toBe(30 * 60 * 1000)
})
test("default sync timeout accessor follows MAX_POLL_TIME_MS config", () => {
test("default sync inactivity timeout accessor follows MAX_POLL_TIME_MS config", () => {
// #given
__resetTimingConfig()
@@ -0,0 +1,18 @@
import { describe, expect, test } from "bun:test"
import { createDelegateTaskPresentation } from "./tool-description"
describe("createDelegateTaskPresentation", () => {
test("#given sync task usage #when description is rendered #then timeout is described as inactivity based", () => {
//#given
const presentation = createDelegateTaskPresentation({})
//#when
const description = presentation.description
//#then
expect(description).toContain("30-minute inactivity window")
expect(description).toContain("busy/retry/running")
expect(description).toContain("not a total wall-clock limit")
})
})
@@ -67,6 +67,7 @@ export function createDelegateTaskPresentation(options: DelegateTaskToolOptions)
${categoryList}
- subagent_type: Use specific agent directly (explore, librarian, oracle, metis, momus)
- run_in_background: REQUIRED. true=async (returns task_id), false=sync (waits). Use background=true ONLY for parallel exploration with 5+ independent queries.
Sync waits use a 30-minute inactivity window: OpenCode busy/retry/running status resets the window, so this is not a total wall-clock limit.
- task_id: Existing task to continue (from previous task output). Continues the same subagent session with FULL CONTEXT PRESERVED.
- command: The command that triggered this task (optional, for slash command tracking).