You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -171,7 +171,7 @@ validate state contained in [`RunAgentInput.state`](https://docs.ag-ui.com/sdk/j
171
171
If the `state` field's type is a Pydantic `BaseModel` subclass, the raw state dictionary on the request is automatically validated. If not, you can validate the raw value yourself in your dependencies dataclass's `__post_init__` method.
172
172
173
173
174
-
```python {title="ag_ui_state.py" py="3.10"}
174
+
```python {title="ag_ui_state.py"}
175
175
from pydantic import BaseModel
176
176
177
177
from pydantic_ai import Agent
@@ -211,7 +211,7 @@ which returns a (subclass of)
211
211
[`BaseEvent`](https://docs.ag-ui.com/sdk/python/core/events#baseevent), which allows
Copy file name to clipboardExpand all lines: docs/graph.md
+19-19Lines changed: 19 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -122,7 +122,7 @@ class MyNode(BaseNode[MyState, None, int]): # (1)!
122
122
123
123
Here's an example of a simple graph:
124
124
125
-
```py {title="graph_example.py" py="3.10"}
125
+
```py {title="graph_example.py"}
126
126
from__future__import annotations
127
127
128
128
from dataclasses import dataclass
@@ -163,11 +163,11 @@ print(result.output)
163
163
3. The graph is created with a sequence of nodes.
164
164
4. The graph is run synchronously with [`run_sync`][pydantic_graph.graph.Graph.run_sync]. The initial node is `DivisibleBy5(4)`. Because the graph doesn't use external state or deps, we don't pass `state` or `deps`.
165
165
166
-
_(This example is complete, it can be run "as is" with Python 3.10+)_
166
+
_(This example is complete, it can be run "as is")_
167
167
168
168
A [mermaid diagram](#mermaid-diagrams) for this graph can be generated with the following code:
from graph_example import DivisibleBy5, fives_graph
172
172
173
173
fives_graph.mermaid_code(start_node=DivisibleBy5)
@@ -201,7 +201,7 @@ The "state" concept in `pydantic-graph` provides an optional way to access and m
201
201
202
202
Here's an example of a graph which represents a vending machine where the user may insert coins and select a product to purchase.
203
203
204
-
```python {title="vending_machine.py" py="3.10"}
204
+
```python {title="vending_machine.py"}
205
205
from__future__import annotations
206
206
207
207
from dataclasses import dataclass
@@ -304,11 +304,11 @@ async def main():
304
304
17. The return type of `CoinsInserted`'s [`run`][pydantic_graph.nodes.BaseNode.run] method is a union, meaning multiple outgoing edges are possible.
305
305
18. Unlike other nodes, `Purchase` can end the run, so the [`RunEndT`][pydantic_graph.nodes.RunEndT] generic parameter must be set. In this case it's `None` since the graph run return type is `None`.
306
306
307
-
_(This example is complete, it can be run "as is" with Python 3.10+ — you'll need to add `asyncio.run(main())` to run `main`)_
307
+
_(This example is complete, it can be run "as is" — you'll need to add `asyncio.run(main())` to run `main`)_
308
308
309
309
A [mermaid diagram](#mermaid-diagrams) for this graph can be generated with the following code:
from pydantic_graph import End, FullStatePersistence
529
529
from count_down import CountDown, CountDownState, count_down_graph
530
530
@@ -593,7 +593,7 @@ We can run the `count_down_graph` from [above](#iterating-over-a-graph), using [
593
593
594
594
As you can see in this code, `run_node` requires no external application state (apart from state persistence) to be run, meaning graphs can easily be executed by distributed execution and queueing systems.
5.[`graph.run()`][pydantic_graph.graph.Graph.run] will return either a [node][pydantic_graph.nodes.BaseNode] or an [`End`][pydantic_graph.nodes.End] object.
638
638
6. Check if the node is an [`End`][pydantic_graph.nodes.End] object, if it is, the graph run is complete.
639
639
640
-
_(This example is complete, it can be run "as is" with Python 3.10+ — you'll need to add `asyncio.run(main())` to run `main`)_
640
+
_(This example is complete, it can be run "as is" — you'll need to add `asyncio.run(main())` to run `main`)_
641
641
642
642
### Example: Human in the loop.
643
643
@@ -648,7 +648,7 @@ In this example, an AI asks the user a question, the user provides an answer, th
648
648
Instead of running the entire graph in a single process invocation, we run the graph by running the process repeatedly, optionally providing an answer to the question as a command line argument.
649
649
650
650
??? example "`ai_q_and_a_graph.py` — `question_graph` definition"
8. To demonstrate the state persistence, we call [`load_all`][pydantic_graph.persistence.BaseStatePersistence.load_all] to get all the snapshots from the persistence instance. This will return a list of [`Snapshot`][pydantic_graph.persistence.Snapshot] objects.
800
800
9. If the node is an `Answer` object, we print the question and break out of the loop to end the process and wait for user input.
801
801
802
-
_(This example is complete, it can be run "as is" with Python 3.10+ — you'll need to add `asyncio.run(main())` to run `main`)_
802
+
_(This example is complete, it can be run "as is" — you'll need to add `asyncio.run(main())` to run `main`)_
803
803
804
804
For a complete example of this graph, see the [question graph example](examples/question-graph.md).
805
805
@@ -809,7 +809,7 @@ As with Pydantic AI, `pydantic-graph` supports dependency injection via a generi
809
809
810
810
As an example of dependency injection, let's modify the `DivisibleBy5` example [above](#graph) to use a [`ProcessPoolExecutor`][concurrent.futures.ProcessPoolExecutor] to run the compute load in a separate process (this is a contrived example, `ProcessPoolExecutor` wouldn't actually improve performance in this example):
from pydantic_ai.mcp import MCPServerStreamableHTTP
59
56
@@ -71,7 +68,7 @@ async def main():
71
68
2. Create an agent with the MCP server attached.
72
69
3. Create a client session to connect to the server.
73
70
74
-
_(This example is complete, it can be run "as is" with Python 3.10+ — you'll need to add `asyncio.run(main())` to run `main`)_
71
+
_(This example is complete, it can be run "as is" — you'll need to add `asyncio.run(main())` to run `main`)_
75
72
76
73
**What's happening here?**
77
74
@@ -113,7 +110,7 @@ deno run \
113
110
jsr:@pydantic/mcp-run-python sse
114
111
```
115
112
116
-
```python {title="mcp_sse_client.py" py="3.10"}
113
+
```python {title="mcp_sse_client.py"}
117
114
from pydantic_ai import Agent
118
115
from pydantic_ai.mcp import MCPServerSSE
119
116
@@ -132,13 +129,13 @@ async def main():
132
129
2. Create an agent with the MCP server attached.
133
130
3. Create a client session to connect to the server.
134
131
135
-
_(This example is complete, it can be run "as is" with Python 3.10+ — you'll need to add `asyncio.run(main())` to run `main`)_
132
+
_(This example is complete, it can be run "as is" — you'll need to add `asyncio.run(main())` to run `main`)_
136
133
137
134
### MCP "stdio" Server
138
135
139
136
The other transport offered by MCP is the [stdio transport](https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/transports/#stdio) where the server is run as a subprocess and communicates with the client over `stdin` and `stdout`. In this case, you'd use the [`MCPServerStdio`][pydantic_ai.mcp.MCPServerStdio] class.
140
137
141
-
```python {title="mcp_stdio_client.py" py="3.10"}
138
+
```python {title="mcp_stdio_client.py"}
142
139
from pydantic_ai import Agent
143
140
from pydantic_ai.mcp import MCPServerStdio
144
141
@@ -174,7 +171,7 @@ the customisation of tool call requests and their responses.
174
171
A common use case for this is to inject metadata to the requests which the server
@@ -418,7 +415,7 @@ This allows for a more interactive and user-friendly experience, especially for
418
415
419
416
To enable elicitation, provide an [`elicitation_callback`][pydantic_ai.mcp.MCPServer.elicitation_callback] function when creating your MCP server instance:
This server demonstrates elicitation by requesting structured booking details from the client when the `book_table` tool is called. Here's how to create a client that handles these elicitation requests:
Copy file name to clipboardExpand all lines: docs/mcp/run-python.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -52,7 +52,7 @@ Usage of `jsr:@pydantic/mcp-run-python` with Pydantic AI is described in the [cl
52
52
53
53
As well as using this server with Pydantic AI, it can be connected to other MCP clients. For clarity, in this example we connect directly using the [Python MCP client](https://github.com/modelcontextprotocol/python-sdk).
54
54
55
-
```python {title="mcp_run_python.py" py="3.10"}
55
+
```python {title="mcp_run_python.py"}
56
56
from mcp import ClientSession, StdioServerParameters
57
57
from mcp.client.stdio import stdio_client
58
58
@@ -127,7 +127,7 @@ As introduced in PEP 723, explained [here](https://packaging.python.org/en/lates
127
127
128
128
This allows use of dependencies that aren't imported in the code, and is more explicit.
@@ -70,7 +70,7 @@ When Pydantic AI agents are used within MCP servers, they can use sampling via [
70
70
71
71
We can extend the above example to use sampling so instead of connecting directly to the LLM, the agent calls back through the MCP client to make LLM calls.
72
72
73
-
```py {title="mcp_server_sampling.py" py="3.10"}
73
+
```py {title="mcp_server_sampling.py"}
74
74
from mcp.server.fastmcp import Context, FastMCP
75
75
76
76
from pydantic_ai import Agent
@@ -95,7 +95,7 @@ The [above](#simple-client) client does not support sampling, so if you tried to
95
95
96
96
The simplest way to support sampling in an MCP client is to [use](./client.md#mcp-sampling) a Pydantic AI agent as the client, but if you wanted to support sampling with the vanilla MCP SDK, you could do so like this:
0 commit comments