[Feature Request] Real-time steering: priority message channel for redirecting Claude mid-execution
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:
- Wait until the turn completes (potentially minutes of wasted work)
- Escape to interrupt (destructive — loses in-progress work)
- 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:
- 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"
- Explicit steering mode: A user-activated mode (e.g.,
/steeror 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.
- 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:
- Checks a file for user messages on every tool call
- Injects any contents as
additionalContext - 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.
27 Comments
Found 1 possible duplicate issue:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
yeah this is 100% needed and is something codex has supported for a while now
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/steerAPI (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.
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.
Yes, I find this is a huge annoyance that makes me wanna use another tool like Cline.
++ for this feature.
A
UserPromptSubmithook can implement priority message injection:Send priority messages from outside:
The next time Claude processes a prompt, the priority message is injected ahead of normal context.
+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:
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.
Shipped this in pikiclaw — an open-source web dashboard for managing Claude Code, Codex, and Gemini sessions.
Steer from the dashboard:
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/steerRPC).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.+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.
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).
Exactly what I'm waiting for! ++
+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.
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
+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.
Codex actually does this already at least in the app so I agree toggle it up!
+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.
+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.
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?
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.
+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.
+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.
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:
The actual cost of a mid-task correction today is:
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.
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:
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
pullmodel with apush / interrupt-drivenone.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:
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
Harder / to revisit
Action Items
/steerto 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
+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.