Send instructions during a task
Give a running agent a new instruction and track how it is delivered.
Send an instruction
Section titled “Send an instruction”Create a steering controller and pass it to the dispatch. While the task runs, send() submits another instruction and resolves when Outpost can report how it was delivered.
send() resolves when the agent receives the text, not when it has acted on it. The agent reads it as one more user message; the brief still applies.
How it reaches each agent
Section titled “How it reaches each agent”| Agent | mode | What happens |
|---|---|---|
| Built-in harness | injected | Added to the next model request, after the current tool results. A model about to finish continues instead. |
| Claude Code | injected | Written to its stream-json input. It joins the running turn, or runs next in the same process if Claude was already answering. |
| Codex | injected | A steered dispatch runs codex app-server. turn/steer adds the text to the active turn, or starts the next one. |
| Copilot CLI, Kimi Code, Antigravity | resumed | Outpost stops the process once its conversation is known, then resumes it with the text in the same sandbox. |
With resumed, the action in progress is cut short, but files already changed stay in the workspace. Every sandbox provider carries live input; on Vercel and Daytona each instruction costs one provider command and arrives a moment later.
When you send it
Section titled “When you send it”| You send it | What happens | mode |
|---|---|---|
| Before the agent starts | Appended to the prompt. | injected |
| During the turn | Delivered as in the table above. | injected / resumed |
| After the agent answered | Outpost resumes the conversation in a new turn, so the result reflects it. | resumed |
| While no dispatch uses the controller | Waits for the next dispatch that receives the controller. | ― |
An instruction the dispatch cannot deliver, for example because the agent never reported a conversation, is rejected when the dispatch ends. The rejection is an OutpostError with code steering and the text in details.text.
Target a built-in subagent
Section titled “Target a built-in subagent”Each built-in subagent run has an id, reported by its subagent event. Pass it as subagent to reach that run only.
API reference: SteeringSendOptions.
An instruction still waiting when its run ends is rejected with code steering and the run id in details.subagent.
Reuse the controller
Section titled “Reuse the controller”A controller serves one dispatch at a time, across all its passes; attaching it to a second concurrent dispatch fails. Once a dispatch ends, the next one can use it. close() rejects pending instructions and every later send().
result.resume() and result.fork() do not inherit it: pass steering again in their options.
In a workflow, return steering from the request of a defineAgentTask() or defineIsolatedTask(). With a fallback agent, steering follows the candidate that runs.
Events and usage
Section titled “Events and usage”Each delivery emits a steer agent event with text, mode, pass, and subagentId when a subagent received it. The terminal reporter prints it, and the conversation records it as a user message.
A resumed delivery ends the interrupted turn with a stopped event of reason steered; that turn appears in result.turns with interrupted: "steering". A pass still emits one summary, and result.usage includes interrupted turns. A replay reproduces steered runs turn by turn.
Limits
Section titled “Limits”- Instructions live in memory. For questions and answers that must survive a restart, use interactive tasks.
- A dispatch with
steeringrejects agents that can neither take live input nor resume a conversation, including replay agents. - Codex steering uses the
app-serverprotocol, which Codex marks experimental. - Subagents of CLI agents cannot be addressed: an instruction with
subagentis rejected as soon as a CLI turn sees it.
API: createSteering · Steering · SteeringSendOptions · SteeringDelivery · DispatchOptions.