From d3d2d4913b5e362c8680decb068d6ad3e5ebffab Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 19 May 2026 12:29:46 +0900 Subject: [PATCH] fix(parent-wake): preserve stale tool-call wake escape --- .../background-agent/parent-wake-notifier.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/features/background-agent/parent-wake-notifier.ts b/src/features/background-agent/parent-wake-notifier.ts index 10c790513..c65e43d99 100644 --- a/src/features/background-agent/parent-wake-notifier.ts +++ b/src/features/background-agent/parent-wake-notifier.ts @@ -62,6 +62,11 @@ type ParentWakeNotifierOptions = { userMessageInProgressWindowMs: number } +type ToolWaitDeferralDecision = { + defer: boolean + skipPromptGateToolStateCheck: boolean +} + type Unrefable = ReturnType & { unref?: () => unknown } function unrefTimerHandle(handle: ReturnType): void { @@ -151,7 +156,8 @@ export class ParentWakeNotifier { return } - if (await this.shouldDeferParentWakeForSessionHistory(sessionID, latestWake)) { + const toolWaitDecision = await this.shouldDeferParentWakeForSessionHistory(sessionID, latestWake) + if (toolWaitDecision.defer) { this.schedulePendingParentWakeFlush(sessionID) return } @@ -183,6 +189,7 @@ export class ParentWakeNotifier { source: "background-agent-parent-wake", settleMs: 0, postDispatchHoldMs: 250, + checkToolState: !toolWaitDecision.skipPromptGateToolStateCheck, input: { path: { id: sessionID }, body: { @@ -482,12 +489,15 @@ export class ParentWakeNotifier { return false } - private async shouldDeferParentWakeForSessionHistory(sessionID: string, wake: PendingParentWake): Promise { + private async shouldDeferParentWakeForSessionHistory( + sessionID: string, + wake: PendingParentWake, + ): Promise { const messages = await this.loadParentWakeSessionMessages(sessionID) const toolWaitState = this.latestAssistantToolWaitState(messages) if (!toolWaitState.waiting) { delete wake.toolCallDeferralStartedAt - return false + return { defer: false, skipPromptGateToolStateCheck: false } } const now = Date.now() wake.toolCallDeferralStartedAt ??= now @@ -502,12 +512,12 @@ export class ParentWakeNotifier { log("[background-agent] Sending parent wake after stale tool-call deferral window:", { sessionID, }) - return false + return { defer: false, skipPromptGateToolStateCheck: true } } log("[background-agent] Deferred parent wake because latest assistant turn is waiting on tool results:", { sessionID, }) - return true + return { defer: true, skipPromptGateToolStateCheck: false } } private async hasAcceptedMessageAfterDispatchedParentWake(sessionID: string, wake: PendingParentWake): Promise {