Session and Turn

The handles of a session and of its turns, and what a turn takes as input.

Guides: Sessions and Turns.

NameWhat it is
SessionA session, named by its ID.
TurnA turn of a session, named by its ID.
SessionInputA value you pass when you start a session, which tools and hooks can read.
DependsMark an Annotated parameter as a session input: Annotated[T, agents.Depends()].
HistoryImportEntryAn entry of a history that seeds a new session, as history= takes it: a message, the model's reasoning, a tool call, a tool result or a snapshot.
HistoryImportMessageA message of the history: what the user, the model or the system said.
HistoryImportReasoningThe model's reasoning, as a history entry.
HistoryImportToolCallA tool call the model made, as a history entry.
HistoryImportToolResultThe result of a tool call, as a history entry: result or error, not both.
HistoryImportSnapshotData saved in the history that the model does not see.
TextContentBlockA block of text.
ImageContentBlockAn image, by URI.
AudioContentBlockAn audio clip, by URI.
ResourceLinkContentBlockA link to a resource, such as a file, that the block does not hold.
EmbeddedResourceContentBlockA resource, such as a file, held in the block as text or as base64 data.
UnknownContentBlockA content block of a type added after your SDK version.
ContentAnnotationsMCP block annotations: who a block is for and how much it matters.
Session

Session

class Session

A session, named by its ID. Binding one with agent.session(session_id) sends no request.

Get one with await agent.start_session(), or bind a stored ID with agent.session(session_id). Both keep the agent's output_type for run, and for the get and result of the session's turns.

on_approval answers the approvals of the session and its subagents while session.run or turn.result waits, with AllowApproval, DenyApproval or agents.KeepCallbackOpen(). on_sign_in answers their sign-ins with a SignInAnswer. on_client_tool answers their client tool calls, so the wait does not return Blocked on them. An approval or sign-in handler that raises, or returns anything else, leaves its callback open, and the waiting call raises while the turn keeps running. A client tool answer or on_client_tool handler that raises follows the agent's tool_errors, as on agent.run: by default the model reads that the call failed and the wait goes on. Two waits at once in one event loop share the answers: the answer runs once per client tool call.

Two handles are equal when they name the same session in the same place: the same Mistral API for a deployed agent, however you loaded it, or the same local runtime. Keep them in a set or as dictionary keys.

AttributeTypeDescription
idstrThe session's ID.
Session.turn

Session.turn

def turn(turn_id: str) -> Turn

Return the handle of a turn of this session. Sends no request.

ParameterTypeDefaultDescription
turn_idstrrequiredThe ID of the turn.
Session.send_message

Session.send_message

async def send_message(
    content: str | Sequence[TextContentBlock | ImageContentBlock | Mapping[str, Any]],
    *,
    idempotency_key: str | None = None,
) -> Turn

Send a message: the session starts a turn, or adds the message to the running one.

turn.started says which: True for a new turn, False for the running one.

Raises agents.SessionBusyError when the session still cannot take the message after its retries; nothing was applied.

ParameterTypeDefaultDescription
contentstr | Sequence[TextContentBlock | ImageContentBlock | Mapping[str, Any]]requiredThe message: a string or content blocks.
idempotency_keystr | NoneNoneMakes the send safe to retry: the same key returns the same turn, and reusing it for another message raises agents.SessionIdempotencyConflictError.
Session.start_turn

Session.start_turn

async def start_turn(
    content: str | Sequence[TextContentBlock | ImageContentBlock | Mapping[str, Any]],
    *,
    idempotency_key: str | None = None,
) -> Turn | Busy

Start a new turn. Returns Busy, with the running turn in busy.turn, when one is active.

The same idempotency_key returns the turn that key started; reusing it for another message raises agents.SessionIdempotencyConflictError while the session runs. A retry with a key refused with Busy starts a turn once the running one ends. A start never joins a running turn, so turn.started is True.

Raises SessionBusyError when the session cannot take a start for another reason, such as a limit on running subagents; nothing was applied.

ParameterTypeDefaultDescription
contentstr | Sequence[TextContentBlock | ImageContentBlock | Mapping[str, Any]]requiredThe message that starts the turn: a string or content blocks.
idempotency_keystr | NoneNoneNames the start, so a retry with it returns the turn it started.
Session.run

Session.run

