Skip to content

Commit 9f11b3b

Browse files
committed
Merge main
2 parents 34ec681 + e603f68 commit 9f11b3b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1877
-454
lines changed

.github/workflows/after-ci.yml

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ jobs:
1717
- uses: astral-sh/setup-uv@v5
1818
with:
1919
enable-cache: true
20-
python-version: '3.12'
20+
python-version: "3.12"
2121

2222
- uses: dawidd6/action-download-artifact@v6
2323
with:
2424
workflow: ci.yml
25-
name: '(diff-)?coverage-html.*'
25+
name: "(diff-)?coverage-html.*"
2626
name_is_regexp: true
2727
commit: ${{ github.event.workflow_run.head_sha }}
2828
allow_forks: true
@@ -39,16 +39,6 @@ jobs:
3939
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
4040
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }}
4141

42-
- run: uvx smokeshow upload diff-coverage-html
43-
if: hashFiles('diff-coverage-html/*.html') != ''
44-
env:
45-
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Diff coverage {coverage-percentage}
46-
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 95
47-
SMOKESHOW_GITHUB_CONTEXT: diff-coverage
48-
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49-
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
50-
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }}
51-
5242
deploy-docs-preview:
5343
runs-on: ubuntu-latest
5444
if: github.event.workflow_run.event == 'pull_request'
@@ -65,7 +55,7 @@ jobs:
6555
- uses: astral-sh/setup-uv@v5
6656
with:
6757
enable-cache: true
68-
python-version: '3.12'
58+
python-version: "3.12"
6959

7060
- uses: dawidd6/action-download-artifact@v6
7161
with:

.github/workflows/ci.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,13 @@ jobs:
266266
env:
267267
COVERAGE_FILE: .coverage/.coverage
268268

269+
- run: uv run coverage html --show-contexts --title "Pydantic AI coverage for ${{ github.sha }}"
270+
- uses: actions/upload-artifact@v4
271+
with:
272+
name: coverage-html
273+
path: htmlcov
274+
include-hidden-files: true
275+
269276
test-mcp-run-python:
270277
runs-on: ubuntu-latest
271278
timeout-minutes: 5
@@ -292,7 +299,16 @@ jobs:
292299
# https://github.com/marketplace/actions/alls-green#why used for branch protection checks
293300
check:
294301
if: always()
295-
needs: [lint, mypy, docs, test-live, test, test-lowest-versions, test-examples, coverage, test-mcp-run-python]
302+
needs:
303+
- lint
304+
- mypy
305+
- docs
306+
- test-live
307+
- test
308+
- test-lowest-versions
309+
- test-examples
310+
- coverage
311+
- test-mcp-run-python
296312
runs-on: ubuntu-latest
297313

298314
steps:

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CLAUDE.md

docs/builtin-tools.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ Builtin tools are native tools provided by LLM providers that can be used to enh
44

55
## Overview
66

7-
PydanticAI supports two types of builtin tools:
7+
PydanticAI supports the following builtin tools:
88

99
- **[`WebSearchTool`][pydantic_ai.builtin_tools.WebSearchTool]**: Allows agents to search the web
1010
- **[`CodeExecutionTool`][pydantic_ai.builtin_tools.CodeExecutionTool]**: Enables agents to execute code in a secure environment
11+
- **[`UrlContextTool`][pydantic_ai.builtin_tools.UrlContextTool]**: Enables agents to pull URL contents into their context
1112

1213
These tools are passed to the agent via the `builtin_tools` parameter and are executed by the model provider's infrastructure.
1314

