- the room messaging fabric that carries messages between participants
- the thread that defines continuity and persistence
- the turn lifecycle that tells clients what one active run is doing right now
Why turns are separate from plain messages
Plain room messages are good for discrete participant-to-participant communication. Process-backed agents need more than that. They need to:- accept work from several channels
- assign that work to a specific thread
- report that the work was accepted before it actually starts
- stream progress while the turn is still running
- allow steering or interruption of the active turn
- mark the point where the turn started and ended
Turn lifecycle
At a high level, the flow looks like this:- A client sends
meshagent.agent.turn.start. - The runtime replies with
meshagent.agent.turn.start.accepted. - When execution actually begins, the runtime emits
meshagent.agent.turn.started. - While the turn runs, the runtime can emit text deltas, tool call events, approval requests, and other live updates.
- When the turn finishes or fails, the runtime emits
meshagent.agent.turn.ended.
turn.start.acceptedmeans the runtime accepted the requestturn.startedmeans that specific turn is now activeturn.endedmeans that active turn is finished
Core turn messages
| Message or event | What it means |
|---|---|
meshagent.agent.turn.start | Start a new turn for a given thread_id with typed input content. |
meshagent.agent.turn.start.accepted | The runtime accepted the request and tied it to the source message. |
meshagent.agent.turn.started | The turn is now active and has a turn_id. |
meshagent.agent.turn.steer | Add more input to the active turn without starting a separate turn. |
meshagent.agent.turn.interrupt | Interrupt the active turn. |
meshagent.agent.turn.ended | The turn completed or failed. |
What a turn start carries
A turn start request includes:thread_id: which persisted thread this work belongs tomessage_id: the client-side message id for correlationcontent: typed input items such as text or files- optional
model: override the model for this turn - optional
instructions: extra instructions for this turn - optional toolkit configuration
- optional tool choice
Steering and interruption
Steering and interruption are part of the same turn model. Use steering when the turn should continue but needs more input. For example:- a user clarifies what they meant
- a UI wants to append more instructions
- a workflow injects follow-up context while the turn is still live
- the user cancelled the request
- the UI is starting a different turn instead
- a tool flow became irrelevant or stale
turn_id.
How turns relate to threads
A thread can contain many turns over time. The thread gives the runtime a persisted continuity boundary. The turn gives the runtime a live execution boundary. That means:- thread answers “what history does this work belong to?”
- turn answers “what active run is happening right now?”
How turns relate to messaging
Turn messages are carried over the same room messaging fabric used by other participant messages, but they are not the same thing as the general-purpose Messaging API. Use the Messaging API when you want:- direct participant messages
- broadcasts
- attachments
- participant discovery
- process-backed agent execution
- active-turn lifecycle updates
- steering or interruption
- thread-aware runtime control