> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeroruntime.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Chat & Context

> Python API reference for Chat & Context.

The conversation state an agent carries: chat context and messages, function-call
records, and image content, plus helpers for windowing history and encoding images
for vision.

## ChatContext

Mutable container for a conversation's messages and agent handoffs.

Holds the ordered list of `ChatMessage` items that make up a conversation
along with any `AgentHandoff` records, and provides helpers for adding
messages, estimating size, truncating history, and converting to and from
transport message formats.

### Constructor

```python theme={null}
ChatContext(initial_messages: 'Optional[List[ChatMessage]]' = None, initial_handoffs: 'Optional[List[AgentHandoff]]' = None)
```

<ParamField path="initial_messages" type="Optional[List[ChatMessage]]">
  Messages to seed the context with. Copied into a new list; defaults to empty.
</ParamField>

<ParamField path="initial_handoffs" type="Optional[List[AgentHandoff]]">
  Handoff records to seed the context with. Copied into a new list; defaults to empty.
</ParamField>

### add\_attributed\_message

```python theme={null}
def add_attributed_message(self, role: 'ChatRole', content: 'str', agent_id: 'str', message_id: 'Optional[str]' = None, images: 'Optional[List[ImageContent]]' = None) -> 'ChatMessage'
```

Append a message attributed to a specific agent.

<ParamField path="role" type="ChatRole" required>
  The role of the message author.
</ParamField>

<ParamField path="content" type="str" required>
  The message text. Non-string values are coerced to `str`.
</ParamField>

<ParamField path="agent_id" type="str" required>
  Identifier of the agent that produced the message.
</ParamField>

<ParamField path="message_id" type="Optional[str]">
  Identifier for the message. A new UUID is generated when not provided.
</ParamField>

<ParamField path="images" type="Optional[List[ImageContent]]">
  Optional image attachments for the message.
</ParamField>

<ResponseField name="returns" type="ChatMessage">
  The newly created and appended `ChatMessage`.
</ResponseField>

### add\_handoff

```python theme={null}
def add_handoff(self, to_agent: 'str', from_agent: 'str' = '', reason: 'str' = '') -> 'AgentHandoff'
```

Record a handoff from one agent to another.

<ParamField path="to_agent" type="str" required>
  Identifier of the agent receiving control.
</ParamField>

<ParamField path="from_agent" type="str" default="">
  Identifier of the agent relinquishing control.
</ParamField>

<ParamField path="reason" type="str" default="">
  Optional explanation for the handoff.
</ParamField>

<ResponseField name="returns" type="AgentHandoff">
  The newly created and appended `AgentHandoff` with a generated id.
</ResponseField>

### add\_message

```python theme={null}
def add_message(self, role: 'ChatRole', content: 'str', message_id: 'Optional[str]' = None, images: 'Optional[List[ImageContent]]' = None, created_at: 'Optional[float]' = None, replace: 'bool' = False) -> 'ChatMessage'
```

Append a message to the context.

<ParamField path="role" type="ChatRole" required>
  The role of the message author.
</ParamField>

<ParamField path="content" type="str" required>
  The message text. Non-string values are coerced to `str`.
</ParamField>

<ParamField path="message_id" type="Optional[str]">
  Identifier for the message. A new UUID is generated when not provided.
</ParamField>

<ParamField path="images" type="Optional[List[ImageContent]]">
  Optional image attachments for the message.
</ParamField>

<ParamField path="created_at" type="Optional[float]">
  Optional creation timestamp (currently unused).
</ParamField>

<ParamField path="replace" type="bool" default="False">
  Reserved flag (currently unused).
</ParamField>

<ResponseField name="returns" type="ChatMessage">
  The newly created and appended `ChatMessage`.
</ResponseField>

### copy

```python theme={null}
def copy(self, **kwargs) -> "'ChatContext'"
```

Create a copy of this context.

<ResponseField name="returns" type="'ChatContext'">
  A new `ChatContext` sharing the current messages and handoffs.
</ResponseField>

### empty

```python theme={null}
def empty() -> "'ChatContext'"
```

Create an empty chat context.

<ResponseField name="returns" type="'ChatContext'">
  A new `ChatContext` with no messages or handoffs.
</ResponseField>

### estimated\_tokens

```python theme={null}
def estimated_tokens(self) -> 'int'
```

Estimate the token count of the conversation.

Uses a rough heuristic of two tokens per whitespace-separated word
across all message contents.

<ResponseField name="returns" type="int">
  The estimated total token count.
</ResponseField>

### from\_context\_messages

