fix(coding-agent): resume suspended input pump on programmatic admission - #895
Open
twaldin wants to merge 2 commits into
Open
fix(coding-agent): resume suspended input pump on programmatic admission#895twaldin wants to merge 2 commits into
twaldin wants to merge 2 commits into
Conversation
Any abort (requestAbort, abortForUpdateRestart) suspends the session input pump. A user-typed prompt clears the suspension, but programmatic admission via queueAgentMessagePrompt/_queuePreparedPrompt never does, so queued agent messages, heartbeats, and wake prompts starve forever while the session sits idle. Clear the suspension on programmatic turn admission when not streaming, mirroring _prompt(). A starved queue also blocked every heartbeat fire, and a skipped heartbeat lost the fire until the next full interval because nextRunAt was recomputed from the skip time. A skipped heartbeat now retries at the next scheduler tick. Regression tests: queued agent mail post-abort delivers at idle, and a pre-abort backlog drains once a later programmatic admission arrives. Both fail on the previous behavior.
A follow-up re-fire that coalesces into an already-queued owner (same queueKey, e.g. rolling wake prompts or heartbeats) was dropped before the pump-resume path ran, so the queued owner still starved after an abort suspended the pump at idle. Resume the pump on the coalesced path too.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Any abort —
requestAbort()from Esc/TUI interrupt, a daemonabort, a goal abort, orabortForUpdateRestart()— sets_sessionInputPumpSuspended = true. The user-typed prompt path (_prompt) clears that flag when the session is not streaming, but the programmatic admission path (queueAgentMessagePrompt→_queuePreparedPrompt→_admitSessionInput) never does. After one abort, every programmatically queued item — agent messages from children, heartbeat prompts, injected wake prompts — sits in the queue forever while the session is idle. Only a human-typed prompt or an explicitresume_queuerevives delivery.Reproduced clean-room on a pristine 0.7.0 install with a stub provider, driven over the daemon socket:
queuedCountpersisted >90s idle)The starved queue also blackholes heartbeats:
shouldDeferHeartbeatCronJobdefers whileunfinishedActionCount > 0, and a skipped fire is lost until the next full interval becausenextRunAtis recomputed from the skip time (adjacent to #820).Related: #820 (heartbeat fires dropped when coincident with busy), #821 (send retry duplication), #823 (queued agent mail delivery). None of them names the suspended-pump starvation itself.
Fix
_admitSessionInput: when a programmatic turn admission arrives while the session is not streaming and the pump is suspended, clear the suspension, notify checkpoint waiters, and schedule the pump — the same resume semantics_prompt()already gives user-typed input.recordDispatchResult: a skipped heartbeat fire reschedules to the next scheduler tick (1 minute) instead of the next full interval, so a deferred fire retries instead of being lost.Testing
resume-suspended-input-pump.test.ts: queued agent mail after an idle abort delivers; a backlog queued before an abort drains once a later programmatic admission arrives. Both fail without the fix.cron-jobs.test.tsskip-reschedule expectation to the new retry-next-tick semantics.vitest runon cron-jobs, agent-session-queue, agent-session-prompt, agent-session-action-races: no new failures versus the unpatched baseline.This PR was prepared with agent assistance.
Note
Fix
AgentSession.admitSessionActionto resume suspended input pump on programmatic admissionturnactions.now + 1 minuteinstead of waiting for the full schedule interval, preventing long stalls after a skip.resume-suspended-input-pump.test.tscover the three resume scenarios.Macroscope summarized 9f77b4d.