@@ -26,7 +27,7 @@ making it ideal for queries that require up-to-date data.
2627
| OpenAI || Full feature support |
2728
| Anthropic || Full feature support |
2829
| Groq || Limited parameter support |
29-
| Google | | Not supported |
30+
| Google | | No parameter support |
3031
| Bedrock || Not supported |
3132
| Mistral || Not supported |
3233
| Cohere || Not supported |
@@ -118,6 +119,35 @@ result = agent.run_sync('Calculate the factorial of 15 and show your work')
118119
# > The factorial of 15 is **1,307,674,368,000**.
119120
```
120121

122+
## URL Context Tool
123+
124+
The [`UrlContextTool`][pydantic_ai.builtin_tools.UrlContextTool] enables your agent to pull URL contents into its context,
125+
allowing it to pull up-to-date information from the web.
126+
127+
### Provider Support
128+
129+
| Provider | Supported |
130+
|----------|-----------|
131+
| Google ||
132+
| OpenAI ||
133+
| Anthropic ||
134+
| Groq ||
135+
| Bedrock ||
136+
| Mistral ||
137+
| Cohere ||
138+
| HuggingFace ||
139+
140+
### Usage
141+
142+
```py title="url_context_basic.py"
143+
from pydantic_ai import Agent, UrlContextTool
144+
145+
agent = Agent('google-gla:gemini-2.5-flash', builtin_tools=[UrlContextTool()])
146+
147+
result = agent.run_sync('What is this? https://ai.pydantic.dev')
148+
# > A Python agent framework for building Generative AI applications.
149+
```
150+
121151
## API Reference
122152

123153
For complete API documentation, see the [API Reference](api/builtin_tools.md).

docs/mcp/run-python.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@ where:
3232
so Pyodide can download and cache the Python standard library and packages
3333
- `--node-modules-dir=auto` tells deno to use a local `node_modules` directory
3434
- `stdio` runs the server with the
35-
[Stdio MCP transport](https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/transports/#stdio)
36-
— suitable for running the process as a subprocess locally
35+
[Stdio MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) — suitable for
36+
running the process as a subprocess locally
3737
- `streamable_http` runs the server with the
38-
[Streamable HTTP MCP transport](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http)
39-
— running the server as an HTTP server to connect locally or remotely.
40-
This supports stateful requests, but does not require the client to hold a stateful connection like SSE
38+
[Streamable HTTP MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) -
39+
suitable for running the server as an HTTP server to connect locally or remotely. This supports stateful requests, but does not require the client to hold a stateful connection like SSE
4140
- `sse` runs the server with the
42-
[SSE MCP transport](https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/transports/#http-with-sse)
43-
— running the server as an HTTP server to connect locally or remotely
41+
[SSE MCP transport](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports#http-with-sse)
42+
suitable for running the server as an HTTP server to connect locally or remotely. Note that the SSE transport has been
43+
[deprecated in newer MCP protocol versions](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#backwards-compatibility)
44+
and is there to maintain backwards compatibility.
4445
- `warmup` will run a minimal Python script to download and cache the Python
4546
standard library. This is also useful to check the server is running
4647
correctly.

docs/multi-agent-applications.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ async def joke_factory(ctx: RunContext[None], count: int) -> list[str]:
4848

4949
result = joke_selection_agent.run_sync(
5050
'Tell me a joke.',
51-
usage_limits=UsageLimits(request_limit=5, total_tokens_limit=300),
51+
usage_limits=UsageLimits(request_limit=5, total_tokens_limit=500),
5252
)
5353
print(result.output)
5454
#> Did you hear about the toothpaste scandal? They called it Colgate.

docs/tools.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ _(This example is complete, it can be run "as is")_
471471

472472
### Custom Tool Schema
473473

474-
If you have a function that lacks appropriate documentation (i.e. poorly named, no type information, poor docstring, use of \*args or \*\*kwargs and suchlike) then you can still turn it into a tool that can be effectively used by the agent with the [`Tool.from_schema`][pydantic_ai.Tool.from_schema] function. With this you provide the name, description and JSON schema for the function directly:
474+
If you have a function that lacks appropriate documentation (i.e. poorly named, no type information, poor docstring, use of \*args or \*\*kwargs and suchlike) then you can still turn it into a tool that can be effectively used by the agent with the [`Tool.from_schema`][pydantic_ai.Tool.from_schema] function. With this you provide the name, description, JSON schema, and whether the function takes a `RunContext` for the function directly:
475475

476476
```python
477477
from pydantic_ai import Agent, Tool
@@ -493,7 +493,8 @@ tool = Tool.from_schema(
493493
},
494494
'required': ['a', 'b'],
495495
'type': 'object',
496-
}
496+
},
497+
takes_ctx=False,
497498
)
498499

499500
test_model = TestModel()

mcp-run-python/README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The server can be run with `deno` installed using:
1212
```bash
1313
deno run \
1414
-N -R=node_modules -W=node_modules --node-modules-dir=auto \
15-
jsr:@pydantic/mcp-run-python [stdio|sse|warmup]
15+
jsr:@pydantic/mcp-run-python [stdio|streamable_http|sse|warmup]
1616
```
1717