async def run(
    content: str | Sequence[TextContentBlock | ImageContentBlock | Mapping[str, Any]],
    *,
    output_type: type[BaseModel] | None = None,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    on_event: Callable[[Event], Awaitable[None] | None] | None = None,
) -> TurnState[Any] | Busy

Start a turn and wait for it to end, or to wait on a callback; return its record.

Returns Busy when another turn is active. It is start_turn, then turn.result(timeout=, on_event=): leaving the wait does not stop the turn. With the handle's on_client_tool, it raises what Turn.result raises for a client tool answer.

ParameterTypeDefaultDescription
contentstr | Sequence[TextContentBlock | ImageContentBlock | Mapping[str, Any]]requiredThe message that starts the turn: a string or content blocks.
output_typetype[BaseModel] | NoneNoneA Pydantic model that validates the output of a Completed record (see Turn.result). Without it, the handle's agent's output_type does, if it has one.
idempotency_keystr | NoneNoneNames the start, so a retry with it returns the turn it started.
timeoutfloat | NoneNoneThe most seconds to wait for the turn, not counting the start. An on_approval or on_sign_in handler's time counts; your client-tool code does not. None waits with no limit.
on_eventCallable[[Event], Awaitable[None] | None] | NoneNoneA plain or async function called with each of the turn's events while the call waits. When the turn has ended, the last event is TurnEnded.
Session.iter_events

Session.iter_events

def iter_events(*, after: TurnState[object] | str | None = None) -> AsyncIterator[Event]

Yield the session's events after after, a record or a cursor, or from its start.

It follows the session until the session ends, and never changes anything. It reads each ended turn, so each TurnEnded carries its record.

ParameterTypeDefaultDescription
afterTurnState[object] | str | NoneNoneA record or a cursor to continue after. None starts at the session's start.
Raises
ObservationLostThe session's events could not be read again; continue after its cursor.
InvalidCursorErrorAt the first iteration, after is a record or a cursor of another session, or a cursor that is not valid.
Session.cancel

Session.cancel

async def cancel() -> None

End the session and its subagents. A session that already ended is left as it is.

Running turns are interrupted, and the session takes no new command: a later send raises SessionTerminatedError. Its history stays readable. A deployed cancel returns once the deployment accepts it; a local one returns once the session has ended and released its sandbox. A subagent cannot be cancelled on its own. Cancel its root session instead.

Session.subagents

Session.subagents

async def subagents() -> list[Session]

Return the handles of this session's direct subagents, newest first.

A subagent's handle reads, and its turns take interrupt: send_message, start_turn, run and cancel on the handle, and steer on its turns, raise UnsupportedSessionProcedureError. To redirect a subagent, message or steer its parent; to stop it, cancel its root session. It has this handle's on_approval, on_sign_in and on_client_tool.

Turn

Turn

class Turn

A turn of a session, named by its ID. Binding one with session.turn(turn_id) sends no request.

Get one with session.turn(turn_id), or from a send. Two handles of the same turn of the same session are equal.

AttributeTypeDescription
idstrThe turn's ID.
startedbool | NoneTrue for a turn a send started, False for a running turn a send joined. None for a handle that did not come from a send, such as one bound by ID.
Turn.get

Turn.get

async def get() -> TurnState[Any]

Read this turn's state now. Never waits and never changes the turn.

Returns Running, Blocked (the turn waits on a callback), or the record of how the turn ended: Completed, Interrupted, Failed or UnknownOutcome. Completed.output is the turn's text, or, when the handle's agent has an output_type, that text parsed as on result(output_type=...). The record's cursor is the session's last event ID when the record was read. The session's active turn is Blocked also while one of its subagents, at any depth, waits on a callback, such as an approval: Blocked.callbacks lists it with the subagent's IDs. A turn of a session that ended is never Running. When the session did not report how the turn ended, the turn reads as the session ended: for a cancelled session, Interrupted with cause="cancelled". A turn a send returned is Running until the session lists it: a deployed agent answers the send before it does.

Raises
TurnNotFoundErrorThe session has no turn with this ID. Never for a turn a send returned, nor for busy.turn.
Turn.result

Turn.result

async def result(
    *,
    output_type: type[BaseModel] | None = None,
    after: TurnState[object] | str | None = None,
    timeout: float | None = None,
    on_event: Callable[[Event], Awaitable[None] | None] | None = None,
) -> TurnState[Any]

Wait for the turn to end, or to wait on a callback, and return its record.

