Skip to content

feat: Improve queue vs steer messaging clarity in composer #343

@amanthanvi

Description

@amanthanvi

Summary

When an agent is actively processing, the composer offers two fundamentally different behaviors — steering (sending immediately to redirect the agent) and queuing (deferring the message until the turn finishes). Currently, the distinction between these two modes is underexposed in the UI, making it easy for users to accidentally steer when they meant to queue, or vice versa.

Context: I started using CodexMonitor and love it — this request is about making the queue vs steer distinction more discoverable and intuitive.

Current Behavior

The steerEnabled global setting (Settings → Steer mode, defaults to true) controls what Enter does while the agent is processing:

Steer mode ON (default) Steer mode OFF
Enter → sends immediately (steers/interrupts agent) Enter → queues locally
Tab → queues (undiscoverable shortcut) No way to steer at all
Send button label: "Send" Send button label: "Queue"

What works well today

  • The queued message chip list (ComposerQueue.tsx) with edit/delete is great
  • The sendLabel in useLayoutNodes.tsx correctly flips between "Send" and "Queue"
  • The useQueuedSend hook cleanly branches the two paths

Where the UX falls short

  1. No visual distinction on the send button — The button icon is always the same arrow (ArrowUp) regardless of whether pressing it will steer or queue. The label change is only in the aria-label, not visible to sighted users at a glance. (ComposerInput.tsx lines 541-567)

  2. Tab-to-queue is undiscoverable — When steer mode is on, Tab queues instead. No tooltip, keyboard hint, or inline label communicates this. The only mention is a small subtitle in Settings. (Composer.tsx lines 643-653)

  3. No inline status explaining the current mode — While the agent is processing, there is no banner, badge, or composer-adjacent indicator telling the user: "Agent is working. Enter will [steer/queue]." Users must mentally track the global setting.

  4. No per-message mode toggle — Switching between steer and queue requires navigating to Settings. There is no quick toggle in the composer itself for situational use (e.g., "I usually steer, but this time I want to queue").

  5. No confirmation for steering — Steering is irreversible and interrupts the agent's current line of thought. There is no lightweight confirmation or undo, which can be surprising for users who don't realize they're interrupting.

  6. Steered messages have no visual badge — Optimistic steer messages inserted via useThreadMessaging.ts (lines 140-161) look identical to normal messages. There is no indicator that a message was a steer/interrupt vs a regular follow-up.

Proposed Improvements

These are suggestions — happy to discuss alternatives or subsets:

Minimal (low effort, high impact)

  • Visible label on the send button while agent is processing — e.g., show "Steer ↑" or "Queue ↑" text next to the icon, or change the icon itself (e.g., a redirect arrow for steer, a clock/queue icon for queue)
  • Keyboard shortcut hint near the composer — e.g., a subtle "Tab to queue" hint when steer mode is on and the agent is processing

Medium effort

  • Inline composer banner when agent is processing — a small bar above the input: "Agent is working — Enter will send immediately (steer)" or "Agent is working — Enter will queue"
  • Quick toggle in composer — a small button or dropdown near the send button to switch between steer/queue for the current message without navigating to Settings
  • "Steered" badge on messages that were sent as steering interrupts, so the conversation history reflects what happened

Nice-to-have

  • Confirmation option for steering (opt-in in Settings) — "Are you sure you want to interrupt the agent?" with a "Don't ask again" checkbox
  • Tooltip on send button explaining current behavior and the Tab shortcut

Relevant Code Paths

File Role
src/features/threads/hooks/useQueuedSend.ts Central queue vs steer branching (lines 192-238)
src/features/threads/hooks/useThreadMessaging.ts Optimistic steer message insertion (lines 140-161)
src/features/composer/components/Composer.tsx Tab key queue binding (lines 643-653)
src/features/composer/components/ComposerInput.tsx Send/Stop button rendering (lines 541-567)
src/features/composer/components/ComposerQueue.tsx Queued message chip list
src/features/layout/hooks/useLayoutNodes.tsx sendLabel determination (lines 562-564)
src/features/settings/components/SettingsView.tsx Steer mode toggle (lines 3475-3492)

Environment

  • macOS (but applies to all platforms)
  • v0.7.40 (latest at time of writing)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions