The /steer command in lets you nudge an active agent run mid-flight without queuing a new turn or stopping the one already in progress. Send /steer focus on the security review part, skip the cost analysis, the message lands in the active run’s steering buffer at the next model boundary, and the agent course-corrects on the same turn. Before v2026.5.3 (shipped 2026-05-04) the choice was either wait for the run to finish or interrupt it; /steer is the missing middle option, and on v2026.4.29 it became the default queueing behaviour for any message sent while a run is active.

This post covers what active-run steering actually does, where /steer differs from a normal message, the queue modes that landed in v2026.4.29, and a few patterns that map cleanly onto real personal-agent work: long research runs, code edits, and channel-driven sessions.

What active-run steering does

A normal agent turn in is request → model call → tool calls → reply. If you send a second message while the first turn is still running, you have to decide what happens to it. Historically queued every message and dispatched them one at a time at the next idle boundary. That’s still available, but as of v2026.4.29 the default is steer mode: pending messages drain into the current run at the next model boundary, and the model sees them as additional steering context inside the same turn.

The practical result is that you stop having to wait three minutes for a 12-step tool chain to finish before you can say “actually, skip the database part.” The steering message lands at the next tool boundary, the model reads it, and the next tool call reflects the new instructions.

/steer <message>, added in v2026.5.3 (PR #76934), is the explicit form. It does the same thing as a queued message in steer mode, but with two differences worth knowing:

  • It works even when the active session is idle. A normal message at idle starts a fresh turn; /steer is treated as queue-independent steering for the current session run without starting a new turn.
  • It never gets reclassified as a new turn. The command is labelled as steering on dispatch, so progress UI in Control UI, Discord, Slack and Telegram shows it inside the running turn rather than as a separate request.

/steer vs a regular message: when each one fires

Here is the decision matrix in :

SituationSend a regular messageSend /steer ...
Session is idle (no run)New turn starts immediatelySteering buffered; nothing visible until a new run begins
Run is active, default steer queueDrains into the current run at the next model boundarySame effect, explicit label
Run is active, legacy queue modeHeld until the run finishes, then dispatched one at a timeDrains into the current run regardless of queue mode
Need to interrupt and kill the runUse the Control UI abort or sessions abortNot what /steer is for

In other words: most users never need to type /steer explicitly, because the default queue mode already steers. The command exists for two cases. The first is when your config still uses the legacy queue mode. The second is when you want the run to visibly show your message as steering rather than as a queued next-turn message.

Configuring the queue mode

The queue behaviour is in messages.queue (top level) or per-channel. Both values match what the release notes call out:

{
  "messages": {
    "queue": "steer"  // default since 2026.4.29
  }
}

Possible values:

  • steer: drain pending messages into the active run at the next model boundary. Followup messages within 500ms are debounced into the same drain. This is the default.
  • queue: legacy. Hold messages until the run finishes, dispatch one new turn at a time.

The 500ms debounce is the detail most people miss. If you fire three steering messages within half a second (“focus on auth”, “use Bedrock not Anthropic”, “skip costs”), collects them, drains them as one steering batch at the next boundary, and the model sees all three in order. You do not get three sequential interrupts.

Per-channel override looks the same shape: channels.<id>.messages.queue or channels.<id>.messages.groupChat.queue. The latter is the override that matters most for Slack, Discord and Telegram group threads where multiple humans steer at once.

What “visible-reply enforcement” changes

v2026.4.29 also introduced messages.visibleReplies and messages.groupChat.visibleReplies. These are separate from steering, but they show up in the same configuration block and they matter when you start steering group conversations.

When visibleReplies is on, any agent output that needs to be visible to the human channel has to go through the message(action=send) tool. Output that stays internal (tool results, reasoning, internal notes) never leaks into the channel. The reason this interacts with steering: a /steer instruction like “don’t post any messages to Slack until I confirm” works cleanly under visible-reply enforcement, because the model has a real boundary between internal work and visible output. Without that flag set, has to infer intent, and the result is less predictable.

For self-hosted setups, especially ones with group channels routed to one agent, set messages.groupChat.visibleReplies: "send" and messages.queue: "steer" together. The combination is what makes mid-run steering safe in a room full of people.

Three patterns that map onto real work

1. Long research runs

You ask the agent to research a topic across web search, GitHub and a vendor doc site. Twelve tool calls in, you realize you forgot to mention you only care about self-hosted options. Without steering you either let it finish and ask again (wasting the run) or abort and restart. With /steer only count self-hosted options going forward; ignore SaaS-only vendors, the next tool call reflects the constraint.

2. Long code edits

The agent is in the middle of editing six files across a refactor and you spot it about to touch a generated file. /steer skip src/generated/, those are codegen outputs lands at the next tool boundary and you keep your generated files clean without aborting the refactor.

3. Group channels with multiple stakeholders

In a Slack channel routed to your agent, two people can steer the same run from different angles (“make the response shorter”, “focus on cost”). With queue: steer and the 500ms debounce, both messages land in the same steering batch and the model reconciles them. With legacy queue mode the second person would have to wait for an entire extra turn.

The /side and /btw aliases

While you are looking at the new command surface, v2026.5.3 also added /side as a text and native slash-command alias for /btw. /btw and /side are different from /steer: they ask a side question that gets answered in a separate context and does not affect the active run. Quick reference:

CommandWhat it doesUse when
/steer <message>Adds guidance to the active run, no new turnYou want to redirect work already in progress
/btw <question> or /side <question>Spawns a side answer in a separate contextYou have a quick unrelated question while a run is going

The mental model: /steer modifies the current job; /btw and /side open a side conversation.

Putting a /steer workflow together

A simple, useful setup for a self-hosted personal agent:

  1. Confirm messages.queue: "steer" (the default since v2026.4.29).
  2. Set messages.groupChat.visibleReplies: "send" for any group channel routed to the agent.
  3. Set messages.groupChat.queue: "steer" per group channel that has more than two humans in it.
  4. Run doctor and let it migrate any legacy queue settings forward.

That gets you mid-run steering across direct chat, Slack, Discord, Telegram and the Control UI in . If you want to learn how the rest of the runtime fits together (sessions, agents, cron, channels), see How works and the cron jobs scheduling guide. For more recent v2026.5.x feature work, see the bundled file-transfer plugin and paired-node policy and the Discord voice agent setup walkthrough.

FAQ

Does /steer work in cron-scheduled sessions?

Yes, with caveats. Cron jobs run in isolated sessions, and a /steer message has to be sent to the same session key the cron run is using. The cleanest pattern is: the cron job runs in an isolated session, the human steers via Control UI or via the channel the cron job is delivering to. If the cron job’s delivery.mode is none, there is no channel to steer through.

What happens if I /steer at idle?

The steering message is buffered. Nothing visible happens until a new run begins on that session, and then the buffered steering is applied at the first model boundary. This is intentional: /steer is queue-independent, so it does not start a fresh turn the way a regular message at idle does.

Does /steer count as a new turn for billing or rate limits?

No. It drains into the active run as additional steering context. From the model’s perspective it is more input on the same turn, not a new request. For self-hosted setups using your own API keys, this means /steer is cheaper than aborting and restarting.

What if I am still on the legacy queue mode?

/steer still works. The command is queue-independent and explicitly drains into the active run regardless of the configured queue mode. You can use /steer on every send and ignore the queue setting entirely, or run messages.queue: "steer" so that regular messages get the same behaviour without prefixing each one.

Can I see what was steered in the run log?

Yes. The dispatched steering messages appear in the session transcript labelled as steering rather than as standalone user turns. Control UI shows them inline in the active run; CLI session views show them in the same transcript path.

Sources