Skip to main content
For a guided walkthrough, see Use an agent — Subscribe to events.

Turn Events

turn.execute({ stream: true }) (or turn.stream() when reconnecting) streams Server-Sent Events (SSE). Each event is a JSON object with a type field.
  • The stream always opens with turn.created and closes with turn.done.
  • All events carry a thread_id. Thread-scoped events use "main" (root agent) or a unique sub-agent ID; turn-level events use None.
  • thread.created and thread.done track sub-agent threads only - they are not emitted for the main thread, which is created automatically on the first Turn and lives for the session’s lifetime.
  • All events carry an id. It identifies the logical event and is present in both stream() and list_events().
  • Events delivered via execute({ stream: true }) and stream() also carry a sequence_number, monotonically increasing within a turn.
  • All events carry a created_at ISO-8601 timestamp marking when the event was emitted.
  • turn.created and turn.done are stream-only; they appear on the stream but are not returned by listEvents() / list_events().

TurnCreatedEvent

First event on every Turn stream, carrying the Turn’s turn_id and metadata. Stream-only.

ModelMessageDeltaEvent

The most frequent SSE event. Carries an incremental LLM delta for one message - assistant text and/or tool call chunks. Every delta shares the id of the base ModelMessageEvent it belongs to; merge each delta into that base event in your id-keyed event index. A delta with a non-null finish_reason signals the message is complete. Use the merge pattern to fold a delta into its base event in place. Import is_event_delta and merge_event_delta from truefoundry_gateway_sdk.agents (Python) or truefoundry-gateway-sdk/agents (TypeScript). Each ToolCallDelta is shaped like an OpenAI streaming tool-call chunk. id, type, and tool_info appear only on the first chunk for a given index; function.arguments is a partial JSON string concatenated across chunks. ToolCallFunctionDelta: ToolCallInfo carries metadata about the tool, discriminated on type. Read the tool name from name. For MCP-backed tools (type: "mcp"): For built-in TrueFoundry system tools (type: "truefoundry-system"), for example ask_user_question:

ModelMessageEvent

The complete, assembled form of a model message: fully concatenated content and fully reconstructed tool_calls, with finish_reason set. Returned by listEvents() / list_events(); on the stream, the assistant output arrives as ModelMessageDeltaEvent deltas that merge into a base event with the same id. Each ToolCall is shaped like OpenAI’s ChatCompletionMessageToolCall. Read the tool name from tool_info.name. ToolCallFunction:

ToolResponseEvent

A complete server-side tool result returned to the LLM. Not a streaming delta - one event carries the full result.

ThreadCreatedEvent

Emitted when a sub-agent thread starts.
Not emitted for the main thread. The main thread (thread_id: "main") is the root agent; it is created automatically on the session’s first Turn and is never the subject of a thread.created or thread.done event. thread.created/thread.done track only sub-agent threads.
AgentInfo:

ThreadDoneEvent

Emitted when a sub-agent thread reaches a terminal state. Does not terminate the overall turn stream. Inspect state.status ("done" or "error") on the nested ThreadState object.
Not emitted for the main thread. The main thread is never “done” - it lives across Turns for the lifetime of the session. The overall Turn’s completion is signalled by turn.done, and the session ends only when it is cancelled.

McpInitializeEvent

Emitted when one or more MCP server sessions are initialized for a thread.

SandboxCreatedEvent

Emitted once when a sandbox is provisioned for the Turn. The sandbox is reused across Turns within the session.

McpAuthRequiredEvent

Emitted when one or more MCP servers require OAuth authorization before the agent can proceed. The stream ends after this event. Resume by creating a new turn on the same session with prepareTurn() / prepare_turn() after the user completes the OAuth flow — no input is required (omit input or pass []).

ToolApprovalRequiredEvent

Emitted when one or more tool calls require explicit human approval before they can run. The stream ends after this event. Resume by creating a new turn with UserToolApprovalEvent items — one per pending tool_call_id — via prepareTurn() / prepare_turn().

ToolResponseRequiredEvent

Emitted when the agent has called a client-side tool and is waiting for the result. The stream ends after this event. Resume by creating a new turn with UserToolResponseEvent items — one per pending tool_call_id — via prepareTurn() / prepare_turn().

TurnDoneEvent

Final event on every turn stream. Stream-only. Its state is the terminal state object — the same value in turn.state once the turn completes — so callers don’t need a separate turn fetch to know what happened.

TurnTerminalState

The terminal lifecycle state of a turn, available on turn.state and carried by TurnDoneEvent’s state. It is one of three objects, discriminated on status: TurnStateDone, TurnStateCancelled, or TurnStateError. (The non-terminal TurnStateRunning, on turn.state while a turn is still running, has only status: "running".)

TurnStateDone

The turn completed normally.

TurnStateCancelled

The turn was cancelled.

TurnStateError

The turn failed.