Concurrency modes across agent frameworks
A user often sends a message while the agent is still answering the previous one. Every agent framework has a policy for that moment, but the names don’t agree. “Steer” adds the message to the running turn in Eve and in Runtype, but cancels the turn in Mastra. “Interrupt” keeps the stopped run’s progress in LangGraph and ends the turn in Claude Managed Agents.
This page maps each framework’s term to the Runtype mode that behaves the same way. Use it to reproduce another framework’s behavior on a Runtype agent, or to compare policies before you choose one.
Runtype concurrency modes
You choose a mode per request with the x-runtype-concurrency header. The following table lists what each mode does when the conversation already has a running execution:
The modes apply to saved native Runtype agents on POST /v1/dispatch and POST /v1/agents/{id}/execute. Send the same conversationId on every message in the conversation. Without a conversationId, each request runs on its own: reject, supersede, and queue have no effect, and steer returns INVALID_STEER_ADMISSION. If an agent’s configuration doesn’t support these modes, Runtype ignores reject, supersede, and queue, and returns an error for steer. For the full steer contract, including delivery receipts, see Steer an active agent execution. For auto, including the classifier’s fallbacks and agent configuration, see Route a busy message automatically.
Send an Idempotency-Key header that’s unique for each user message. If a network retry repeats the request, Runtype returns the original execution’s ID instead of queuing or superseding again, and the retry doesn’t count against your quota.
In the TypeScript SDK, pass the headers as the concurrency, coalesce, and idempotencyKey options of client.dispatch.execute(), executeAsync(), and executeStream().
Refusals and errors
A request refused because of its concurrency headers returns one of the following codes. For the other errors that steer can return, see Troubleshoot steer errors.
The CONVERSATION_BUSY body names the running execution’s executionId and its phase: claiming, running, paused, or queued. The response carries a Retry-After header of one second. When the phase is queued, a steer retry returns CONVERSATION_QUEUE_FULL. For what each phase means, see Steer a conversation that answered busy.
On a streaming request, a CONVERSATION_BUSY or CONVERSATION_QUEUE_FULL refusal doesn’t use an HTTP error status. Runtype returns a 200 event stream that contains a single error event with the refusal code and the running execution’s ID. Check the stream’s error event, not only the status code.
Browser clients
Browser clients use the submitMode field on POST /v1/client/chat instead of the header:
normal(default) andinterrupt: supersede the running execution. The two values behave the same way. Runtype records which one the client sent.steer: adds the message to the running execution. SenddurableRecovery: trueonPOST /v1/client/init, and offersteeronly when the response returnsdurableRecovery.steer: true. That requires durable turns turned on for the chat surface or client token. For setup, see Steer from a browser client.auto: lets a classifier steer the message into the running execution or queue it as the next turn. It takes the same message shape assteer, and with nothing running it starts an ordinary turn.
Map a framework’s term to a Runtype mode
The following table maps each framework’s policy to the Runtype mode with the same behavior. The Checked against column records the release or documentation that this mapping was checked against, because several frameworks have changed these semantics between releases. For the page or commit behind each row, see Sources.
Terms that mean different things
Three words cause most of the confusion. Check the framework, not the word, before you pick a Runtype mode.
- Steer: Runtype
steerand Eve’ssteerboth add input to the running turn. Mastra’sSession.steer()stops the run first, so it maps tosupersede. Before release 0.57.0, Eve’ssteeralso cancelled the turn, so older Eve documentation describes thesupersedebehavior. Flue and MastrasendMessage()provide the same behavior as Runtypesteerwithout using the word. - Interrupt: LangGraph’s
interruptand Claude Managed Agents’user.interruptboth map tosupersede. The Runtype browsersubmitMode: "interrupt"also supersedes. LangGraph’s graph-levelinterrupt()function is a different feature: it pauses a run for human input and isn’t a concurrency policy. - Queue: Every framework in the table runs queued input after the current turn. They differ on whether several waiting messages run as separate turns or merge into one. Runtype holds one waiting turn per conversation.
queuealone refuses a second waiting message withCONVERSATION_QUEUE_FULL, andx-runtype-coalesce: truemerges it into the waiting turn.
Differences within a matching mode
A matching mode doesn’t guarantee identical timing. The following differences affect what the user sees:
- Steer timing: When a model request is still waiting for its first output, Eve stops that request and sends it again with the incoming message included. Runtype
steerlets an in-flight model call or tool batch finish, then applies the message at the next boundary. - Queue depth: LangGraph
enqueue, MastraqueueMessage(), and Cloudflare"queue"accept several waiting messages and run them in order. Runtypequeueholds one. To accept more, addx-runtype-coalesce: trueto merge them, or retry afterCONVERSATION_QUEUE_FULL. - Busy response: LangGraph
rejectand Runtyperejectboth refuse the request. Runtype also returns the running execution ID and its phase, so a client can switch tosteerwithout guessing.
Behaviors with no Runtype equivalent
The following policies from other frameworks have no Runtype mode. If your application depends on one, handle it in your client:
- Rollback (LangGraph): removes the stopped run’s progress and its input from the conversation before it runs the incoming message.
- Newest message only (Cloudflare
"latest"and"debounce"): stores older overlapping messages but runs only the newest one. - Store without running (Mastra
persistsignal behavior): adds a message to an idle thread without starting a run. - Separate active and idle policies (Mastra
ifActiveandifIdle): applies one behavior when a run is active and another when the thread is idle. In Runtype,steeron an idle conversation always starts an execution.
Reproduce a framework’s behavior
To make a Runtype agent behave like a framework policy, send the header from the Runtype mode column of the mapping table on every message.
For example, the following requests reproduce Eve’s queue policy. Each one queues the message and merges it with any message that’s already waiting:
Replace the following:
agent_YOUR_AGENT_ID: the ID of your saved native agentRUNTYPE_API_KEY: your Runtype API keyconversation-123: any stable ID that you reuse for every message in the conversationuser-message-42: a key that’s unique for each user message
The Claude Managed Agents row reproduces an explicit interrupt followed by a message. The Claude Managed Agents documentation doesn’t state what a user.message sent during a running turn does without an interrupt, so this page doesn’t map that case.
Sources
Each mapping was checked on 2026-09-25 against the following sources. Where a framework’s documentation carries no version, the link points at the page or the pinned commit that was read:
- Eve 0.66.3: Execution model and durability and the Eve changelog (release 0.57.0 changed
steer). - Flue 2.0.3: Agent API.
- LangGraph: Double texting in the LangSmith documentation.
- Mastra: Signals and the
Session.steer()implementation. - Cloudflare Agents 0.24.0:
MessageConcurrency. - OpenAI Agents SDK:
RealtimeSession.interrupt()in TypeScript andRealtimeSession.interrupt()in Python. - Claude Managed Agents: Session event stream.
Next steps
- Steer an active agent execution: delivery receipts, error codes, and browser steering.
- Route a busy message automatically: let a classifier choose between
steerandqueue. - End-user identity and credentials: keep scope and credential authority consistent across messages.