Returns Completed, Interrupted, Failed or UnknownOutcome when the turn ends, and Blocked when it waits on a callback opened after after that is still open. At the deadline, it returns the turn's record at that moment, Running or Blocked, and raises nothing.

Leaving the wait sends nothing, and the turn keeps running. A cancel, such as asyncio.wait_for or Ctrl-C, gets a note with the IDs and how to stop the turn.

Without after, a turn that waits on any callback returns at once. Pass this turn's last record as after to wait past the callbacks you already handled.

ParameterTypeDefaultDescription
output_typetype[BaseModel] | NoneNoneA Pydantic model that the turn's text is parsed into, as Completed.output. Defaults to the handle's agent's output_type.
afterTurnState[object] | str | NoneNoneA record of this session, or its cursor, to read the turn's events after. Defaults to this turn's start: callbacks of earlier turns don't count. Pass this turn's record, or one read before this turn started. Another turn's record, read while this turn ran, can miss some of this turn's events.
timeoutfloat | NoneNoneThe most seconds to wait for the turn. An on_approval or on_sign_in handler's time counts; your client-tool code does not. None waits as long as the turn does.
on_eventCallable[[Event], Awaitable[None] | None] | NoneNoneA plain or async function called with each of the turn's events, in order, while the call waits. When the turn has ended, the last event is TurnEnded.
Raises
ObservationLostThe session's events, or its subagents' callbacks, could not be read; the turn keeps running.
TurnNotFoundErrorThe session has no turn with this ID. Never for a turn a send returned, nor for busy.turn: until the session lists it, the wait follows its events.
InvalidCursorErrorafter is a record or a cursor of another session, raised before any read, or a cursor the session never had, raised only when the wait reads the events.
ClientToolAnswerErrorThe handle's on_client_tool answered a call, and the answer could not be sent; the call stays open.
ExceptionWith tool_errors="raise", the exception a client tool answer or on_client_tool handler raised; its call stays open.
Turn.iter_events

Turn.iter_events

def iter_events(*, after: TurnState[object] | str | None = None) -> AsyncIterator[Event]

Yield this turn's events after after, or from its start, up to its TurnEnded.

It yields the events the session has, then the live ones, with no time limit: a turn that waits on an approval can send no event for hours. When the turn ended, the last is TurnEnded, with its record, and a position at or after its end yields nothing, at once. It changes nothing.

ParameterTypeDefaultDescription
afterTurnState[object] | str | NoneNoneThis turn's record, a record read before this turn started (such as the previous turn's result), or a cursor inside this turn. None starts after the previous turn's end.
Raises
ObservationLostThe session's events could not be read again; continue after its cursor.
TurnNotFoundErrorAt the first iteration, the session has no turn with this ID. Never for a turn a send returned, nor for busy.turn.
InvalidCursorErrorAt the first iteration, after is a record or a cursor of another session, or a cursor that is not valid.
Turn.steer

Turn.steer

async def steer(
    content: str | Sequence[TextContentBlock | ImageContentBlock | Mapping[str, Any]],
) -> Turn | TurnConflict

Add a message to this turn while it runs.

Returns TurnConflict when this turn is no longer the active one: the message is not added.

ParameterTypeDefaultDescription
contentstr | Sequence[TextContentBlock | ImageContentBlock | Mapping[str, Any]]requiredThe message to add: a string or content blocks.
Turn.answer

Turn.answer

async def answer(callback_id: str, answer: object) -> Answered | AlreadySettled | NotFound

Answer any open callback of this turn's session or of its subagents, from any turn, by its callback ID. The turn's ID is not used: a callback's ID names it in its session.

An approval (OpenApproval) takes AllowApproval or DenyApproval. A sign-in (OpenSignIn) takes a SignInAnswer that names each source it asks for, and only those. A client tool call (OpenClientToolCall) takes the tool's result: what an answer function would return, such as a model, a dict or a ToolResult. When the stub is in the tools= of the agent or of its subagents, the result is checked against the stub's return type and sent as its answer is. Otherwise it is sent as JSON, unchecked: a tool built with output_schema=, a hook's tool, a tool ID that two different stubs share, or a handle from Agent.load_from().

Reads the session once, then answers. Returns Answered when the callback was open, AlreadySettled when it is no longer open (another client answered it first, or it closed), and NotFound when the session never opened it. A subagent's open callback, listed in the root's Blocked.callbacks, is answered on the subagent's session, and the record names that session; once it is no longer open, the root says NotFound and the subagent's own session, agent.session(callback.session_id), says AlreadySettled.