```python theme={null}
def from_context_messages(messages: 'Any') -> "'ChatContext'"
```

Build a context from transport message dictionaries or objects.

Accepts an iterable of mappings or attribute-bearing objects and
reconstructs `ChatMessage` entries, including any images and tool
calls. Unknown or invalid roles fall back to `ChatRole.USER`.

<ParamField path="messages" type="Any" required>
  An iterable of message mappings or objects, or `None`.
</ParamField>

<ResponseField name="returns" type="'ChatContext'">
  A new `ChatContext` populated with the reconstructed messages.
</ResponseField>

### handoffs

```python theme={null}
def handoffs(self) -> 'List[AgentHandoff]'
```

Return a shallow copy of the recorded handoffs.

<ResponseField name="returns" type="List[AgentHandoff]">
  A new list containing the current `AgentHandoff` records.
</ResponseField>

### last\_handoff

```python theme={null}
def last_handoff(self) -> 'Optional[AgentHandoff]'
```

Return the most recent handoff, if any.

<ResponseField name="returns" type="Optional[AgentHandoff]">
  The last `AgentHandoff` recorded, or `None` when there are none.
</ResponseField>

### messages

```python theme={null}
def messages(self) -> 'List[ChatMessage]'
```

Return a shallow copy of the context's messages.

<ResponseField name="returns" type="List[ChatMessage]">
  A new list containing the current `ChatMessage` objects.
</ResponseField>

### to\_context\_messages

```python theme={null}
def to_context_messages(self) -> 'List[Dict[str, Any]]'
```

Serialize the context to transport message dictionaries.

Each message is emitted with its role and content, and optionally its
`message_id`, `images`, `tool_calls`, and `tool_call_id` when
present.

<ResponseField name="returns" type="List[Dict[str, Any]]">
  A list of dictionaries representing the messages in the SDK's transport format.
</ResponseField>

### to\_openai\_messages

```python theme={null}
def to_openai_messages(self, *, reasoning_model: 'bool' = False) -> 'List[Dict[str, Any]]'
```

Convert the context to OpenAI chat message dictionaries.

<ParamField path="reasoning_model" type="bool" default="False">
  Reserved flag for reasoning-model formatting (currently unused).
</ParamField>

<ResponseField name="returns" type="List[Dict[str, Any]]">
  A list of `&#123;'role', 'content'&#125;` dictionaries, one per message.
</ResponseField>

### truncate

```python theme={null}
def truncate(self, max_items: 'Optional[int]' = None, max_tokens: 'Optional[int]' = None) -> "'ChatContext'"
```

Return a new context trimmed to size limits.

When `max_items` is given, only the most recent messages are kept.
When `max_tokens` is given, the oldest messages are dropped (always
retaining at least one) until the estimated token total fits, using the
same two-tokens-per-word heuristic as `estimated_tokens`.

<ParamField path="max_items" type="Optional[int]">
  Maximum number of messages to retain.
</ParamField>

<ParamField path="max_tokens" type="Optional[int]">
  Maximum estimated token budget to retain.
</ParamField>

<ResponseField name="returns" type="'ChatContext'">
  A new `ChatContext` containing the retained messages.
</ResponseField>

### turn\_count

```python theme={null}
def turn_count(self) -> 'int'
```

Count the number of user turns in the conversation.

<ResponseField name="returns" type="int">
  The number of messages whose role is `ChatRole.USER`.
</ResponseField>

***

## ChatMessage

A single message within a conversation.

### Fields

<ParamField path="role" type="ChatRole" default="user">
  Role of the message author.
</ParamField>

<ParamField path="content" type="str" default="">
  The message text.
</ParamField>

<ParamField path="message_id" type="str" default="">
  Unique identifier for the message.
</ParamField>

<ParamField path="tool_calls" type="List[FunctionCall]" default="…">
  Tool invocations requested by this message.
</ParamField>

<ParamField path="tool_call_id" type="str" default="">
  Identifier of the tool call this message responds to.
</ParamField>

<ParamField path="images" type="List[ImageContent]" default="…">
  Image attachments associated with the message.
</ParamField>

<ParamField path="agent_id" type="str" default="">
  Identifier of the agent that produced the message, if any.
</ParamField>

***

## ChatContent

Textual content part of a chat message.

### Fields

<ParamField path="type" type="str" default="text">
  Content type discriminator; `'text'` for this part.
</ParamField>

<ParamField path="text" type="str" default="">
  The text payload.
</ParamField>

***

## ChatRole

Roles a message can take in a chat conversation.

```python theme={null}
class ChatRole(Enum):
    SYSTEM = 'system'
    USER = 'user'
    ASSISTANT = 'assistant'
    DEVELOPER = 'developer'
```

***

## FunctionCall

A tool invocation requested by the model.

### Fields

<ParamField path="name" type="str" default="">
  Name of the tool to invoke.
</ParamField>

<ParamField path="arguments" type="str" default="">
  Arguments for the call, encoded as a JSON string.
</ParamField>

<ParamField path="call_id" type="str" default="">
  Identifier correlating this call with its output.
</ParamField>

***

## FunctionCallOutput

The result of executing a tool call.

### Fields

<ParamField path="name" type="str" default="">
  Name of the tool that was invoked.
</ParamField>

<ParamField path="output" type="str" default="">
  The tool's output, encoded as a string.
</ParamField>

<ParamField path="call_id" type="str" default="">
  Identifier correlating this output with its originating call.
</ParamField>

<ParamField path="is_error" type="bool" default="False">
  Whether the output represents an error.
</ParamField>

***

## ImageContent

Image content part of a chat message.

### Fields

<ParamField path="type" type="str" default="image">
  Content type discriminator; `'image'` for this part.
</ParamField>

<ParamField path="url" type="str" default="">
  The image location, either an `http(s)` URL or a `data:` URL embedding the image bytes.
</ParamField>

<ParamField path="detail" type="str" default="auto">
  Requested level of detail for the image (e.g. `'auto'`, `'low'`, `'high'`).
</ParamField>

### from\_base64

```python theme={null}
def from_base64(base64_str: 'str', mime_type: 'str', detail: 'str' = 'auto') -> "'ImageContent'"
```

Create image content from a base64-encoded string.

<ParamField path="base64_str" type="str" required>
  The base64-encoded image data.
</ParamField>

<ParamField path="mime_type" type="str" required>
  MIME type of the image (e.g. `'image/jpeg'`).
</ParamField>

<ParamField path="detail" type="str" default="auto">
  Requested level of detail for the image.
</ParamField>

<ResponseField name="returns" type="'ImageContent'">
  An `ImageContent` with a `data:` URL built from the inputs.
</ResponseField>

### from\_bytes

```python theme={null}
def from_bytes(data: 'bytes', mime_type: 'str', detail: 'str' = 'auto') -> "'ImageContent'"
```

Create image content from raw image bytes.

<ParamField path="data" type="bytes" required>
  The raw image bytes.
</ParamField>

<ParamField path="mime_type" type="str" required>
  MIME type of the image (e.g. `'image/jpeg'`).
</ParamField>

<ParamField path="detail" type="str" default="auto">
  Requested level of detail for the image.
</ParamField>

<ResponseField name="returns" type="'ImageContent'">
  An `ImageContent` with a base64 `data:` URL built from the bytes.
</ResponseField>

### from\_data\_url

```python theme={null}
def from_data_url(data_url: 'str', detail: 'str' = 'auto') -> "'ImageContent'"
```

Create image content from a `data:` URL.

<ParamField path="data_url" type="str" required>
  A `data:` URL embedding the image bytes.
</ParamField>

<ParamField path="detail" type="str" default="auto">
  Requested level of detail for the image.
</ParamField>

<ResponseField name="returns" type="'ImageContent'">
  An `ImageContent` referencing the given data URL.
</ResponseField>

### from\_file

```python theme={null}
def from_file(path: 'str', mime_type: 'Optional[str]' = None, detail: 'str' = 'auto') -> "'ImageContent'"
```

Create image content by reading an image file from disk.

<ParamField path="path" type="str" required>
  Filesystem path to the image file.
</ParamField>

<ParamField path="mime_type" type="Optional[str]">
  MIME type of the image. When omitted, it is inferred from the file extension, defaulting to `'image/jpeg'`.
</ParamField>

<ParamField path="detail" type="str" default="auto">
  Requested level of detail for the image.
</ParamField>

<ResponseField name="returns" type="'ImageContent'">
  An `ImageContent` with a base64 `data:` URL of the file contents.
</ResponseField>

### from\_frame

```python theme={null}
def from_frame(frame: 'Any', detail: 'str' = 'auto') -> "'ImageContent'"
```

Create image content from a video or image frame.

Accepts a mapping carrying raw `data` and an optional MIME type, or an
arbitrary frame object that is coerced to JPEG bytes.

<ParamField path="frame" type="Any" required>
  The source frame. May be a mapping with a `data` key (and optional `mime_type`/`mimeType`) or any object accepted by `coerce_image_to_jpeg_bytes`.
</ParamField>

<ParamField path="detail" type="str" default="auto">
  Requested level of detail for the image.
</ParamField>

<ResponseField name="returns" type="'ImageContent'">
  An `ImageContent` with a base64 `data:` URL of the frame image.
</ResponseField>

### from\_url

```python theme={null}
def from_url(url: 'str', detail: 'str' = 'auto') -> "'ImageContent'"
```

Create image content from an `http(s)` URL.

<ParamField path="url" type="str" required>
  The image URL.
</ParamField>

<ParamField path="detail" type="str" default="auto">
  Requested level of detail for the image.
</ParamField>

<ResponseField name="returns" type="'ImageContent'">
  An `ImageContent` referencing the given URL.
</ResponseField>

***

## ContextWindow

Configuration governing how conversation context is bounded and truncated.

### Fields

<ParamField path="max_tokens" type="int | None">
  Maximum number of tokens to retain in the context, or `None` for no token-based limit.
</ParamField>

<ParamField path="max_context_items" type="int | None">
  Maximum number of context items to retain, or `None` for no item-based limit.
</ParamField>

<ParamField path="keep_recent_turns" type="int" default="3">
  Number of most recent turns to always preserve.
</ParamField>

<ParamField path="max_tool_calls_per_turn" type="int" default="10">
  Maximum number of tool calls allowed within a single turn.
</ParamField>

<ParamField path="summary_llm" type="Any">
  Optional language model used to summarize older context when it is trimmed.
</ParamField>

***

## EncodeOptions

Options controlling how an image frame is encoded.

### Fields

<ParamField path="format" type="Literal['JPEG', 'PNG']" default="JPEG">
  Output image format, either `'JPEG'` or `'PNG'`.
</ParamField>

<ParamField path="resize_options" type="Optional[ResizeOptions]" default="…">
  Dimensions to resize the image to before encoding. When `None`, the image is encoded at its original size; defaults to the legacy default resolution.
</ParamField>

<ParamField path="quality" type="int" default="75">
  JPEG quality (0-100); ignored for PNG output.
</ParamField>

***

## ResizeOptions

Target dimensions for resizing an image.

### Fields

<ParamField path="width" type="int" required>
  Target width in pixels.
</ParamField>

<ParamField path="height" type="int" required>
  Target height in pixels.
</ParamField>

***

## encode

```python theme={null}
def encode(frame: 'Any', options: 'Optional[EncodeOptions]' = None) -> 'bytes'
```

Encode an image frame to JPEG or PNG bytes.

Converts the frame to a Pillow image, optionally resizes it, and encodes it
using the requested format. For JPEG output the image is converted to RGB
when needed and saved with optimization enabled.

<ParamField path="frame" type="Any" required>
  Source image. Accepted types include raw `bytes`-like data, a `PIL.Image.Image`, a numpy array, or an object exposing a `to_image` method (such as an `av.VideoFrame`).
</ParamField>

<ParamField path="options" type="Optional[EncodeOptions]">
  Encoding options controlling format, resize dimensions, and JPEG quality. Defaults to `EncodeOptions()` when not provided.
</ParamField>

<ResponseField name="returns" type="bytes">
  The encoded image as bytes.
</ResponseField>

***

## coerce\_image\_to\_jpeg\_bytes

```python theme={null}
def coerce_image_to_jpeg_bytes(frame: 'Any', *, options: 'Optional[EncodeOptions]' = None) -> 'bytes'
```

Return JPEG bytes for an image frame, passing through raw bytes.

If the frame is already bytes-like it is returned unchanged; otherwise the
frame is encoded using the provided options.

<ParamField path="frame" type="Any" required>
  Source image. Accepted types include raw `bytes`-like data, a `PIL.Image.Image`, a numpy array, or an object exposing a `to_image` method (such as an `av.VideoFrame`).
</ParamField>

<ParamField path="options" type="Optional[EncodeOptions]">
  Encoding options used when the frame must be encoded. Defaults to `DEFAULT_REALTIME_ENCODE_OPTIONS` when not provided.
</ParamField>

<ResponseField name="returns" type="bytes">
  The image as bytes, either passed through unchanged or freshly encoded.
</ResponseField>

***

## DEFAULT\_REALTIME\_ENCODE\_OPTIONS

```python theme={null}
DEFAULT_REALTIME_ENCODE_OPTIONS = EncodeOptions(format='JPEG', resize_options=ResizeOptions(width=1024, height=1024), quality=75)
```
