Skip to content

fix(desktop): interrupt running turn when user sends a message while busy - #51666

Open
raymondclowe wants to merge 1 commit into
NousResearch:mainfrom
raymondclowe:fix/desktop-interrupt-on-enter
Open

fix(desktop): interrupt running turn when user sends a message while busy#51666
raymondclowe wants to merge 1 commit into
NousResearch:mainfrom
raymondclowe:fix/desktop-interrupt-on-enter

Conversation

@raymondclowe

Copy link
Copy Markdown

Problem

When the agent is busy and the user types a correction + Enter, the desktop composer queues the message but never interrupts the running turn. The agent keeps going for minutes, ignoring the user's input. The queue counter grows ("4 queued", "5 queued"...) and only ONE message drains after the turn finally ends — leaving the rest stranded and often sending the agent off on a tangent based on a single out-of-context message.

The CLI has busy_input_mode: interrupt (the default) which fires agent.interrupt() on Enter. The desktop app had no equivalent — it only queued.

Fix

When the user presses Enter with a payload while busy, the composer now both queues the message AND fires onCancel() to interrupt the running turn. This mirrors:

  • The CLI's busy_input_mode: interrupt behaviour
  • The existing sendQueuedNow busy-path (line ~1568): promote to head → onCancel() → auto-drain on busy→false

The auto-drain mechanism (shouldAutoDrain in composer-queue.ts) then sends the queued message as soon as the agent reports busy: false.

Changes

  • apps/desktop/src/app/chat/composer/index.tsx: In submitDraft(), the busy && payloadPresent branch now calls queueCurrentDraft() + onCancel() instead of just queueCurrentDraft()
  • apps/desktop/src/app/chat/composer/enter-submit-dom-race.test.tsx: Updated test harness and assertion to expect onCancel to be called when queueing while busy

Related issue

Closes #51665

Note

This PR addresses issue #1 from the issue (queue-not-interrupt). The WebSocket stall (#2) and reconnect queue recovery (#3) need separate investigation.

…busy

The desktop composer queued messages while the agent was busy but never
fired an interrupt — so the agent kept running for minutes, ignoring the
user's correction.  The queue counter grew ('4 queued', '5 queued'...)
and only ONE message drained after the turn finally ended, leaving the
rest stranded.

Now when the user presses Enter with a payload while busy, the composer
both queues the message AND fires onCancel() to interrupt the running
turn — mirroring the CLI's busy_input_mode: interrupt behaviour and the
existing sendQueuedNow busy-path.  The auto-drain then sends the queued
message as soon as the agent reports busy=false.

Files changed:
- apps/desktop/src/app/chat/composer/index.tsx
- apps/desktop/src/app/chat/composer/enter-submit-dom-race.test.tsx
@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have labels Jun 24, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for isolating the busy-composer behavior. The defect is still present on current main, but this PR needs a small relocation before it can be salvaged.

Problems

  • submitDraft was extracted from apps/desktop/src/app/chat/composer/index.tsx into apps/desktop/src/app/chat/composer/hooks/use-composer-submit.ts by 773a3703bfc1f8ff2f3aef40d7a565e7f4fe1404. The live busy/payload branch remains queueCurrentDraft() only at hooks/use-composer-submit.ts:151-152, so the current diff no longer targets the production decision point.
  • The proposed onCancel() is unconditional after queueCurrentDraft(). That helper can return false when no active queue key exists or enqueueing fails (hooks/use-composer-queue.ts:164-180), so cancellation should occur only after a successful queue.

Suggested changes

  • Apply the guarded queue-then-cancel behavior in hooks/use-composer-submit.ts.
  • Update the regression test for the relocated path and cover queue failure without cancellation.

Automated hermes-sweeper review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Desktop app: queued messages ignored while agent runs 10+ minutes; Esc/Stop don't work under heavy tool output

3 participants