For an approval, Answered.answer is the answer that counted: two clients that answer at the same time both get Answered, with the answer of the one that came first, so compare it with yours. It is None when the answer that counted could not be read in time; read the turn to see the outcome. For a client tool call and a sign-in it is None: the first result sent counts. Local and deployed sessions do the same.

An approval's answer is AllowApproval or DenyApproval, never a bool, a dict or None. KeepCallbackOpen() is a handler's return, never an answer: to leave a callback open, do not answer it.

ParameterTypeDefaultDescription
callback_idstrrequiredThe ID of the open callback, as in Blocked.callbacks.
answerobjectrequiredThe answer of the callback's kind: AllowApproval or DenyApproval, a SignInAnswer, or a client tool's result.
Raises
ValueErrorcallback_id is not a UUID (nothing is sent).
SdkErroranswer is KeepCallbackOpen() or does not fit the callback, or two subagents have a callback open with that ID. Also when answer allows a hook's approval for the whole session (AllowApproval(scope="session")), or the callback is a client tool call of a tool the platform provides, such as one in the connectors namespace. Nothing is sent. A sign-in arrives as OpenSignIn and takes a SignInAnswer.
ObservationLostThe callback is open nowhere, and the session's events could not be read.
Turn.interrupt

Turn.interrupt

async def interrupt() -> Turn | TurnConflict

Stop this turn; the session stays open for new turns.

Returns TurnConflict when this turn is no longer the active one.

Input

Input

SessionInput

SessionInput

class SessionInput(pydantic.BaseModel)

A value you pass when you start a session, which tools and hooks can read.

Subclass it with the fields you need, such as a repository or an organization, and set input_id. A tool, a hook or a sandbox hook reads it with a parameter annotated Annotated[YourInput, agents.Depends()]; the model never sees it. Never put a credential in it: the session keeps it for its whole lifetime.

A rule that only a validator expresses is checked where the value is used, and a rejected value fails that use. Never put the value in a validator's message, since the message reaches turn results and the model.

A session keeps its inputs for its whole lifetime, across new deployments of the agent, so a change to a class must keep accepting the values its previous version accepted.

AttributeTypeDescription
input_idstrThe input's stable name, which a session uses to find it. It is not part of the value.
Depends

Depends

class Depends()

Mark an Annotated parameter as a session input: Annotated[T, agents.Depends()].

The annotated type T is the input class, declared once.

HistoryImportEntry

HistoryImportEntry

type HistoryImportEntry = (
    HistoryImportMessage
    | HistoryImportReasoning
    | HistoryImportToolCall
    | HistoryImportToolResult
    | HistoryImportSnapshot
)

An entry of a history that seeds a new session, as history= takes it: a message, the model's reasoning, a tool call, a tool result or a snapshot. Give each entry as one of the classes below, or as a dict of the same fields, in snake case or camelCase, with its type: "message", "reasoning", "tool_call", "tool_result" or "snapshot".

HistoryImportMessage

HistoryImportMessage

class HistoryImportMessage(
    *,
    role: Literal['system', 'user', 'assistant'],
    content: list[ContentBlock] = [],
)

A message of the history: what the user, the model or the system said.

ParameterTypeDefaultDescription
roleLiteral['system', 'user', 'assistant']required"system", "user" or "assistant".
contentlist[ContentBlock][]The message's content blocks. A system message takes text blocks only, and an assistant message takes no embedded resource.
AttributeTypeDescription
typeLiteral['message']Always "message".
HistoryImportReasoning

HistoryImportReasoning

class HistoryImportReasoning(*, text: str)

The model's reasoning, as a history entry.

ParameterTypeDefaultDescription
textstrrequiredThe model's reasoning.
AttributeTypeDescription
typeLiteral['reasoning']Always "reasoning".
HistoryImportToolCall

HistoryImportToolCall

class HistoryImportToolCall(
    *,
    tool_call_id: str,
    tool_kind: Literal['builtin', 'local', 'mcp', 'client', 'plugin', 'connector'] = 'local',
    name: str,
    arguments: JsonValue = None,
)

A tool call the model made, as a history entry.

ParameterTypeDefaultDescription
tool_call_idstrrequiredThe ID of the call: its result carries the same ID.
tool_kindLiteral['builtin', 'local', 'mcp', 'client', 'plugin', 'connector']'local'Where the tool comes from, such as "local" or "mcp".
namestrrequiredThe name of the tool the model called.
argumentsJsonValueNoneThe call's arguments, as the history shows them: the model's, or the ones a pre_tool_call hook set.
AttributeTypeDescription
typeLiteral['tool_call']Always "tool_call".
HistoryImportToolResult

HistoryImportToolResult

class HistoryImportToolResult(
    *,
    tool_call_id: str,
    name: str | None = None,
    result: JsonValue = None,
    error: ProtocolError | None = None,
    annotations: dict[str, JsonValue] = {},
)

The result of a tool call, as a history entry: result or error, not both.

ParameterTypeDefaultDescription
tool_call_idstrrequiredThe ID of the call this is the result of.
namestr | NoneNoneThe name of the tool, or None.
resultJsonValueNoneThe tool's result, for a call that succeeded.
errorProtocolError | NoneNoneFor a failed call, its error, such as {"message": "..."}, in place of result: an entry with both is refused.
annotationsdict[str, JsonValue]{}Metadata kept with the result.
AttributeTypeDescription
typeLiteral['tool_result']Always "tool_result".
HistoryImportSnapshot

HistoryImportSnapshot

class HistoryImportSnapshot(*, task_name: str, snapshot_type: str, value: JsonValue = None)

Data saved in the history that the model does not see. The session's history shows it as an agents.UnknownEntry of type "checkpoint": raw["message"] is task_name:snapshot_type, and raw["details"] is value.

ParameterTypeDefaultDescription
task_namestrrequiredThe task the snapshot is of. The checkpoint's message is task_name:snapshot_type.
snapshot_typestrrequiredThe kind of snapshot.
valueJsonValueNoneThe snapshot's data, kept as the checkpoint's details. The model does not read it.
AttributeTypeDescription
typeLiteral['snapshot']Always "snapshot".
TextContentBlock

TextContentBlock

class TextContentBlock(
    *,
    annotations: ContentAnnotations | None = None,
    meta: dict[str, JsonValue] | None = None,
    text: str = '',
)

A block of text.

ParameterTypeDefaultDescription
annotationsContentAnnotations | NoneNoneWho the block is for and how much it matters, as MCP annotations.
metadict[str, JsonValue] | NoneNoneMetadata for your client, as MCP _meta. The model never sees it. Must be a JSON object.
textstr''The text.
AttributeTypeDescription
typeLiteral['text']Always "text".
ImageContentBlock

ImageContentBlock

class ImageContentBlock(
    *,
    annotations: ContentAnnotations | None = None,
    meta: dict[str, JsonValue] | None = None,
    uri: str,
    media_type: str | None = None,
    alt_text: str | None = None,
)

An image, by URI.

ParameterTypeDefaultDescription
annotationsContentAnnotations | NoneNoneWho the block is for and how much it matters, as MCP annotations.
metadict[str, JsonValue] | NoneNoneMetadata for your client, as MCP _meta. The model never sees it. Must be a JSON object.
uristrrequiredThe image's URI, such as a data: URI that holds the image in base64.
media_typestr | NoneNoneThe image's media type, such as "image/png".
alt_textstr | NoneNoneA text description of the image.
AttributeTypeDescription
typeLiteral['image']Always "image".
ImageContentBlock.from_bytes

ImageContentBlock.from_bytes

@classmethod
def from_bytes(
    data: bytes,
    media_type: str | None = None,
    *,
    alt_text: str | None = None,
    annotations: ContentAnnotations | None = None,
) -> ImageContentBlock

An inline image; the media type is read from PNG, JPEG, GIF or WebP bytes.

ParameterTypeDefaultDescription
databytesrequiredThe image's bytes.
media_typestr | NoneNoneThe image's media type. Defaults to the one read from the bytes.
alt_textstr | NoneNoneA text description of the image.
annotationsContentAnnotations | NoneNoneWho the block is for and how much it matters.
ImageContentBlock.from_path

ImageContentBlock.from_path

@classmethod
def from_path(
    path: str | PathLike[str],
    media_type: str | None = None,
    *,
    alt_text: str | None = None,
    annotations: ContentAnnotations | None = None,
) -> ImageContentBlock

An inline image read from a local file. Its base64 is at most 10,000,000 characters, a file of about 7.5 MB; a larger file raises ValueError.

ParameterTypeDefaultDescription
pathstr | PathLike[str]requiredThe image file.
media_typestr | NoneNoneThe image's media type. Defaults to the one read from the file's bytes.
alt_textstr | NoneNoneA text description of the image.
annotationsContentAnnotations | NoneNoneWho the block is for and how much it matters.
AudioContentBlock

AudioContentBlock

class AudioContentBlock(
    *,
    annotations: ContentAnnotations | None = None,
    meta: dict[str, JsonValue] | None = None,
    uri: str,
    media_type: str | None = None,
)

An audio clip, by URI.

ParameterTypeDefaultDescription
annotationsContentAnnotations | NoneNoneWho the block is for and how much it matters, as MCP annotations.
metadict[str, JsonValue] | NoneNoneMetadata for your client, as MCP _meta. The model never sees it. Must be a JSON object.
uristrrequiredThe clip's URI, such as a data: URI that holds the clip in base64.
media_typestr | NoneNoneThe clip's media type, such as "audio/wav".
AttributeTypeDescription
typeLiteral['audio']Always "audio".
ResourceLinkContentBlock

ResourceLinkContentBlock

class ResourceLinkContentBlock(
    *,
    annotations: ContentAnnotations | None = None,
    meta: dict[str, JsonValue] | None = None,
    uri: str,
    name: str | None = None,
    title: str | None = None,
    description: str | None = None,
    media_type: str | None = None,
    size: int | None = None,
)

A link to a resource, such as a file, that the block does not hold.

ParameterTypeDefaultDescription
annotationsContentAnnotations | NoneNoneWho the block is for and how much it matters, as MCP annotations.
metadict[str, JsonValue] | NoneNoneMetadata for your client, as MCP _meta. The model never sees it. Must be a JSON object.
uristrrequiredThe resource's URI.
namestr | NoneNoneThe resource's name.
titlestr | NoneNoneA name for people.
descriptionstr | NoneNoneWhat the resource is.
media_typestr | NoneNoneThe resource's media type.
sizeint | NoneNoneThe resource's size, in bytes.
AttributeTypeDescription
typeLiteral['resource_link']Always "resource_link".
EmbeddedResourceContentBlock

EmbeddedResourceContentBlock

class EmbeddedResourceContentBlock(
    *,
    annotations: ContentAnnotations | None = None,
    meta: dict[str, JsonValue] | None = None,
    uri: str,
    media_type: str | None = None,
    text: str | None = None,
    blob: str | None = None,
)

A resource, such as a file, held in the block as text or as base64 data.

ParameterTypeDefaultDescription
annotationsContentAnnotations | NoneNoneWho the block is for and how much it matters, as MCP annotations.
metadict[str, JsonValue] | NoneNoneMetadata for your client, as MCP _meta. The model never sees it. Must be a JSON object.
uristrrequiredThe resource's URI.
media_typestr | NoneNoneThe resource's media type.
textstr | NoneNoneThe resource's text. Set exactly one of text and blob.
blobstr | NoneNoneThe resource's data, in base64. Set exactly one of text and blob.
AttributeTypeDescription
typeLiteral['embedded_resource']Always "embedded_resource".
UnknownContentBlock

UnknownContentBlock

class UnknownContentBlock(*, original_type: str)

A content block of a type added after your SDK version. Its type is unknown, so a match on type still works for the known blocks; original_type names its type, and its other fields are kept as they came. A turn's input cannot hold one.

ParameterTypeDefaultDescription
original_typestrrequiredThe block's type as it came.
AttributeTypeDescription
typeLiteral['unknown']Always "unknown".
ContentAnnotations

ContentAnnotations

class ContentAnnotations(
    *,
    audience: list[Literal['user', 'assistant'] | str] | None = None,
    priority: float | None = None,
    last_modified: str | None = None,
)

MCP block annotations: who a block is for and how much it matters.

A tool result block whose audience excludes "assistant" is never sent to the model; a client may hide a block whose audience excludes "user". priority must be between 0 and 1.

ParameterTypeDefaultDescription
audiencelist[Literal['user', 'assistant'] | str] | NoneNoneWho the block is for: "user", "assistant" or both. None for both.
priorityfloat | NoneNoneHow much the block matters. Must be between 0 and 1.
last_modifiedstr | NoneNoneWhen the block's content last changed, as an ISO 8601 timestamp.