# pydantic\_ai.ui.ag\_ui

AG-UI protocol integration for Pydantic AI agents.

### AGUIEventStream

**Bases:** `UIEventStream[RunAgentInput, BaseEvent, AgentDepsT, OutputDataT]`

UI event stream transformer for the Agent-User Interaction (AG-UI) protocol.

#### Methods

##### handle\_event

`@async`

```python
def handle_event(event: NativeEvent) -> AsyncIterator[BaseEvent]
```

Override to set timestamps on all AG-UI events.

###### Returns

[`AsyncIterator`](https://docs.python.org/3/library/typing.html#typing.AsyncIterator)\[`BaseEvent`\]

### AGUIAdapter

**Bases:** `UIAdapter[RunAgentInput, Message, BaseEvent, AgentDepsT, OutputDataT]`

UI adapter for the Agent-User Interaction (AG-UI) protocol.

When [`preserve_file_data`](/docs/ai/api/ui/base/#pydantic_ai.ui.UIAdapter.preserve_file_data) is `True`, agent-generated files and uploaded files are stored as [activity messages](https://docs.ag-ui.com/concepts/activities) during `dump_messages` and restored during `load_messages`, enabling full round-trip fidelity. When `False` (the default), they are dropped. If your AG-UI frontend uses activities, be aware that `pydantic_ai_*` activity types are reserved for internal round-trip use and should be ignored by frontend activity handlers.

#### Attributes

##### ag\_ui\_version

AG-UI protocol version controlling behavior thresholds.

Accepts any version string (e.g. `'0.1.13'`). Defaults to the version detected from the installed `ag-ui-protocol` package.

Known thresholds:

-   `< 0.1.13`: emits `THINKING_*` events during streaming, drops `ThinkingPart` from `dump_messages` output.
-   `>= 0.1.13`: emits `REASONING_*` events with encrypted metadata during streaming, and includes `ThinkingPart` as `ReasoningMessage` in `dump_messages` output for full round-trip fidelity of thinking signatures and provider metadata.
-   `>= 0.1.15`: emits typed multimodal input content (`ImageInputContent`, `AudioInputContent`, `VideoInputContent`, `DocumentInputContent`) instead of generic `BinaryInputContent`.

`load_messages` always accepts `ReasoningMessage` and multimodal content types regardless of this setting.

**Type:** [`str`](https://docs.python.org/3/library/stdtypes.html#str) **Default:** `DEFAULT_AG_UI_VERSION`

##### messages

Pydantic AI messages from the AG-UI run input.

**Type:** [`list`](https://docs.python.org/3/glossary.html#term-list)\[[`ModelMessage`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.ModelMessage)\]

##### toolset

Toolset representing frontend tools from the AG-UI run input.

**Type:** [`AbstractToolset`](/docs/ai/api/pydantic-ai/toolsets/#pydantic_ai.toolsets.AbstractToolset)\[`AgentDepsT`\] | [`None`](https://docs.python.org/3/library/constants.html#None)

##### state

Frontend state from the AG-UI run input.

**Type:** [`dict`](https://docs.python.org/3/reference/expressions.html#dict)\[[`str`](https://docs.python.org/3/library/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)\] | [`None`](https://docs.python.org/3/library/constants.html#None)

##### conversation\_id

Conversation ID from the AG-UI `RunAgentInput.threadId`.

**Type:** [`str`](https://docs.python.org/3/library/stdtypes.html#str) | [`None`](https://docs.python.org/3/library/constants.html#None)

#### Methods

##### build\_run\_input

`@classmethod`

```python
def build_run_input(cls, body: bytes) -> RunAgentInput
```

Build an AG-UI run input object from the request body.

###### Returns

`RunAgentInput`

##### build\_event\_stream

```python
def build_event_stream(

) -> UIEventStream[RunAgentInput, BaseEvent, AgentDepsT, OutputDataT]
```

Build an AG-UI event stream transformer.

###### Returns

`UIEventStream`\[`RunAgentInput`, `BaseEvent`, `AgentDepsT`, `OutputDataT`\]

##### from\_request

`@async`

`@classmethod`

```python
def from_request(
    cls,
    request: Request,
    agent: AbstractAgent[AgentDepsT, OutputDataT],
    ag_ui_version: str = DEFAULT_AG_UI_VERSION,
    preserve_file_data: bool = False,
    manage_system_prompt: Literal['server', 'client'] = 'server',
    allowed_file_url_schemes: frozenset[str] = frozenset({'http', 'https'}),
    allowed_file_url_force_download: frozenset[ForceDownloadMode] = frozenset(),
    kwargs: Any = {},
) -> AGUIAdapter[AgentDepsT, OutputDataT]
```

Extends [`from_request`](/docs/ai/api/ui/base/#pydantic_ai.ui.UIAdapter.from_request) with AG-UI-specific parameters.

###### Returns

`AGUIAdapter`\[`AgentDepsT`, `OutputDataT`\]

##### load\_messages

`@classmethod`

```python
def load_messages(
    cls,
    messages: Sequence[Message],
    preserve_file_data: bool = False,
) -> list[ModelMessage]
```

Transform AG-UI messages into Pydantic AI messages.

###### Returns

[`list`](https://docs.python.org/3/glossary.html#term-list)\[[`ModelMessage`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.ModelMessage)\]

##### dump\_messages

`@classmethod`

```python
def dump_messages(
    cls,
    messages: Sequence[ModelMessage],
    ag_ui_version: str = DEFAULT_AG_UI_VERSION,
    preserve_file_data: bool = False,
) -> list[Message]
```

Transform Pydantic AI messages into AG-UI messages.

Note: The round-trip `dump_messages` -> `load_messages` is not fully lossless:

-   `TextPart.id`, `.provider_name`, `.provider_details` are lost.
-   `ToolCallPart.id`, `.provider_name`, `.provider_details` are lost.
-   `NativeToolCallPart.id`, `.provider_details` are lost (only `.provider_name` survives via the prefixed tool call ID).
-   `NativeToolReturnPart.provider_details` is lost.
-   `RetryPromptPart` becomes `ToolReturnPart` (or `UserPromptPart`) on reload.
-   `CachePoint` and `UploadedFile` content items are dropped (unless `preserve_file_data=True`).
-   `ThinkingPart` is dropped when `ag_ui_version='0.1.10'`.
-   `FilePart` is silently dropped unless `preserve_file_data=True`.
-   `UploadedFile` in a multi-item `UserPromptPart` is split into a separate activity message when `preserve_file_data=True`, which reloads as a separate `UserPromptPart`.
-   Part ordering within a `ModelResponse` may change when text follows tool calls.

###### Returns

[`list`](https://docs.python.org/3/glossary.html#term-list)\[`Message`\] -- A list of AG-UI Message objects.

###### Parameters

**`messages`** : [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)\[[`ModelMessage`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.ModelMessage)\]

A sequence of ModelMessage objects to convert.

**`ag_ui_version`** : [`str`](https://docs.python.org/3/library/stdtypes.html#str) _Default:_ `DEFAULT_AG_UI_VERSION`

AG-UI protocol version controlling `ThinkingPart` emission.

**`preserve_file_data`** : [`bool`](https://docs.python.org/3/library/functions.html#bool) _Default:_ `False`

Whether to include `FilePart` and `UploadedFile` as `ActivityMessage`.

### DEFAULT\_AG\_UI\_VERSION

The default AG-UI version, auto-detected from the installed `ag-ui-protocol` package.

**Type:** [`str`](https://docs.python.org/3/library/stdtypes.html#str) **Default:** `detect_ag_ui_version()`

AG-UI protocol integration for Pydantic AI agents.

### AGUIApp

**Bases:** `Generic[AgentDepsT, OutputDataT]`, `Starlette`

ASGI application for running Pydantic AI agents with AG-UI protocol support.

#### Methods

##### \_\_init\_\_

`@deprecated`

```python
def __init__(
    agent: AbstractAgent[AgentDepsT, OutputDataT],
    ag_ui_version: str = DEFAULT_AG_UI_VERSION,
    preserve_file_data: bool = False,
    output_type: OutputSpec[Any] | None = None,
    message_history: Sequence[ModelMessage] | None = None,
    deferred_tool_results: DeferredToolResults | None = None,
    conversation_id: str | None = None,
    model: Model | KnownModelName | str | None = None,
    deps: AgentDepsT = None,
    model_settings: ModelSettings | None = None,
    usage_limits: UsageLimits | None = None,
    usage: RunUsage | None = None,
    infer_name: bool = True,
    toolsets: Sequence[AbstractToolset[AgentDepsT]] | None = None,
    capabilities: Sequence[AbstractCapability[AgentDepsT]] | None = None,
    on_complete: OnCompleteFunc[Any] | None = None,
    debug: bool = False,
    routes: Sequence[BaseRoute] | None = None,
    middleware: Sequence[Middleware] | None = None,
    exception_handlers: Mapping[Any, ExceptionHandler] | None = None,
    on_startup: Sequence[Callable[[], Any]] | None = None,
    on_shutdown: Sequence[Callable[[], Any]] | None = None,
    lifespan: Lifespan[Self] | None = None,
    _deprecated_kwargs: Any = {},
) -> None
```

An ASGI application that handles every request by running the agent and streaming the response.

Note that the `deps` will be the same for each request, with the exception of the frontend state that's injected into the `state` field of a `deps` object that implements the [`StateHandler`](/docs/ai/api/ui/base/#pydantic_ai.ui.StateHandler) protocol. To provide different `deps` for each request (e.g. based on the authenticated user), use `AGUIAdapter.run_stream()` or `AGUIAdapter.dispatch_request()` instead.

###### Returns

[`None`](https://docs.python.org/3/library/constants.html#None)

###### Parameters

**`agent`** : `AbstractAgent`\[`AgentDepsT`, `OutputDataT`\]

The agent to run.

**`ag_ui_version`** : [`str`](https://docs.python.org/3/library/stdtypes.html#str) _Default:_ `DEFAULT_AG_UI_VERSION`

AG-UI protocol version controlling thinking/reasoning event format.

**`preserve_file_data`** : [`bool`](https://docs.python.org/3/library/functions.html#bool) _Default:_ `False`

Whether to preserve agent-generated files and uploaded files in AG-UI message conversion. See `AGUIAdapter.preserve_file_data`.

**`output_type`** : `OutputSpec`\[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

Custom output type to use for this run, `output_type` may only be used if the agent has no output validators since output validators would expect an argument that matches the agent's output type.

**`message_history`** : [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)\[[`ModelMessage`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.ModelMessage)\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

History of the conversation so far.

**`deferred_tool_results`** : [`DeferredToolResults`](/docs/ai/api/pydantic-ai/tools/#pydantic_ai.tools.DeferredToolResults) | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

Optional results for deferred tool calls in the message history.

**`conversation_id`** : [`str`](https://docs.python.org/3/library/stdtypes.html#str) | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

ID of the conversation this run belongs to. Pass `'new'` to start a fresh conversation, ignoring any `conversation_id` already on `message_history`. If omitted, falls back to the most recent `conversation_id` on `message_history` or a freshly generated UUID7.

**`model`** : `Model` | `KnownModelName` | [`str`](https://docs.python.org/3/library/stdtypes.html#str) | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

Optional model to use for this run, required if `model` was not set when creating the agent.

**`deps`** : `AgentDepsT` _Default:_ `None`

Optional dependencies to use for this run.

**`model_settings`** : [`ModelSettings`](/docs/ai/api/pydantic-ai/settings/#pydantic_ai.settings.ModelSettings) | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

Optional settings to use for this model's request.

**`usage_limits`** : [`UsageLimits`](/docs/ai/api/pydantic-ai/usage/#pydantic_ai.usage.UsageLimits) | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

Optional limits on model request count or token usage.

**`usage`** : [`RunUsage`](/docs/ai/api/pydantic-ai/usage/#pydantic_ai.usage.RunUsage) | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

Optional usage to start with, useful for resuming a conversation or agents used in tools.

**`infer_name`** : [`bool`](https://docs.python.org/3/library/functions.html#bool) _Default:_ `True`

Whether to try to infer the agent name from the call frame if it's not set.

**`toolsets`** : [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)\[[`AbstractToolset`](/docs/ai/api/pydantic-ai/toolsets/#pydantic_ai.toolsets.AbstractToolset)\[`AgentDepsT`\]\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

Optional additional toolsets for this run.

**`capabilities`** : [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)\[`AbstractCapability`\[`AgentDepsT`\]\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

Optional additional [capabilities](https://ai.pydantic.dev/capabilities/) for every run handled by this app, merged with the agent's configured capabilities. Use `capabilities=[NativeTool(...)]` to add provider-side native tools per app.

**`on_complete`** : `OnCompleteFunc`\[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

Optional callback function called when the agent run completes successfully. The callback receives the completed [`AgentRunResult`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRunResult) and can access `all_messages()` and other result data.

**`debug`** : [`bool`](https://docs.python.org/3/library/functions.html#bool) _Default:_ `False`

Boolean indicating if debug tracebacks should be returned on errors.

**`routes`** : [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)\[`BaseRoute`\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

A list of routes to serve incoming HTTP and WebSocket requests.

**`middleware`** : [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)\[`Middleware`\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

A list of middleware to run for every request. A starlette application will always automatically include two middleware classes. `ServerErrorMiddleware` is added as the very outermost middleware, to handle any uncaught errors occurring anywhere in the entire stack. `ExceptionMiddleware` is added as the very innermost middleware, to deal with handled exception cases occurring in the routing or endpoints.

**`exception_handlers`** : [`Mapping`](https://docs.python.org/3/library/typing.html#typing.Mapping)\[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any), `ExceptionHandler`\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

A mapping of either integer status codes, or exception class types onto callables which handle the exceptions. Exception handler callables should be of the form `handler(request, exc) -> response` and may be either standard functions, or async functions.

**`on_startup`** : [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)\[[`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)\[\[\], [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)\]\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

A list of callables to run on application startup. Startup handler callables do not take any arguments, and may be either standard functions, or async functions.

**`on_shutdown`** : [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)\[[`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)\[\[\], [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)\]\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

A list of callables to run on application shutdown. Shutdown handler callables do not take any arguments, and may be either standard functions, or async functions.

**`lifespan`** : `Lifespan`\[[`Self`](https://docs.python.org/3/library/typing.html#typing.Self)\] | [`None`](https://docs.python.org/3/library/constants.html#None) _Default:_ `None`

A lifespan context function, which can be used to perform startup and shutdown tasks. This is a newer style that replaces the `on_startup` and `on_shutdown` handlers. Use one or the other, not both.