Skip to content

Commit bbf5626

Browse files
authored
Merge branch 'main' into feat-anthropic-cache-all
2 parents 03dfa19 + 50489c5 commit bbf5626

File tree

110 files changed

+8158
-1108
lines changed

Some content is hidden

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

110 files changed

+8158
-1108
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typecheck-pyright:
4343
.PHONY: typecheck-mypy
4444
typecheck-mypy:
4545
uv run mypy
46+
uv run mypy typings/ --strict
4647

4748
.PHONY: typecheck
4849
typecheck: typecheck-pyright ## Run static type checking

docs/api/models/openrouter.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# `pydantic_ai.models.openrouter`
2+
3+
## Setup
4+
5+
For details on how to set up authentication with this model, see [model configuration for OpenRouter](../../models/openrouter.md).
6+
7+
::: pydantic_ai.models.openrouter

docs/builtin-tools.md

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Pydantic AI supports the following built-in tools:
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
1111
- **[`ImageGenerationTool`][pydantic_ai.builtin_tools.ImageGenerationTool]**: Enables agents to generate images
12-
- **[`UrlContextTool`][pydantic_ai.builtin_tools.UrlContextTool]**: Enables agents to pull URL contents into their context
12+
- **[`WebFetchTool`][pydantic_ai.builtin_tools.WebFetchTool]**: Enables agents to fetch web pages
1313
- **[`MemoryTool`][pydantic_ai.builtin_tools.MemoryTool]**: Enables agents to use memory
1414
- **[`MCPServerTool`][pydantic_ai.builtin_tools.MCPServerTool]**: Enables agents to use remote MCP servers with communication handled by the model provider
1515

