Skip to content

fix(tui): close busy-flag race that stuck queue-mode back-to-back sends - #56100

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-7b88098f
Jul 1, 2026
Merged

fix(tui): close busy-flag race that stuck queue-mode back-to-back sends#56100
teknium1 merged 1 commit into
mainfrom
hermes/hermes-7b88098f

Conversation

@teknium1

@teknium1 teknium1 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes the queue-mode busy-flag race that stuck the TUI on "Analyzing…" forever after two rapid back-to-back sends. Salvage of #56046 by @benbarclay onto current main.

Root cause: the submit path set the session busy flag asynchronously, only inside the .then of an input.detect_drop RPC. dispatchSubmission routes queue-vs-send on getUiState().busy, so a second Enter pressed inside that RPC window read busy === false and raced a second prompt.submit down the send path. The gateway accepts a mid-turn submit as a success ({status:"queued"}, not an error), so the client's isSessionBusyError re-queue path never fired and the message vanished from the local drain effect — UI stuck busy until Ctrl+C.

Changes

  • ui-tui/src/app/submissionCore.ts (new): pure, testable submit core; markSubmitting() flips busy synchronously at the choke point, before the detect_drop round-trip. Legacy isSessionBusyError re-queue kept as a defensive net.
  • ui-tui/src/app/useSubmission.ts: send now funnels through submitPrompt; dead imports removed.
  • ui-tui/src/__tests__/submissionCore.test.ts (new): asserts busy flips synchronously before the RPC resolves.

Validation

Before After
2nd rapid send reads busy false (races a 2nd submit) true (local enqueue)
UI after back-to-back sends stuck "Analyzing…", needs Ctrl+C drains both turns
ui-tui typecheck clean clean
submissionCore.test.ts n/a 6/6 pass; 3 regression assertions verified red without markSubmitting()

Infographic

queue-race-fix

Under display.busy_input_mode: queue, sending two messages back-to-back
hung the session on 'Analyzing…' until a manual Ctrl+C.

The submit path only marked the session busy inside the .then of an
async input.detect_drop RPC. dispatchSubmission routes queue-vs-send on
getUiState().busy, so a second Enter inside that RPC window read
busy===false and raced a second prompt.submit down the send path
instead of enqueuing locally. The gateway accepts the mid-turn submit
as a success ({status:'queued'}, not an error), and the client's only
re-queue recovery is gated on catching a 'session busy' error — which
never fires — so the message became invisible to the client-side drain
effect and the UI stayed busy forever.

Extract the ready-prompt submit into a pure submissionCore module and
mark the session busy synchronously at the choke point, before the
detect_drop round-trip, closing the gap for every caller (mainline
submit, queue-edit picks, drain, interpolation). Verified the real
gateway already queues+drains both turns correctly, so the fix is
purely client-side. Adds submissionCore.test.ts whose regression
assertions fail without the synchronous busy and pass with it.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/tui Terminal UI (ui-tui/ + tui_gateway/) labels Jul 1, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: salvage of #56046 (@benbarclay's original, still open) onto current main. Distinct from merged gateway-side #52594 (mid-turn queue on busy retry) and #17110 (honor busy_input_mode) — this closes the client-side async busy-flag race in useSubmission.ts. Not a duplicate.

@teknium1
teknium1 merged commit e71f9ad into main Jul 1, 2026
22 checks passed
@teknium1
teknium1 deleted the hermes/hermes-7b88098f branch July 1, 2026 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants