fix(tui): surface parked replies and recover undelivered queued follow-ups#31
Merged
Merged
Conversation
…w-ups Two bugs made a message queued during a backgrounded sub-agent look ignored: 1. Parked replies were invisible. The TUI surfaces a parked run's reply via OnParked, which captured cogito's reasoning callback as "the reply that preceded the park" — but that callback carries reasoning tokens (empty for most models), not the reply text. Any answer the model produced at a park boundary (e.g. to a follow-up injected while a detached agent kept the run alive) existed in the fragment but was never rendered. cogito's WithOnPark now passes the parked reply (mudler/cogito#59); the session forwards it and drops the lastReply hack. 2. End-of-run drain discarded unconsumed follow-ups. A queue entry released into the live run while its final LLM call was in flight was echoed to the transcript but never consumed — SendMessage's deferred channel drain silently threw it away. The session now tracks user-typed injections (InjectUser) and hands unconsumed ones back (TakeUndelivered); the TUI re-dispatches them as fresh turns ahead of the queue, without a second echo. System notices (shell-job completions, wake-ups) are still dropped by the drain so stale notices can't re-trigger finished work. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Symptom
Queue a message while a sub-agent runs in the background (Ctrl+B detach), e.g. "ok great, meanwhile, whats 2+2?" — the message is echoed to the transcript but never visibly answered; the final reply only addresses the sub-agent's result.
Two root causes
1. Parked replies were never shown. The injected follow-up was delivered and answered — but the answer was produced at a park boundary, and parked replies surface via
OnParked(s.lastReply), wherelastReplywas captured from cogito's reasoning callback. That callback carriesresp.ReasoningContent(reasoning tokens — empty for most models), not the reply text, soOnParkedalways received""and every park-boundary answer was silently dropped. Fixed in cogito by mudler/cogito#59 (WithOnParknow carries the parked reply); this PR bumps cogito, forwards the reply directly, and deletes thelastReplyhack.2. The end-of-run drain could lose follow-ups entirely.
releaseQueueFrontpops the queue and echoes as soon as the buffered channel send succeeds — but if the run's final LLM call is already in flight, the message is never consumed andSendMessage's deferred drain discarded it: echoed, unanswered, no longer queued. The session now tracks user-typed injections (InjectUser) and hands unconsumed ones back viaTakeUndelivered; the TUI re-dispatches them as fresh turns ahead of the queue, without a second transcript echo. System notices (shell-job completions, wake-ups, sub-agent completions) keep being dropped by the drain, so a stale notice can't re-trigger finished work (cf. #28).Tests
TestParkedReplySurfacedToOnParked— fake OpenAI server spawns a background sub-agent, run parks with a text reply; assertsOnParkedreceives it. Fails withOnParked reply = ""before the cogito bump (the exact user-visible bug).TestUndeliveredInjectHandedBack— injects a user follow-up + a system notice while the final LLM call is held in flight; asserts only the follow-up is handed back.TestRedispatchGoesFirstWithoutEcho,TestReleaseQueueFrontTracksUndelivered— TUI re-dispatch ordering and no double echo.🤖 Generated with Claude Code