1818
where:
@@ -22,11 +22,17 @@ where:
2222
the Python standard library and packages
2323
- `--node-modules-dir=auto` tells deno to use a local `node_modules` directory
2424
- `stdio` runs the server with the
25-
[Stdio MCP transport](https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/transports/#stdio)
26-
suitable for running the process as a subprocess locally
25+
[Stdio MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) — suitable for
26+
running the process as a subprocess locally
27+
- `streamable_http` runs the server with the
28+
[Streamable HTTP MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) -
29+
suitable for running the server as an HTTP server to connect locally or remotely. This supports stateful requests, but
30+
does not require the client to hold a stateful connection like SSE
2731
- `sse` runs the server with the
28-
[SSE MCP transport](https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/transports/#http-with-sse)
29-
running the server as an HTTP server to connect locally or remotely
32+
[SSE MCP transport](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports#http-with-sse)
33+
suitable for running the server as an HTTP server to connect locally or remotely. Note that the SSE transport has been
34+
[deprecated in newer MCP protocol versions](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#backwards-compatibility)
35+
and is there to maintain backwards compatibility.
3036
- `warmup` will run a minimal Python script to download and cache the Python standard library. This is also useful to
3137
check the server is running correctly.
3238

pydantic_ai_slim/pydantic_ai/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from importlib.metadata import version as _metadata_version
22

33
from .agent import Agent, CallToolsNode, EndStrategy, ModelRequestNode, UserPromptNode, capture_run_messages
4-
from .builtin_tools import CodeExecutionTool, WebSearchTool, WebSearchUserLocation
4+
from .builtin_tools import CodeExecutionTool, UrlContextTool, WebSearchTool, WebSearchUserLocation
55
from .exceptions import (
66
AgentRunError,
77
FallbackExceptionGroup,
@@ -45,6 +45,7 @@
4545
# builtin_tools
4646
'WebSearchTool',
4747
'WebSearchUserLocation',
48+
'UrlContextTool',
4849
'CodeExecutionTool',
4950
# output
5051
'ToolOutput',
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""Type definitions of OpenTelemetry GenAI spec message parts.
2+
3+
Based on https://github.com/lmolkova/semantic-conventions/blob/eccd1f806e426a32c98271c3ce77585492d26de2/docs/gen-ai/non-normative/models.ipynb
4+
"""
5+
6+
from __future__ import annotations
7+
8+
from typing import Literal
9+
10+
from pydantic import JsonValue
11+
from typing_extensions import NotRequired, TypeAlias, TypedDict
12+
13+
14+
class TextPart(TypedDict):
15+
type: Literal['text']
16+
content: NotRequired[str]
17+
18+
19+
class ToolCallPart(TypedDict):
20+
type: Literal['tool_call']
21+
id: str
22+
name: str
23+
arguments: NotRequired[JsonValue]
24+
25+
26+
class ToolCallResponsePart(TypedDict):
27+
type: Literal['tool_call_response']
28+
id: str
29+
name: str
30+
result: NotRequired[JsonValue]
31+
32+
33+
class MediaUrlPart(TypedDict):
34+
type: Literal['image-url', 'audio-url', 'video-url', 'document-url']
35+
url: NotRequired[str]
36+
37+
38+
class BinaryDataPart(TypedDict):
39+
type: Literal['binary']
40+
media_type: str
41+
content: NotRequired[str]
42+
43+
44+
class ThinkingPart(TypedDict):
45+
type: Literal['thinking']
46+
content: NotRequired[str]
47+
48+
49+
MessagePart: TypeAlias = 'TextPart | ToolCallPart | ToolCallResponsePart | MediaUrlPart | BinaryDataPart | ThinkingPart'
50+
51+
52+
Role = Literal['system', 'user', 'assistant']
53+
54+
55+
class ChatMessage(TypedDict):
56+
role: Role
57+
parts: list[MessagePart]
58+
59+
60+
InputMessages: TypeAlias = list[ChatMessage]
61+
62+
63+
class OutputMessage(ChatMessage):
64+
finish_reason: NotRequired[str]
65+
66+
67+
OutputMessages: TypeAlias = list[OutputMessage]

0 commit comments

Comments
 (0)