fix(parent-wake): preserve stale tool-call wake escape

This commit is contained in:
YeonGyu-Kim
2026-05-19 12:29:46 +09:00
parent dfc2e8e4ae
commit d3d2d4913b
@@ -62,6 +62,11 @@ type ParentWakeNotifierOptions = {
userMessageInProgressWindowMs: number userMessageInProgressWindowMs: number
} }
type ToolWaitDeferralDecision = {
defer: boolean
skipPromptGateToolStateCheck: boolean
}
type Unrefable = ReturnType<typeof setTimeout> & { unref?: () => unknown } type Unrefable = ReturnType<typeof setTimeout> & { unref?: () => unknown }
function unrefTimerHandle(handle: ReturnType<typeof setTimeout>): void { function unrefTimerHandle(handle: ReturnType<typeof setTimeout>): void {
@@ -151,7 +156,8 @@ export class ParentWakeNotifier {
return return
} }
if (await this.shouldDeferParentWakeForSessionHistory(sessionID, latestWake)) { const toolWaitDecision = await this.shouldDeferParentWakeForSessionHistory(sessionID, latestWake)
if (toolWaitDecision.defer) {
this.schedulePendingParentWakeFlush(sessionID) this.schedulePendingParentWakeFlush(sessionID)
return return
} }
@@ -183,6 +189,7 @@ export class ParentWakeNotifier {
source: "background-agent-parent-wake", source: "background-agent-parent-wake",
settleMs: 0, settleMs: 0,
postDispatchHoldMs: 250, postDispatchHoldMs: 250,
checkToolState: !toolWaitDecision.skipPromptGateToolStateCheck,
input: { input: {
path: { id: sessionID }, path: { id: sessionID },
body: { body: {
@@ -482,12 +489,15 @@ export class ParentWakeNotifier {
return false return false
} }
private async shouldDeferParentWakeForSessionHistory(sessionID: string, wake: PendingParentWake): Promise<boolean> { private async shouldDeferParentWakeForSessionHistory(
sessionID: string,
wake: PendingParentWake,
): Promise<ToolWaitDeferralDecision> {
const messages = await this.loadParentWakeSessionMessages(sessionID) const messages = await this.loadParentWakeSessionMessages(sessionID)
const toolWaitState = this.latestAssistantToolWaitState(messages) const toolWaitState = this.latestAssistantToolWaitState(messages)
if (!toolWaitState.waiting) { if (!toolWaitState.waiting) {
delete wake.toolCallDeferralStartedAt delete wake.toolCallDeferralStartedAt
return false return { defer: false, skipPromptGateToolStateCheck: false }
} }
const now = Date.now() const now = Date.now()
wake.toolCallDeferralStartedAt ??= now wake.toolCallDeferralStartedAt ??= now
@@ -502,12 +512,12 @@ export class ParentWakeNotifier {
log("[background-agent] Sending parent wake after stale tool-call deferral window:", { log("[background-agent] Sending parent wake after stale tool-call deferral window:", {
sessionID, sessionID,
}) })
return false return { defer: false, skipPromptGateToolStateCheck: true }
} }
log("[background-agent] Deferred parent wake because latest assistant turn is waiting on tool results:", { log("[background-agent] Deferred parent wake because latest assistant turn is waiting on tool results:", {
sessionID, sessionID,
}) })
return true return { defer: true, skipPromptGateToolStateCheck: false }
} }
private async hasAcceptedMessageAfterDispatchedParentWake(sessionID: string, wake: PendingParentWake): Promise<boolean> { private async hasAcceptedMessageAfterDispatchedParentWake(sessionID: string, wake: PendingParentWake): Promise<boolean> {