[Feature Request] Real-time steering: priority message channel for redirecting Claude mid-execution

Status Fixed / completed
Maintainer reply ✓ Yes — bcherny
Activity 35 comments · opened Mar 3, 2026 · closed Aug 17, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

When Claude Code is executing a complex, multi-step workflow (pipelines, multi-file refactors, coordinated subagent work), the user has no way to steer the work mid-execution. Messages typed during processing are queued and delivered at the next turn boundary — by which point Claude may have completed significant work in the wrong direction.

The existing interrupt mechanism (Escape) is destructive: it discards in-progress work and forces a restart. What's missing is a non-destructive steering channel — a way to say "pivot to file X instead" or "skip the tests, focus on the implementation" without losing what's already been done.

Related issues address adjacent problems:

  • #29224 addresses acknowledging queued messages (side-channel responses)
  • #29490 addresses detecting stop-words to pause execution
  • #26388 addresses temporal misinterpretation of queued messages

This request addresses a different need: intentional mid-execution redirection — giving the user the ability to change the agent's course while it's working, without interrupting or restarting.

Why This Matters

As Claude Code is used for increasingly autonomous, longer-running workflows — agent teams, multi-step pipelines, large refactors — the gap between "fully autonomous" and "user-steerable" becomes a real problem. Users who delegate complex work need to be able to course-correct when they see the agent heading in a suboptimal direction. The current options are:

  1. Wait until the turn completes (potentially minutes of wasted work)
  2. Escape to interrupt (destructive — loses in-progress work)
  3. Hope the queued message is interpreted correctly at the next boundary (unreliable per #26388)

None of these support the natural collaboration pattern: "hey, I see what you're doing — shift your focus to this instead."

Proposed Solution

A priority message channel that delivers user messages to Claude between tool calls during active execution, rather than queuing them for the next turn boundary.

Core mechanism: Between tool calls (Read, Edit, Bash, etc.), Claude Code already runs PreToolUse hooks. A native priority message system could use this same interstitial window to deliver queued user messages as high-priority context, tagged so Claude recognizes them as steering input rather than conversational replies.

Possible implementation approaches:

  1. Native priority injection: Messages typed during execution are tagged as [steering] and injected into Claude's context at the next tool call boundary (before the next PreToolUse hook fires), rather than waiting for the full turn to complete. Claude sees: [User steering message — typed during active execution]: "skip the tests, focus on implementation"
  1. Explicit steering mode: A user-activated mode (e.g., /steer or a keybinding) that changes message delivery from queued to priority. When active, typed messages are delivered between tool calls. When inactive, normal queuing behavior applies.
  1. Priority classification: Claude Code automatically classifies queued messages as "steering" (directional — "focus on X", "skip Y", "pivot to Z") vs. "conversational" (reactions, questions) and delivers steering messages with priority.

What this would look like for the user:

# Claude is actively running a multi-step refactor...

# User types (while Claude is working):
> Actually, start with the API layer, not the UI

# Instead of being queued until Claude's turn ends,
# the message is delivered at the next tool-call boundary.
# Claude sees it before its next Read/Edit/Bash call
# and adjusts course without losing completed work.

Workaround (Current)

It's possible to approximate this today using a PreToolUse wildcard hook that:

  1. Checks a file for user messages on every tool call
  2. Injects any contents as additionalContext
  3. Clears the file after reading

Combined with a shell alias (steer "pivot to X"), this gives near-real-time steering during tool-heavy work. But it requires the user to write to a file from another terminal rather than typing naturally into Claude Code, and the hook overhead (however small) applies to every tool call in every session.

A native solution would be simpler, more natural (type into the same interface), and could handle edge cases the workaround can't (like delivering messages during the gap between a tool completing and the next generation starting).

Additional Context

This becomes increasingly important as agent teams and long-running autonomous workflows mature. The team lead pattern (where Claude coordinates multiple sub-agents) already provides partial steerability — the user can message the lead while teammates work. But the lead itself is unsteerable during its own processing turns. A priority message channel would close this gap entirely.

The fundamental insight: Claude Code already has interstitial windows between tool calls where context can be injected (PreToolUse hooks prove this). The feature request is to make those windows available for user messages natively.

View original on GitHub ↗

35 Comments

github-actions[bot] · 6 months ago

Found 1 possible duplicate issue:

  1. https://github.com/anthropics/claude-code/issues/29490

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

sam0x17 · 5 months ago

yeah this is 100% needed and is something codex has supported for a while now

ThinkOffApp · 5 months ago

This is a real problem we hit daily running Claude Code as a persistent agent (via IDE Agent Kit, where external room messages get relayed to Claude Code sessions).

The current behavior is exactly as described: messages typed during processing queue up and arrive at the next turn boundary, often misinterpreted because temporal context is lost. Our workaround (tmux send-keys injection) has the same limitation, it can only deliver at turn boundaries.

Worth noting: Codex already ships a turn/steer API (added Feb 2026) that injects user messages into an active turn without waiting for completion. Enter steers mid-execution, ESC interrupts. This is becoming table stakes for agentic workflows. Claude Code is the only major IDE agent that still forces you to wait for the current turn to finish before you can redirect.

The most useful version of this for us would be a non-blocking priority channel that surfaces as a system-level notification within the current turn. Something Claude sees immediately and can choose to act on or defer, rather than a queued user message that gets batched with everything else.

jkanczura-work · 5 months ago

This is one of the biggest pain points I have with Claude Code! This should be higher priority with how much Opus 4.6 churns through tokens and how badly it can spiral. Attempting to steer it with regular follow-up messages (in the current functionality) often causes context corruption because it keeps referring back to those statements you made trying to guide it during semi-related tasks.

msmccor100 · 5 months ago

Yes, I find this is a huge annoyance that makes me wanna use another tool like Cline.

rpcai · 5 months ago

++ for this feature.

yurukusa · 5 months ago

A UserPromptSubmit hook can implement priority message injection:

PRIORITY_FILE="/tmp/cc-priority-message"
[ -f "$PRIORITY_FILE" ] || exit 0
MSG=$(cat "$PRIORITY_FILE")
rm -f "$PRIORITY_FILE"
[ -z "$MSG" ] && exit 0
jq -n --arg m "$MSG" '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":"⚡ PRIORITY: " + $m}}'
exit 0

Send priority messages from outside:

echo "Stop current task — urgent bug in production" > /tmp/cc-priority-message

The next time Claude processes a prompt, the priority message is injected ahead of normal context.

ronle · 5 months ago

+1 — I'm building https://github.com/anthropics/claude-code/issues/30492, a multi-agent orchestration dashboard that runs on top of Claude Code in headless mode
(--input-format stream-json).

The gap is even more acute in headless/programmatic mode than in the interactive CLI:

  • Interactive CLI: ESC interrupts the current tool → agent stops → user types new instruction. Destructive but functional.
  • Headless stream-json: No equivalent. Writing to stdin queues until turn end. SIGINT kills the process entirely. The only option is kill + respawn with -r, which is slow, fragile, and frequently leaves sessions in broken states.

I've had to implement an "interrupt" mechanism server-side that kills the agent process and immediately respawns with -r <session_id> plus the new prompt. It works, but it's a hack — you lose in-flight tool state, and the respawn adds seconds of latency.

What would solve this for headless consumers:

A minimal first step — even before full mid-turn steering — would be an interrupt message on stdin:
{"type": "interrupt"}
{"type": "user", "message": {"role": "user", "content": "Stop and do X instead"}}

This would replicate ESC behavior: abort the current tool, keep the process and session alive, process the next queued user message. It's destructive (like ESC), but it avoids the kill/respawn cycle and keeps the conversation context intact.

The full priority-channel / steering proposal in this issue would be even better — non-destructive redirection between tool calls would eliminate the need for any process management on the orchestrator side.

xiaotonng · 4 months ago

Shipped this in pikiclaw — an open-source web dashboard for managing Claude Code, Codex, and Gemini sessions.

Steer from the dashboard:

  • While a task is running, send a new message → it queues up
  • Hit Steer to interrupt the current task and redirect the agent with your new input
  • The previous task's output is frozen in place (non-destructive), and the steered task starts immediately

Queue and steer are separate, explicit actions in the dashboard UI — no confusion about whether your input is steering or a new task.

Works with Claude Code CLI driver (stdin injection) and Codex (turn/steer RPC).

npx pikiclaw@latest
ProfSynapse · 4 months ago

Running into this specifically in the Agent Teams / subagent context too (see #21419). The same turn-boundary queueing applies to lead → teammate SendMessage — by the time my "stop doing X" message lands, the subagent has already done X and the turn is closing. Each teammate is effectively its own session from the scheduler's perspective, so any priority-injection mechanism shipped for the main session should apply symmetrically to teammate mailboxes.

The proposed PreToolUse injection point would solve both flavors cleanly. Would strongly prefer this over a destructive kill like TaskStop, which currently is the only escape hatch.

horonaka · 4 months ago

+1, with a data point from the other side of the client/model boundary:

I've been operating under a strict system-prompt rule that says "treat consecutive user messages as additions/corrections to the previous turn, especially when the response was slow." The rule is there precisely because of the failure mode in this thread — I kept interpreting mid-generation follow-ups as reactions to my latest (not-yet-read-by-user) reply, and conversations went sideways.

Outcome: the rule helps sometimes, but it cannot close the gap on its own. The model has no way to tell whether a queued user message was typed while the previous reply was still streaming, or after the user had read it. Without that signal from the client, the rule either over-applies (treating every follow-up as a mid-generation patch, breaking normal turn-taking) or under-applies (missing the real ones). Multiple failure rounds in the same session are routine.

This is a strong argument that the fix has to live on the client side: the temporal metadata exists only there. The proposals in this thread (priority injection, queue-mode tagging) and in the now-locked #26388 ([typed while Claude was writing] wrapper) are the right shape. Even the minimal version — just tagging queued messages with the fact they were typed pre-completion — would let system prompts reliably disambiguate.

So this is less a feature request than a structural requirement: no amount of prompting can substitute for a client-side timing signal.

ianbrandt · 3 months ago

It would be nice to be able to edit the last message sent to steer Claude (e.g., if it might be headed in the wrong direction because of a typo or poorly worded prompt).

everlats · 3 months ago

Exactly what I'm waiting for! ++

ShneorCr · 3 months ago

+1 — please bring back the old behavior where Claude could read messages while actively working on a task, just like a natural conversation with a human. The model could see the new message mid-run and decide for itself whether it was relevant to the current task (and adjust on the fly) or whether it should wait for the next turn.

This was one of Claude Code's standout features — it made the workflow feel collaborative instead of transactional. You could drop in a quick "actually, also check X" or "ignore the tests for now" without breaking flow or killing in-progress work.

Now that messages just sit in the queue until the current run finishes, that natural back-and-forth is gone. Pressing Esc to interrupt is destructive and loses context. Waiting for the turn to end defeats the purpose of catching a misdirection early.

Please restore this. It was a top feature and a big part of what made Claude Code feel different.

knyck-knostalgia · 3 months ago

Is this still not possible? Is this in the desktop app? This is an important feature that I miss when I come over from codex, i use claude for work and codex for personal

MrVlnka · 3 months ago

+1 — and a bit of history: this actually existed in earlier versions of the
Claude Desktop app. I loved it, and honestly it was one of the more compelling
reasons for me to switch over from Codex. I was genuinely disappointed when it
got removed in an update.
I get that the community seems split on this (see #49373 for the opposite camp,
who want messages to wait until the very end of a turn). So instead of arguing
over the "right" default, my proposal is simple: just give us a setting — a
toggle for how queued messages get injected:
• steer at the next tool boundary (inject mid-task, the old behavior)
• queue until end of turn (current behavior)
• interrupt immediately
That's the best of both worlds, it ends the debate, and it should be fairly
straightforward to implement. Please bring it back as an option. 🙏

A nice UX angle: instead of a settings toggle, make it per-message via the
keybind. Enter = queue (current), and a separate bind (e.g. Ctrl+Enter, since
Shift+Enter is usually newline) = inject/steer immediately. Decide per message,
no menu round-trip. The keybinds are already user-rebindable, so once a
"steer/inject" action exists, wiring this up should be trivial.

ProfSynapse · 3 months ago

Codex actually does this already at least in the app so I agree toggle it up!

afram123 · 2 months ago

+1 — this is the one feature I keep missing from Codex, where it's called steer: while the agent is mid-run you push a short note and it's folded into the current turn, without interrupting.

Right now my only options are Esc (throws away in-progress work) or typing and hoping the queue picks it up at a sane moment — and the timing is a coin flip: sometimes it derails a tool call, sometimes it lands minutes too late after the agent already went the wrong way.

This gets more painful the longer agents run. On multi-hour runs, being able to drop a small correction the moment I see it heading the wrong way — instead of interrupting or waiting — would be huge. A dedicated steer channel (separate from Interrupt and the existing queue) would close the biggest day-to-day gap with Codex for me.

chk-mk · 2 months ago

+1, On "Claude Desktop Code", I've seen the agent work for 15 minutes, do dozens of tool calls, including ones that I had to manually approve and the message is still pending. This is absurd. On denying - and there's no deny-message option that I can see - the message fires off immediately, potentially confusing the model, as if the thing I tried to clarify 15 minutes ago is the problem with the latest tool call (when it's not), and then I had to interrupt the model anyway and try to get things back on track.

This is just unnecessary pain.

As noted in #36326, this also contradicts the documentation, which describes the message as immediately steering. That issue was closed with no fix to the documentation.

Agreed with others that 'queue up' can be useful too, so the fix should be both, not to just change it and break someone else's use case.

bob-obringer · 2 months ago

I've recently written a coding agent with claude agent sdk using input streaming. It was beautiful. Did a wonderful job steering the conversation mid flow. Just like Codex does now.

Why was I able to do this in my own agent using the Claude Agent SDK but Anthropic can't?

BobbinFortnox · 2 months ago

Yeah this sucks. Closed my issue, but I would suggest a /btw style pre-evaluation that determines whether the current block of stuff (however that is defined) should be interrupted.

Qcko · 2 months ago

+1 — strong need. Most of this thread is about the delivery mechanism (when/how a note reaches the model). There's an agent-behavior half that's just as important for the pain described here — silent misinterpretation, stale notes landing late — and it survives whatever channel ships:

1. Restate-before-act. On draining a note, the agent should echo back its reading in a line or two before acting. The core flaw of async steering is the sender never knowing whether the note landed or how it was read; restating closes that loop and fixes the "silently misapplied" failure mode.

**2. A non-destructive soft stop, distinct from Esc.** Esc is a hard kill; steering keeps going. The missing third intent is "wind down cleanly" — reach a consistent state, then halt, losing no in-flight work. Worth its own tier, not folded into Esc.

3. Stale-note handling. If a note refers to work already passed, the agent should say so rather than retrofit it.

NickAry83 · 2 months ago

+1, and one dimension I don't see called out yet in the thread:

In extended-reasoning / max-effort modes the turn isn't atomic. A single turn often stacks several self-posed questions and permission prompts before it ever reaches a boundary, so "wait for the turn to end" can mean waiting through a dozen sub-decisions the agent has already resolved on its own. That's the precise reason queue can't cover this case: queue assumes a boundary arrives soon, and in long autonomous runs the agent burns through the decisions I'd have answered well before that boundary shows up. The longer and more autonomous the run, the more the gap costs, which is the opposite of where you'd want it to scale.

Strong support for the non-destructive priority channel as described, especially Ocko's state-note handling point.

reveal79 · 2 months ago

Strong +1 on this. Want to add a framing that hasn't come up yet: this is a token efficiency problem, not just a UX problem.

Right now there are two failure modes when I spot a problem mid-task:

  1. Interrupt — kills the turn, I lose context, and burn tokens reconstructing state before the correction can even land.
  2. Let it finish — burn tokens completing work I already know is wrong, generate artifacts I'm about to throw away, then correct after the fact — so Claude now has to reason about undoing prior steps on top of the new direction.

The actual cost of a mid-task correction today is:

(remaining wrong work) + (interrupt overhead) + (state reconstruction) + (correction itself)

With steer-at-seam — injecting at the next PreToolUse boundary as you've proposed — that collapses to just the correction. No wasted work, no reconstruction overhead.

At scale across power users running complex multi-step sessions, this isn't just a quality-of-life improvement. It's a meaningful reduction in wasted compute — which matters to Anthropic as much as it does to us.

The infrastructure argument you've already made is exactly right: PreToolUse hooks prove the interstitial windows exist. This is a UX layer on top of a mechanism that already works.

ciscodevelop · 2 months ago

Design Proposal: Doorbell-model message injection at agent lifecycle boundaries

Status: Proposed
Related: #30492 (this), #49373 (end-of-turn queue), #29224 (side-channel responses), #30677 (VS Code queueing)

Context

When the main agent is working, a user message has only two fates today: interrupt the turn (Esc) or sit in a queue that flushes at the next LLM pause — often mid-task, derailing the run (#49373). Both are blunt.

The current queue is effectively a pull / polling model: the loop must reach a pause, then drains whatever is waiting, with no notion of who sent it or what authority it carries. This produces two well-known failure modes:

  • Authority ambiguity — a queued "also update the tests" is read as a fresh instruction and the agent abandons what it was doing.
  • Boundary cost — proposals that check for input at every step imply the loop must constantly watch for arrivals, which is wasteful.

The key observation: the agent already has a return-path it traverses when a subagent finishes. A subagent returning ("here's what I found, here's what changed") is an established, trusted ingestion pattern. The main agent reads that return, evaluates it, and decides the next action. We don't need a new mechanism — we need to let a user message arrive through that same boundary, marked for what it is.

Decision

Treat the user as a first-class external actor in the multi-agent lifecycle, not as an exception that breaks the turn. Two coupled mechanisms:

1. Doorbell, not polling (event-driven delivery)

The loop does not check for input at each step. There is no watching. Like a house with a closed front door: you don't continuously look outside, you wait for the bell. The incoming message raises the event; the loop spends nothing while no one is there.

When a message arrives, it is parked at the door. At the next existing lifecycle boundary (subagent return, or tool-call boundary where PreToolUse hooks already fire), the main agent "hears the bell," checks the peephole, and admits it. Cost is zero when the queue is empty; ingestion is immediate when it isn't. This replaces a pull model with a push / interrupt-driven one.

2. Badge-carrying agent, evaluated by the main agent (authority via judgment, not flags)

The message enters wrapped as an external agent return with a provenance badge — semantically identical to a subagent saying "heads up, this came up." The main agent reads and evaluates it, exactly as it already evaluates subagent returns, and decides authority from content:

  • "Luca flagged a thing to change because X happened" → note it, continue.
  • "The lead said we should do it this way" → suspend, recalibrate.

Authority is not a flag the user sets upfront. It's a judgment the main agent makes downstream, where the intelligence to make it already lives. The badge only guarantees provenance — "this genuinely came from outside, the model did not hallucinate it" — and a double-verification step hardens that provenance against spoofing / injection.

Why this is a reuse, not an addition

| Existing primitive | Reused for |
|--------------------|-----------|
| Subagent return-path | User message ingestion |
| Tool-call / PreToolUse boundary | The "door" where admission happens |
| Main agent evaluating a return | Deciding advisory vs. directive |

The novel surface is small: (a) park-at-door + admit-at-next-boundary, and (b) the provenance badge + verification. Everything else is plumbing that already exists.

Consequences

Easier

  • Long autonomous runs stay steerable without derailment.
  • Users become peers in the lifecycle — they can knock at any time and be admitted at the right point.
  • No per-step polling cost.

Harder / to revisit

  • Trust boundary: subagent returns are system-initiated; a user message injected mid-turn is external input arriving during autonomous reasoning. The badge must carry provenance and survive a verification check.
  • Boundary admission must not stall the loop when the door is empty — the check fires on event, not on schedule.
  • Defining the badge schema and the double-verification contract.

Action Items

  • Define the provenance badge schema (origin, verification token, advisory/directive hint left for the main agent to resolve).
  • Specify the double-verification step for badge authenticity.
  • Add park-at-door + admit-at-next-boundary at the subagent-return / PreToolUse interstitial windows.
  • Have the main agent classify admitted messages (advisory → continue, directive → recalibrate) the same way it classifies subagent returns.
  • Optional explicit /steer to force directive-priority delivery (aligns with this issue's proposal).
jkanczura-work · 2 months ago
# Design Proposal: Doorbell-model message injection at agent lifecycle boundaries Status: Proposed Related: #30492 (this), #49373 (end-of-turn queue), #29224 (side-channel responses), #30677 (VS Code queueing) ## Context When the main agent is working, a user message has only two fates today: interrupt the turn (Esc) or sit in a queue that flushes at the next LLM pause — often mid-task, derailing the run (#49373). Both are blunt. The current queue is effectively a pull / polling model: the loop must reach a pause, then drains whatever is waiting, with no notion of who sent it or what authority it carries. This produces two well-known failure modes: Authority ambiguity — a queued "also update the tests" is read as a fresh instruction and the agent abandons what it was doing. Boundary cost — proposals that check for input at every step imply the loop must constantly watch for arrivals, which is wasteful. The key observation: the agent already has a return-path it traverses when a subagent finishes. A subagent returning ("here's what I found, here's what changed") is an established, trusted ingestion pattern. The main agent reads that return, evaluates it, and decides the next action. We don't need a new mechanism — we need to let a _user message_ arrive through that same boundary, marked for what it is. ## Decision Treat the user as a first-class external actor in the multi-agent lifecycle, not as an exception that breaks the turn. Two coupled mechanisms: ### 1. Doorbell, not polling (event-driven delivery) The loop does not check for input at each step. There is no watching. Like a house with a closed front door: you don't continuously look outside, you wait for the bell. The _incoming message_ raises the event; the loop spends nothing while no one is there. When a message arrives, it is parked at the door. At the next existing lifecycle boundary (subagent return, or tool-call boundary where PreToolUse hooks already fire), the main agent "hears the bell," checks the peephole, and admits it. Cost is zero when the queue is empty; ingestion is immediate when it isn't. This replaces a pull model with a push / interrupt-driven one. ### 2. Badge-carrying agent, evaluated by the main agent (authority via judgment, not flags) The message enters wrapped as an external agent return with a provenance badge — semantically identical to a subagent saying "heads up, this came up." The main agent reads and evaluates it, exactly as it already evaluates subagent returns, and decides authority _from content_: "Luca flagged a thing to change because X happened" → note it, continue. "The lead said we should do it this way" → suspend, recalibrate. Authority is not a flag the user sets upfront. It's a judgment the main agent makes downstream, where the intelligence to make it already lives. The badge only guarantees provenance — "this genuinely came from outside, the model did not hallucinate it" — and a double-verification step hardens that provenance against spoofing / injection. ## Why this is a reuse, not an addition Existing primitive Reused for Subagent return-path User message ingestion Tool-call / PreToolUse boundary The "door" where admission happens Main agent evaluating a return Deciding advisory vs. directive The novel surface is small: (a) park-at-door + admit-at-next-boundary, and (b) the provenance badge + verification. Everything else is plumbing that already exists. ## Consequences Easier Long autonomous runs stay steerable without derailment. Users become peers in the lifecycle — they can knock at any time and be admitted at the right point. No per-step polling cost. Harder / to revisit Trust boundary: subagent returns are system-initiated; a user message injected mid-turn is external input arriving during autonomous reasoning. The badge must carry provenance _and_ survive a verification check. Boundary admission must not stall the loop when the door is empty — the check fires on event, not on schedule. Defining the badge schema and the double-verification contract. ## Action Items Define the provenance badge schema (origin, verification token, advisory/directive hint left for the main agent to resolve). Specify the double-verification step for badge authenticity. Add park-at-door + admit-at-next-boundary at the subagent-return / PreToolUse interstitial windows. Have the main agent classify admitted messages (advisory → continue, directive → recalibrate) the same way it classifies subagent returns. * Optional explicit /steer to force directive-priority delivery (aligns with this issue's proposal).

I don't know if an AI generated, copy and pasted implementation plan is the way to go here

Keenvisionary · 1 month ago

+1. Daily use case here: desktop app with heavy subagent orchestration. Queued messages currently sit until the whole turn completes, so a mid-task course correction is either a destructive Esc or a long wait. With multi-minute tool chains that is a real workflow tax. Codex's turn/steer (Enter injects into the running turn at the next reasoning step, Tab queues for the next turn) is useful prior art for the interaction model. Happy to test a beta.

gfvst · 1 month ago

+1. OpenAI offers it and it's a complete game changer for my experience of interacting. (It's really frustrating to have to interrupt Claude with my message or wait until it's done.)

knyck-knostalgia · 1 month ago

It’s such a huge difference I wonder why it isn’t available to toggle on
for anthropic. Between that and how token hungry Fable is, I’ve been
leaning away more recently :/

Knyckolas Sutherland
(732) 331-0546
@.***

On Wed, Jul 22, 2026 at 12:05 AM gfvst @.***> wrote:

gfvst left a comment (anthropics/claude-code#30492) <https://github.com/anthropics/claude-code/issues/30492#issuecomment-5041733937> +1. OpenAI offers it and it's a complete game changer for my experience of interacting. (It's really frustrating to have to interrupt Claude with my message or wait until it's done.) — Reply to this email directly, view it on GitHub <https://github.com/anthropics/claude-code/issues/30492?email_source=notifications&email_token=B6AAYHQHRDUQMFHRCPFOEWT5GA4QNA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMBUGE3TGMZZGM32M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5041733937>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/B6AAYHTZ3FVKLQL4MD2YF2D5GA4QNAVCNFSNUABFKJSXA33TNF2G64TZHM4TGNZSGUZTINZVHNEXG43VMU5TIMBRHAZTENJVGQ2KC5QC> . Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS <https://github.com/notifications/mobile/ios/B6AAYHWIN6E2VC6W45IDWJL5GA4QNA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMBUGE3TGMZZGM32M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJKTGN5XXIZLSL5UW64Y> and Android <https://github.com/notifications/mobile/android/B6AAYHR74ECKP3U2LPVUMRT5GA4QNA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMBUGE3TGMZZGM32M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>. Download it today! You are receiving this because you commented.Message ID: @.***>
wshallwshall · 1 month ago

+1 from a heavy multi-session user — I regularly run 30+ parallel git worktree + Claude Code sessions against the same repo, several doing long autonomous refactors/builds. The Esc-or-wait bind above is a real tax at that scale: with that many sessions going, I often need to tell one specific session "hold on, also check X" without derailing it — today the only options are wait-through or destroy-and-restart.

For what it's worth, the file-based PreToolUse-hook workaround mentioned upthread does work in practice. I just wired one up: a wildcard PreToolUse hook watches a note file and re-emits its contents as additionalContext, clearing the file after read. It genuinely delivers a note at the next tool-call boundary without interrupting the turn. That's a good signal the underlying mechanism (additionalContext injection at a hook boundary) is sound — it just needs to be a first-class feature instead of something every user has to hand-roll per project. @ciscodevelop's doorbell-model proposal above matches what I built almost exactly.

wshallwshall · 27 days ago

Following up on my own comment above with the number I did not have then — and correcting one I should not have given. I said "30+ parallel sessions"; I cannot support that. The largest I have actually counted in a single snapshot is 8, with 22 distinct sessions across a week. The tax is real at 8; I overstated the scale.

Here is what the workaround costs, because the cost is the reason it cannot be left armed.

The hook is a PreToolUse matching * that reads a note file, deletes it, and re-emits the contents as additionalContext — so a note written from a second terminal lands at the session's next tool-call boundary instead of at end-of-turn. On a long fan-out or a soak, end-of-turn is far too late to redirect anything, so that difference is the entire value.

Measured on this Windows box: a bare pwsh -NoProfile spawn is ~0.30 s, and a * matcher pays that on every tool call, in every session, whether or not a note is waiting — which it almost never is. So the expensive part is not the work the hook does. It is being a subprocess at all.

The consequence is the part that makes this a feature request rather than a tip: because it is too expensive to leave on globally, I enable it per-worktree — which means it is never armed on the session that turns out to need it. The session I want to steer is by definition the one I did not predict. A per-tool-call subprocess tax cannot be paid speculatively across every session, so the workaround is structurally unavailable at the moment it would pay off.

The ask, in the shape the workaround already proves out: a first-party out-of-band message queue for a running session — non-blocking, delivered at the next tool-call boundary, with no per-tool-call subprocess. Everything else about the hook version works; only the delivery mechanism is wrong.

Two design notes from running it, both cheap and both easy to get wrong:

  • Fail open. Any error exits 0 and emits nothing. A broken steering channel must never be able to block a tool call — it is an accessory to the session, not a gate on it.
  • A steering note is data, not authority. It arrives labelled as coming from the user via a side channel, but it should not carry more authority than a normal prompt, and it must never be treated as approval for something that would otherwise need confirmation. If a first-party channel ships, that distinction belongs in the envelope rather than in each user's convention.

Setup: Windows 11, 2.1.219, solo dev. n=1.

wshallwshall · 19 days ago

Following up on my 08-04 comment, because the specific thing I asked for there has since shipped — and I would rather close that out myself than leave it standing as an open ask.

What shipped. My ask was "a first-party out-of-band message queue for a running session — non-blocking, delivered at the next tool-call boundary, with no per-tool-call subprocess." That now exists. On engine 2.1.227 / Claude Desktop 1.26832.0.0, a message typed mid-turn is folded into the running turn: it appears in the session transcript as an attachment parented to the tool-result record, dequeued at the tool-call boundary, with no hook armed and no subprocess. It is on by default in every session I checked, not opt-in per worktree.

That retires the structural complaint from my last comment. The reason the hook workaround was useless in practice was that a * PreToolUse matcher cost ~0.30 s per tool call, so I could only arm it per-worktree — and the session I needed to steer was by definition the one I had not predicted. A default-on channel has no such problem. That half of this issue is genuinely solved, and #71726 tracks it.

What is still missing, and why I do not think this issue is done. Delivery is not the same as attention.

The message now reliably arrives. Nothing obliges the model to act on it before continuing. It is folded in as context alongside a tool result, competing with everything else already in the turn — so on exactly the long, tool-dense turns where steering matters, a note can sit unaddressed through many subsequent actions while the model finishes the plan it already had. The subjective experience is unchanged from before the fix: I type the correction, watch several more tool calls go by, and the only lever that reliably redirects the session is still Esc, which is destructive.

This is the difference between the channel existing and the channel being heard, and it maps exactly onto approach 3 in the original issue body ("priority classification"). Approaches 1 and 2 — injection at the boundary — have effectively shipped. Approach 3 has not.

The ask, narrowed. An explicit priority send: a modifier on submit (Ctrl+Enter, a ! prefix, whatever fits the input model) that marks a message as address this before your next tool call, distinct from the current best-effort fold-in. Not a new channel — the channel is built. A flag on the envelope that the existing channel already carries, and a corresponding instruction that the model resolve it before proceeding rather than at its own discretion.

Two things worth keeping explicitly, both of which I raised last time and neither of which I would want lost in the narrowing:

  • Fail open. A priority message that cannot be delivered must never block or delay a tool call. It is an accessory to the session, not a gate on it.
  • Priority is urgency, not authority. A message marked urgent should be addressed sooner; it must not thereby count as approval for anything that would otherwise require confirmation. Raising salience and raising privilege need to stay separate, and that separation belongs in the envelope rather than in each user's phrasing conventions.

Why the distinction is worth tracking separately rather than closing this as fixed. Anyone reading #71726 would reasonably conclude the steering problem is solved, and for the delivery half it is. But a user running long autonomous turns cannot tell the difference between "my message was never delivered" and "my message was delivered and deprioritized" — both look like being ignored, and both push you to Esc. If this issue is closed on the strength of the delivery fix, the remaining half loses its home.

Environment: Windows 11, Claude Desktop 1.26832.0.0, engine 2.1.227, solo dev, n=1. The delivery-mechanism claims above are from my own session transcripts; the "still gets deprioritized" claim is lived experience across long multi-session runs, not something I have instrumented.

Qcko · 16 days ago

Some measured data on the delivery half of this, since #71726 and #49373 make directly contradictory claims about the Desktop app and I couldn't find a resolution anywhere in the thread.

Setup. Claude Desktop, 2026-08-14. A turn was held open across eight short sequential tool calls (~12s each), and a plain, unprefixed message was typed into the chat box while the turn was running. No hooks were involved in delivery.

Run 1 - text typed during a tool call:

15:45:02.548  tool call 1 starts
15:45:14.355  message typed
15:45:14.727  tool call 1 returns
15:45:15.893  ENTER
              -> message surfaced to the model here; calls 2-8 had not run

Run 2 - text typed between tool calls:

15:49:09.006  tool call 1 starts
15:49:21.173  tool call 1 returns
15:49:27.115  message typed
15:49:28.875  ENTER
              -> message surfaced with the next tool result

Findings:

  1. Desktop delivers typed messages mid-turn, at the next tool-call boundary. It does not hold them until the turn completes. Delivery landed at a different boundary in each run, so this isn't a timing artifact. This supports #49373's description ("flush at the next LLM pause... including pauses between tool calls") and contradicts the premise of #71726, which is filed on the basis that Desktop withholds queued messages until end of turn.
  1. It is boundary delivery, not live injection. In run 1 the text was typed ~0.4s before the in-flight call returned and was not delivered until it did. Injecting into a running tool call - the thing #69124 asked for, closed as not planned - remains absent. Both facts being true at once may be why the tracker is split on this.
  1. Esc keeps completed work. Several issues here (including #64624) state that interrupting "discards all in-progress work". Per the interactive-mode docs it stops the current response or tool call; work already finished is retained. Worth correcting, because it makes the current workaround less costly than the thread assumes.

What this doesn't cover. The delivery mechanism being present doesn't give you the rest of what's asked for in this thread. A mid-turn message arrives undifferentiated - there's no way to mark it as "additive, keep going" versus "course change" versus "wind down and stop", and no guarantee the model restates its reading before acting. The gap I'd still most like closed is a non-destructive stop tier: Esc ends the turn, and a typed "please stop" is just another note the model may or may not treat as halting. There's currently nothing that means "reach a consistent state, then stop".

knyck-knostalgia · 16 days ago

Maybe I'm not grasping what some of the other comments in this thread are saying but I want something very simple. Anthropic team. Go to the codex app. Look at the feature option for Queue vs Steer. Copy it. Give us the option to steer: to type another message while it's in the middle of the thinking to steer it's thinking rather than to queue up further messages for after it's done going down a long wrong path. I switched over completely because of this feature. If there is documentation about them having a technical or philosophical reason they don't support this, please link me to it so I can understand and empathize. Best of luck, its been nearly a month since i switched over all personal work. And 2 weeks since all my company work transitioned to codex.

bcherny collaborator · 14 days ago

This is how the CLI works today: while Claude is mid-turn, just type your correction and press Enter. It doesn't interrupt — Claude reads it as soon as the current action completes and adjusts before its next step, keeping the work done so far. Esc remains the hard stop.

Docs: https://code.claude.com/docs/en/how-claude-code-works#interrupt-and-steer

🤖 Generated with Claude Code