# pydantic\_ai.run

### AgentRun

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

A stateful, async-iterable run of an [`Agent`](/docs/ai/api/pydantic-ai/agent/#pydantic_ai.agent.Agent).

You generally obtain an `AgentRun` instance by calling `async with my_agent.iter(...) as agent_run:`.

Once you have an instance, you can use it to iterate through the run's nodes as they execute. When an `End` is reached, the run finishes and [`result`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRun.result) becomes available.

Example:

```python
from pydantic_ai import Agent

agent = Agent('openai:gpt-5.2')

async def main():
    nodes = []
    # Iterate through the run, recording each node along the way:
    async with agent.iter('What is the capital of France?') as agent_run:
        async for node in agent_run:
            nodes.append(node)
    print(nodes)
    '''
    [
        UserPromptNode(
            user_prompt='What is the capital of France?',
            instructions_functions=[],
            system_prompts=(),
            system_prompt_functions=[],
            system_prompt_dynamic_functions={},
        ),
        ModelRequestNode(
            request=ModelRequest(
                parts=[
                    UserPromptPart(
                        content='What is the capital of France?',
                        timestamp=datetime.datetime(...),
                    )
                ],
                timestamp=datetime.datetime(...),
                run_id='...',
                conversation_id='...',
            )
        ),
        CallToolsNode(
            model_response=ModelResponse(
                parts=[TextPart(content='The capital of France is Paris.')],
                usage=RequestUsage(input_tokens=56, output_tokens=7),
                model_name='gpt-5.2',
                timestamp=datetime.datetime(...),
                run_id='...',
                conversation_id='...',
            )
        ),
        End(data=FinalResult(output='The capital of France is Paris.')),
    ]
    '''
    print(agent_run.result.output)
    #> The capital of France is Paris.
```

You can also manually drive the iteration using the [`next`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRun.next) method for more granular control.

#### Attributes

##### ctx

The current context of the agent run.

**Type:** `GraphRunContext`\[`_agent_graph.GraphAgentState`, `_agent_graph.GraphAgentDeps`\[`AgentDepsT`, [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)\]\]

##### next\_node

The next node that will be run in the agent graph.

This is the next node that will be used during async iteration, or if a node is not passed to `self.next(...)`.

**Type:** `_agent_graph.AgentNode`\[`AgentDepsT`, `OutputDataT`\] | `End`\[`FinalResult`\[`OutputDataT`\]\]

##### result

The final result of the run if it has ended, otherwise `None`.

Once the run returns an `End` node, `result` is populated with an [`AgentRunResult`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRunResult).

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

##### metadata

Metadata associated with this agent run, if configured.

**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)

##### run\_id

The unique identifier for the agent run.

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

##### conversation\_id

The unique identifier for the conversation this run belongs to.

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

##### pending\_messages

Internal: live view of the queue mutated by `enqueue` and drained by `PendingMessageDrainCapability`.

Exposed for inspection / debugging; use [`enqueue`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRun.enqueue) to add messages.

**Type:** [`list`](https://docs.python.org/3/glossary.html#term-list)\[`PendingMessage`\]

#### Methods

##### all\_messages

```python
def all_messages() -> list[_messages.ModelMessage]
```

Return all messages for the run so far.

Messages from older runs are included.

###### Returns

[`list`](https://docs.python.org/3/glossary.html#term-list)\[`_messages.ModelMessage`\]

##### all\_messages\_json

```python
def all_messages_json(output_tool_return_content: str | None = None) -> bytes
```

Return all messages from [`all_messages`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRun.all_messages) as JSON bytes.

###### Returns

[`bytes`](https://docs.python.org/3/library/stdtypes.html#bytes) -- JSON bytes representing the messages.

##### new\_messages

```python
def new_messages() -> list[_messages.ModelMessage]
```

Return the messages produced during this run so far.

Messages provided via `message_history` and messages from older runs are excluded.

###### Returns

[`list`](https://docs.python.org/3/glossary.html#term-list)\[`_messages.ModelMessage`\]

##### new\_messages\_json

```python
def new_messages_json() -> bytes
```

Return new messages from [`new_messages`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRun.new_messages) as JSON bytes.

###### Returns

[`bytes`](https://docs.python.org/3/library/stdtypes.html#bytes) -- JSON bytes representing the new messages.

##### \_\_aiter\_\_

```python
def __aiter__(

) -> AsyncIterator[_agent_graph.AgentNode[AgentDepsT, OutputDataT] | End[FinalResult[OutputDataT]]]
```

Provide async-iteration over the nodes in the agent run.

###### Returns

[`AsyncIterator`](https://docs.python.org/3/library/typing.html#typing.AsyncIterator)\[`_agent_graph.AgentNode`\[`AgentDepsT`, `OutputDataT`\] | `End`\[`FinalResult`\[`OutputDataT`\]\]\]

##### \_\_anext\_\_

`@async`

```python
def __anext__(

) -> _agent_graph.AgentNode[AgentDepsT, OutputDataT] | End[FinalResult[OutputDataT]]
```

Advance to the next node automatically based on the last returned node.

Note: this uses the graph run's internal iteration which does NOT call node hooks (`before_node_run`, `wrap_node_run`, `after_node_run`, `on_node_run_error`). Use `next()` for capability-hooked iteration, or use `agent.run()` which drives via `next()` automatically.

###### Returns

`_agent_graph.AgentNode`\[`AgentDepsT`, `OutputDataT`\] | `End`\[`FinalResult`\[`OutputDataT`\]\]

##### next

`@async`

```python
def next(
    node: _agent_graph.AgentNode[AgentDepsT, OutputDataT],
) -> _agent_graph.AgentNode[AgentDepsT, OutputDataT] | End[FinalResult[OutputDataT]]
```

Manually drive the agent run by passing in the node you want to run next.

This lets you inspect or mutate the node before continuing execution, or skip certain nodes under dynamic conditions. The agent run should be stopped when you return an `End` node.

Example:

```python
from pydantic_ai import Agent
from pydantic_graph import End

agent = Agent('openai:gpt-5.2')

async def main():
    async with agent.iter('What is the capital of France?') as agent_run:
        next_node = agent_run.next_node  # start with the first node
        nodes = [next_node]
        while not isinstance(next_node, End):
            next_node = await agent_run.next(next_node)
            nodes.append(next_node)
        # Once `next_node` is an End, we've finished:
        print(nodes)
        '''
        [
            UserPromptNode(
                user_prompt='What is the capital of France?',
                instructions_functions=[],
                system_prompts=(),
                system_prompt_functions=[],
                system_prompt_dynamic_functions={},
            ),
            ModelRequestNode(
                request=ModelRequest(
                    parts=[
                        UserPromptPart(
                            content='What is the capital of France?',
                            timestamp=datetime.datetime(...),
                        )
                    ],
                    timestamp=datetime.datetime(...),
                    run_id='...',
                    conversation_id='...',
                )
            ),
            CallToolsNode(
                model_response=ModelResponse(
                    parts=[TextPart(content='The capital of France is Paris.')],
                    usage=RequestUsage(input_tokens=56, output_tokens=7),
                    model_name='gpt-5.2',
                    timestamp=datetime.datetime(...),
                    run_id='...',
                    conversation_id='...',
                )
            ),
            End(data=FinalResult(output='The capital of France is Paris.')),
        ]
        '''
        print('Final result:', agent_run.result.output)
        #> Final result: The capital of France is Paris.
```

###### Returns

`_agent_graph.AgentNode`\[`AgentDepsT`, `OutputDataT`\] | `End`\[`FinalResult`\[`OutputDataT`\]\] -- The next node returned by the graph logic, or an `End` node if `_agent_graph.AgentNode`\[`AgentDepsT`, `OutputDataT`\] | `End`\[`FinalResult`\[`OutputDataT`\]\] -- the run has completed.

###### Parameters

**`node`** : `_agent_graph.AgentNode`\[`AgentDepsT`, `OutputDataT`\]

The node to run next in the graph.

##### usage

```python
def usage() -> _usage.RunUsage
```

Get usage statistics for the run so far, including token usage, model requests, and so on.

###### Returns

`_usage.RunUsage`

##### enqueue

```python
def enqueue(
    content: EnqueueContent = (),
    priority: PendingMessagePriority = 'asap',
) -> None
```

Enqueue content to be injected into the conversation.

Designed to be called from the same event loop driving `agent.iter()`. If you're forwarding events from a different thread (e.g. a webhook handler running on its own loop or thread), marshal the call back onto the agent's loop first (e.g. `loop.call_soon_threadsafe(agent_run.enqueue, msg)`). The drain's `queue[:] = remaining` pattern in `_drain_by_priority` isn't atomic against concurrent appends from a different thread.

###### Returns

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

###### Parameters

**`*content`** : `EnqueueContent` _Default:_ `()`

One or more `EnqueueContent` items. Adjacent `UserContent` (a `str` or multi-modal content like an [`ImageUrl`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.ImageUrl)) is gathered into one [`UserPromptPart`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.UserPromptPart), and each [`ModelRequestPart`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.ModelRequestPart) (e.g. a [`SystemPromptPart`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.SystemPromptPart)) is coalesced with adjacent part-style items into one [`ModelRequest`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.ModelRequest); a complete [`ModelRequest`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.ModelRequest) or [`ModelResponse`](/docs/ai/api/pydantic-ai/messages/#pydantic_ai.messages.ModelResponse) is kept as its own message. The assembled sequence must end in a request. Calling with no positional args is a no-op.

**`priority`** : `PendingMessagePriority` _Default:_ `'asap'`

When to deliver: `'asap'` (default) -- at the earliest opportunity (next model request, or a redirect if the agent would otherwise end). `'when_idle'` -- only when the agent would otherwise end, after `'asap'` messages.

### AgentRunResult

**Bases:** `Generic[OutputDataT]`

The final result of an agent run.

#### Attributes

##### output

The output data from the agent run.

**Type:** `OutputDataT`

##### response

Return the last response from the message history.

**Type:** `_messages.ModelResponse`

##### metadata

Metadata associated with this agent run, if configured.

**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)

##### run\_id

The unique identifier for the agent run.

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

##### conversation\_id

The unique identifier for the conversation this run belongs to.

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

#### Methods

##### all\_messages

```python
def all_messages(
    output_tool_return_content: str | None = None,
) -> list[_messages.ModelMessage]
```

Return the history of \_messages.

###### Returns

[`list`](https://docs.python.org/3/glossary.html#term-list)\[`_messages.ModelMessage`\] -- List of messages.

###### Parameters

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

The return content of the tool call to set in the last message. This provides a convenient way to modify the content of the output tool call if you want to continue the conversation and want to set the response to the output tool call. If `None`, the last message will not be modified.

##### all\_messages\_json

```python
def all_messages_json(output_tool_return_content: str | None = None) -> bytes
```

Return all messages from [`all_messages`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRunResult.all_messages) as JSON bytes.

###### Returns

[`bytes`](https://docs.python.org/3/library/stdtypes.html#bytes) -- JSON bytes representing the messages.

###### Parameters

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

The return content of the tool call to set in the last message. This provides a convenient way to modify the content of the output tool call if you want to continue the conversation and want to set the response to the output tool call. If `None`, the last message will not be modified.

##### new\_messages

```python
def new_messages(
    output_tool_return_content: str | None = None,
) -> list[_messages.ModelMessage]
```

Return the messages produced during this run.

Messages provided via `message_history` and messages from older runs are excluded.

###### Returns

[`list`](https://docs.python.org/3/glossary.html#term-list)\[`_messages.ModelMessage`\] -- List of new messages.

###### Parameters

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

The return content of the tool call to set in the last message. This provides a convenient way to modify the content of the output tool call if you want to continue the conversation and want to set the response to the output tool call. If `None`, the last message will not be modified.

##### new\_messages\_json

```python
def new_messages_json(output_tool_return_content: str | None = None) -> bytes
```

Return new messages from [`new_messages`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRunResult.new_messages) as JSON bytes.

###### Returns

[`bytes`](https://docs.python.org/3/library/stdtypes.html#bytes) -- JSON bytes representing the new messages.

###### Parameters

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

The return content of the tool call to set in the last message. This provides a convenient way to modify the content of the output tool call if you want to continue the conversation and want to set the response to the output tool call. If `None`, the last message will not be modified.

##### usage

```python
def usage() -> _usage.RunUsage
```

Return the usage of the whole run.

###### Returns

`_usage.RunUsage`

##### timestamp

```python
def timestamp() -> datetime
```

Return the timestamp of last response.

###### Returns

[`datetime`](https://docs.python.org/3/library/datetime.html#module-datetime)

### AgentRunResultEvent

**Bases:** `Generic[OutputDataT]`

An event indicating the agent run ended and containing the final result of the agent run.

#### Attributes

##### result

The result of the run.

**Type:** [`AgentRunResult`](/docs/ai/api/pydantic-ai/run/#pydantic_ai.run.AgentRunResult)\[`OutputDataT`\]

##### event\_kind

Event type identifier, used as a discriminator.

**Type:** [`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)\['agent\_run\_result'\] **Default:** `'agent_run_result'`