@@ -306,18 +306,18 @@ For more details, check the [API documentation][pydantic_ai.builtin_tools.ImageG
306306
| `quality` |||
307307
| `size` |||
308308

309-
## URL Context Tool
309+
## Web Fetch Tool
310310

311-
The [`UrlContextTool`][pydantic_ai.builtin_tools.UrlContextTool] enables your agent to pull URL contents into its context,
311+
The [`WebFetchTool`][pydantic_ai.builtin_tools.WebFetchTool] enables your agent to pull URL contents into its context,
312312
allowing it to pull up-to-date information from the web.
313313

314314
### Provider Support
315315

316316
| Provider | Supported | Notes |
317317
|----------|-----------|-------|
318-
| Google || No [`BuiltinToolCallPart`][pydantic_ai.messages.BuiltinToolCallPart] or [`BuiltinToolReturnPart`][pydantic_ai.messages.BuiltinToolReturnPart] is currently generated; please submit an issue if you need this. Using built-in tools and function tools (including [output tools](output.md#tool-output)) at the same time is not supported; to use structured output, use [`PromptedOutput`](output.md#prompted-output) instead. |
318+
| Anthropic || Full feature support. Uses Anthropic's [Web Fetch Tool](https://docs.claude.com/en/docs/agents-and-tools/tool-use/web-fetch-tool) internally to retrieve URL contents. |
319+
| Google || No parameter support. The limits are fixed at 20 URLs per request with a maximum of 34MB per URL. Using built-in tools and function tools (including [output tools](output.md#tool-output)) at the same time is not supported; to use structured output, use [`PromptedOutput`](output.md#prompted-output) instead. |
319320
| OpenAI || |
320-
| Anthropic || |
321321
| Groq || |
322322
| Bedrock || |
323323
| Mistral || |
@@ -327,10 +327,10 @@ allowing it to pull up-to-date information from the web.
327327

328328
### Usage
329329

330-
```py {title="url_context_basic.py"}
331-
from pydantic_ai import Agent, UrlContextTool
330+
```py {title="web_fetch_basic.py"}
331+
from pydantic_ai import Agent, WebFetchTool
332332

333-
agent = Agent('google-gla:gemini-2.5-flash', builtin_tools=[UrlContextTool()])
333+
agent = Agent('google-gla:gemini-2.5-flash', builtin_tools=[WebFetchTool()])
334334

335335
result = agent.run_sync('What is this? https://ai.pydantic.dev')
336336
print(result.output)
@@ -339,6 +339,49 @@ print(result.output)
339339

340340
_(This example is complete, it can be run "as is")_
341341

342+
### Configuration Options
343+
344+
The `WebFetchTool` supports several configuration parameters:
345+
346+
```py {title="web_fetch_configured.py"}
347+
from pydantic_ai import Agent, WebFetchTool
348+
349+
agent = Agent(
350+
'anthropic:claude-sonnet-4-0',
351+
builtin_tools=[
352+
WebFetchTool(
353+
allowed_domains=['ai.pydantic.dev', 'docs.pydantic.dev'],
354+
max_uses=10,
355+
enable_citations=True,
356+
max_content_tokens=50000,
357+
)
358+
],
359+
)
360+
361+
result = agent.run_sync(
362+
'Compare the documentation at https://ai.pydantic.dev and https://docs.pydantic.dev'
363+
)
364+
print(result.output)
365+
"""
366+
Both sites provide comprehensive documentation for Pydantic projects. ai.pydantic.dev focuses on PydanticAI, a framework for building AI agents, while docs.pydantic.dev covers Pydantic, the data validation library. They share similar documentation styles and both emphasize type safety and developer experience.
367+
"""
368+
```
369+
370+
_(This example is complete, it can be run "as is")_
371+
372+
#### Provider Support
373+
374+
| Parameter | Anthropic | Google |
375+
|-----------|-----------|--------|
376+
| `max_uses` |||
377+
| `allowed_domains` |||
378+
| `blocked_domains` |||
379+
| `enable_citations` |||
380+
| `max_content_tokens` |||
381+
382+
!!! note "Anthropic Domain Filtering"
383+
With Anthropic, you can only use either `blocked_domains` or `allowed_domains`, not both.
384+
342385
## Memory Tool
343386

344387
The [`MemoryTool`][pydantic_ai.builtin_tools.MemoryTool] enables your agent to use memory.

docs/models/openai.md

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ agent = Agent(model)
233233
```
234234

235235
Various providers also have their own provider classes so that you don't need to specify the base URL yourself and you can use the standard `<PROVIDER>_API_KEY` environment variable to set the API key.
236-
When a provider has its own provider class, you can use the `Agent("<provider>:<model>")` shorthand, e.g. `Agent("deepseek:deepseek-chat")` or `Agent("openrouter:google/gemini-2.5-pro-preview")`, instead of building the `OpenAIChatModel` explicitly. Similarly, you can pass the provider name as a string to the `provider` argument on `OpenAIChatModel` instead of building instantiating the provider class explicitly.
236+
When a provider has its own provider class, you can use the `Agent("<provider>:<model>")` shorthand, e.g. `Agent("deepseek:deepseek-chat")` or `Agent("moonshotai:kimi-k2-0711-preview")`, instead of building the `OpenAIChatModel` explicitly. Similarly, you can pass the provider name as a string to the `provider` argument on `OpenAIChatModel` instead of building instantiating the provider class explicitly.
237237

238238
#### Model Profile
239239

@@ -385,34 +385,6 @@ agent = Agent(model)
385385
...
386386
```
387387

388-
### OpenRouter
389-
390-
To use [OpenRouter](https://openrouter.ai), first create an API key at [openrouter.ai/keys](https://openrouter.ai/keys).
391-
392-
You can set the `OPENROUTER_API_KEY` environment variable and use [`OpenRouterProvider`][pydantic_ai.providers.openrouter.OpenRouterProvider] by name:
393-
394-
```python
395-
from pydantic_ai import Agent
396-
397-
agent = Agent('openrouter:anthropic/claude-3.5-sonnet')
398-
...
399-
```
400-
401-
Or initialise the model and provider directly:
402-
403-
```python
404-
from pydantic_ai import Agent
405-
from pydantic_ai.models.openai import OpenAIChatModel
406-
from pydantic_ai.providers.openrouter import OpenRouterProvider
407-
408-
model = OpenAIChatModel(
409-
'anthropic/claude-3.5-sonnet',
410-
provider=OpenRouterProvider(api_key='your-openrouter-api-key'),
411-
)
412-
agent = Agent(model)
413-
...
414-
```
415-
416388
### Vercel AI Gateway
417389

418390
To use [Vercel's AI Gateway](https://vercel.com/docs/ai-gateway), first follow the [documentation](https://vercel.com/docs/ai-gateway) instructions on obtaining an API key or OIDC token.

docs/models/openrouter.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# OpenRouter
2+
3+
## Install
4+
5+
To use `OpenRouterModel`, you need to either install `pydantic-ai`, or install `pydantic-ai-slim` with the `openrouter` optional group:
6+
7+
```bash
8+
pip/uv-add "pydantic-ai-slim[openrouter]"
9+
```
10+
11+
## Configuration
12+
13+
To use [OpenRouter](https://openrouter.ai), first create an API key at [openrouter.ai/keys](https://openrouter.ai/keys).
14+
15+
You can set the `OPENROUTER_API_KEY` environment variable and use [`OpenRouterProvider`][pydantic_ai.providers.openrouter.OpenRouterProvider] by name:
16+
17+
```python
18+
from pydantic_ai import Agent
19+
20+
agent = Agent('openrouter:anthropic/claude-3.5-sonnet')
21+
...
22+
```
23+
24+
Or initialise the model and provider directly:
25+
26+
```python
27+
from pydantic_ai import Agent
28+
from pydantic_ai.models.openrouter import OpenRouterModel
29+
from pydantic_ai.providers.openrouter import OpenRouterProvider
30+
31+
model = OpenRouterModel(
32+
'anthropic/claude-3.5-sonnet',
33+
provider=OpenRouterProvider(api_key='your-openrouter-api-key'),
34+
)
35+
agent = Agent(model)
36+
...
37+
```
38+
39+
## App Attribution
40+
41+
OpenRouter has an [app attribution](https://openrouter.ai/docs/app-attribution) feature to track your application in their public ranking and analytics.
42+
43+
You can pass in an `app_url` and `app_title` when initializing the provider to enable app attribution.
44+
45+
```python
46+
from pydantic_ai.providers.openrouter import OpenRouterProvider
47+
48+
provider=OpenRouterProvider(
49+
api_key='your-openrouter-api-key',
50+
app_url='https://your-app.com',
51+
app_title='Your App',
52+
),
53+
...
54+
```
55+
56+
## Model Settings
57+
58+
You can customize model behavior using [`OpenRouterModelSettings`][pydantic_ai.models.openrouter.OpenRouterModelSettings]:
59+
60+
```python
61+
from pydantic_ai import Agent
62+
from pydantic_ai.models.openrouter import OpenRouterModel, OpenRouterModelSettings
63+
64+
settings = OpenRouterModelSettings(
65+
openrouter_reasoning={
66+
'effort': 'high',
67+
},
68+
openrouter_usage={
69+
'include': True,
70+
}
71+
)
72+
model = OpenRouterModel('openai/gpt-5')
73+
agent = Agent(model, model_settings=settings)
74+
...
75+
```

docs/models/overview.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,32 @@ Pydantic AI is model-agnostic and has built-in support for multiple model provid
55
* [OpenAI](openai.md)
66
* [Anthropic](anthropic.md)
77
* [Gemini](google.md) (via two different APIs: Generative Language API and VertexAI API)
8-
* [Groq](groq.md)
9-
* [Mistral](mistral.md)
10-
* [Cohere](cohere.md)
118
* [Bedrock](bedrock.md)
9+
* [Cohere](cohere.md)
10+
* [Groq](groq.md)
1211
* [Hugging Face](huggingface.md)
12+
* [Mistral](mistral.md)
13+
* [OpenRouter](openrouter.md)
1314
* [Outlines](outlines.md)
1415

1516
## OpenAI-compatible Providers
1617

1718
In addition, many providers are compatible with the OpenAI API, and can be used with `OpenAIChatModel` in Pydantic AI:
1819

20+
- [Azure AI Foundry](openai.md#azure-ai-foundry)
21+
- [Cerebras](openai.md#cerebras)
1922
- [DeepSeek](openai.md#deepseek)
20-
- [Grok (xAI)](openai.md#grok-xai)
21-
- [Ollama](openai.md#ollama)
22-
- [OpenRouter](openai.md#openrouter)
23-
- [Vercel AI Gateway](openai.md#vercel-ai-gateway)
24-
- [Perplexity](openai.md#perplexity)
2523
- [Fireworks AI](openai.md#fireworks-ai)
26-
- [Together AI](openai.md#together-ai)
27-
- [Azure AI Foundry](openai.md#azure-ai-foundry)
28-
- [Heroku](openai.md#heroku-ai)
2924
- [GitHub Models](openai.md#github-models)
30-
- [Cerebras](openai.md#cerebras)
25+
- [Grok (xAI)](openai.md#grok-xai)
26+
- [Heroku](openai.md#heroku-ai)
3127
- [LiteLLM](openai.md#litellm)
3228
- [Nebius AI Studio](openai.md#nebius-ai-studio)
29+
- [Ollama](openai.md#ollama)
3330
- [OVHcloud AI Endpoints](openai.md#ovhcloud-ai-endpoints)
31+
- [Perplexity](openai.md#perplexity)
32+
- [Together AI](openai.md#together-ai)
33+
- [Vercel AI Gateway](openai.md#vercel-ai-gateway)
3434

3535
Pydantic AI also comes with [`TestModel`](../api/models/test.md) and [`FunctionModel`](../api/models/function.md)
3636
for testing and development.
@@ -180,7 +180,7 @@ contains all the exceptions encountered during the `run` execution.
180180
=== "Python >=3.11"
181181

182182
```python {title="fallback_model_failure.py" py="3.11"}
183-
from pydantic_ai import Agent, ModelHTTPError
183+
from pydantic_ai import Agent, ModelAPIError
184184
from pydantic_ai.models.anthropic import AnthropicModel
185185
from pydantic_ai.models.fallback import FallbackModel
186186
from pydantic_ai.models.openai import OpenAIChatModel
@@ -192,7 +192,7 @@ contains all the exceptions encountered during the `run` execution.
192192
agent = Agent(fallback_model)
193193
try:
194194
response = agent.run_sync('What is the capital of France?')
195-
except* ModelHTTPError as exc_group:
195+
except* ModelAPIError as exc_group:
196196
for exc in exc_group.exceptions:
197197
print(exc)
198198
```
@@ -206,7 +206,7 @@ contains all the exceptions encountered during the `run` execution.
206206
```python {title="fallback_model_failure.py" noqa="F821" test="skip"}
207207
from exceptiongroup import catch
208208

209-
from pydantic_ai import Agent, ModelHTTPError
209+
from pydantic_ai import Agent, ModelAPIError
210210
from pydantic_ai.models.anthropic import AnthropicModel
211211
from pydantic_ai.models.fallback import FallbackModel
212212
from pydantic_ai.models.openai import OpenAIChatModel
@@ -222,10 +222,11 @@ contains all the exceptions encountered during the `run` execution.
222222
fallback_model = FallbackModel(openai_model, anthropic_model)
223223

224224
agent = Agent(fallback_model)
225-
with catch({ModelHTTPError: model_status_error_handler}):
225+
with catch({ModelAPIError: model_status_error_handler}):
226226
response = agent.run_sync('What is the capital of France?')
227227
```
228228

229229
By default, the `FallbackModel` only moves on to the next model if the current model raises a
230+
[`ModelAPIError`][pydantic_ai.exceptions.ModelAPIError], which includes
230231
[`ModelHTTPError`][pydantic_ai.exceptions.ModelHTTPError]. You can customize this behavior by
231232
passing a custom `fallback_on` argument to the `FallbackModel` constructor.

docs/thinking.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,20 @@ agent = Agent(model, model_settings=settings)
144144
...
145145
```
146146

147+
## OpenRouter
148+
149+
To enable thinking, use the [`OpenRouterModelSettings.openrouter_reasoning`][pydantic_ai.models.openrouter.OpenRouterModelSettings.openrouter_reasoning] [model setting](agents.md#model-run-settings).
150+
151+
```python {title="openrouter_thinking_part.py"}
152+
from pydantic_ai import Agent
153+
from pydantic_ai.models.openrouter import OpenRouterModel, OpenRouterModelSettings
154+
155+
model = OpenRouterModel('openai/gpt-5')
156+
settings = OpenRouterModelSettings(openrouter_reasoning={'effort': 'high'})
157+
agent = Agent(model, model_settings=settings)
158+
...
159+
```
160+
147161
## Mistral
148162

149163
Thinking is supported by the `magistral` family of models. It does not need to be specifically enabled.

mkdocs.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ nav:
3232
- models/bedrock.md
3333
- models/cohere.md
3434
- models/groq.md
35-
- models/mistral.md
3635
- models/huggingface.md
36+
- models/mistral.md
37+
- models/openrouter.md
3738
- models/outlines.md
3839
- Tools & Toolsets:
3940
- tools.md
@@ -142,22 +143,23 @@ nav:
142143
- api/format_prompt.md
143144
- api/direct.md
144145
- api/ext.md
145-
- api/models/base.md
146-
- api/models/openai.md
147146
- api/models/anthropic.md
147+
- api/models/base.md
148148
- api/models/bedrock.md
149149
- api/models/cohere.md
150+
- api/models/fallback.md
151+
- api/models/function.md
150152
- api/models/google.md
151153
- api/models/groq.md
152154
- api/models/huggingface.md
153155
- api/models/instrumented.md
156+
- api/models/mcp-sampling.md
154157
- api/models/mistral.md
158+
- api/models/openai.md
159+
- api/models/openrouter.md
155160
- api/models/outlines.md
156161
- api/models/test.md
157-
- api/models/function.md
158-
- api/models/fallback.md
159162
- api/models/wrapper.md
160-
- api/models/mcp-sampling.md
161163
- api/profiles.md
162164
- api/providers.md
163165
- api/retries.md

0 commit comments

Comments
 (0)