From 09a04ee57ce39cef07cf7e5e0cc91e9d41c99565 Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Wed, 19 Nov 2025 20:28:27 -0500 Subject: [PATCH 01/11] add examples to pass an api key and route through a non default provider --- docs/gateway.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/gateway.md b/docs/gateway.md index da9198b4b5..11fe455666 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -35,6 +35,40 @@ from pydantic_ai import Agent agent = Agent('gateway/openai:gpt-5') +result = agent.run_sync('Where does "hello world" come from?') +print(result.output) +""" +The first known use of "hello, world" was in a 1974 textbook about the C programming language. +""" +``` +```python {title="passing_api_key.py"} +from pydantic_ai import Agent + +from pydantic_ai import Agent +from pydantic_ai.providers.gateway import gateway_provider +from pydantic_ai.models.openai import OpenAIChatModel + +provider = gateway_provider('openai', api_key='PYDANTIC_AI_GATEWAY_API_KEY') +model = OpenAIChatModel('gpt-5', provider=provider) +agent = Agent(model) + +result = agent.run_sync('Where does "hello world" come from?') +print(result.output) +""" +The first known use of "hello, world" was in a 1974 textbook about the C programming language. +""" +``` +```python {title="routing_via_provider.py"} +from pydantic_ai import Agent + +from pydantic_ai import Agent +from pydantic_ai.providers.gateway import gateway_provider +from pydantic_ai.models.openai import OpenAIChatModel + +provider = gateway_provider('openai', api_key='PYDANTIC_AI_GATEWAY_API_KEY') +model = OpenAIChatModel('gpt-5', provider=provider, route='modal-ai') +agent = Agent(model) + result = agent.run_sync('Where does "hello world" come from?') print(result.output) """ From 8d8d8fe321c144bb1f8d1ce48a36ffbb7314a5db Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Thu, 20 Nov 2025 09:57:20 -0500 Subject: [PATCH 02/11] move examples to usage --- docs/gateway.md | 76 +++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/docs/gateway.md b/docs/gateway.md index 11fe455666..530ef258f2 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -35,40 +35,6 @@ from pydantic_ai import Agent agent = Agent('gateway/openai:gpt-5') -result = agent.run_sync('Where does "hello world" come from?') -print(result.output) -""" -The first known use of "hello, world" was in a 1974 textbook about the C programming language. -""" -``` -```python {title="passing_api_key.py"} -from pydantic_ai import Agent - -from pydantic_ai import Agent -from pydantic_ai.providers.gateway import gateway_provider -from pydantic_ai.models.openai import OpenAIChatModel - -provider = gateway_provider('openai', api_key='PYDANTIC_AI_GATEWAY_API_KEY') -model = OpenAIChatModel('gpt-5', provider=provider) -agent = Agent(model) - -result = agent.run_sync('Where does "hello world" come from?') -print(result.output) -""" -The first known use of "hello, world" was in a 1974 textbook about the C programming language. -""" -``` -```python {title="routing_via_provider.py"} -from pydantic_ai import Agent - -from pydantic_ai import Agent -from pydantic_ai.providers.gateway import gateway_provider -from pydantic_ai.models.openai import OpenAIChatModel - -provider = gateway_provider('openai', api_key='PYDANTIC_AI_GATEWAY_API_KEY') -model = OpenAIChatModel('gpt-5', provider=provider, route='modal-ai') -agent = Agent(model) - result = agent.run_sync('Where does "hello world" come from?') print(result.output) """ @@ -164,7 +130,49 @@ print(result.output) The first known use of "hello, world" was in a 1974 textbook about the C programming language. """ ``` +=== "Passing API Key Directly" + + Pass your API key directly using the provider: + + ```python {title="passing_api_key.py"} + from pydantic_ai import Agent + + from pydantic_ai import Agent + from pydantic_ai.providers.gateway import gateway_provider + from pydantic_ai.models.openai import OpenAIChatModel + + provider = gateway_provider('openai', api_key='PYDANTIC_AI_GATEWAY_API_KEY') + model = OpenAIChatModel('gpt-5', provider=provider) + agent = Agent(model) + result = agent.run_sync('Where does "hello world" come from?') + print(result.output) + """ + The first known use of "hello, world" was in a 1974 textbook about the C programming language. + """ + ``` + +=== "Using a different upstream provider" + + If you're using a different upstream provider, you can specify it in the route parameter: + + ```python {title="routing_via_provider.py"} + from pydantic_ai import Agent + + from pydantic_ai import Agent + from pydantic_ai.providers.gateway import gateway_provider + from pydantic_ai.models.openai import OpenAIChatModel + + provider = gateway_provider('openai', api_key='PYDANTIC_AI_GATEWAY_API_KEY', route='modal-ai') + model = OpenAIChatModel('gpt-5', provider=provider) + agent = Agent(model) + + result = agent.run_sync('Where does "hello world" come from?') + print(result.output) + """ + The first known use of "hello, world" was in a 1974 textbook about the C programming language. + """ + ``` ### Claude Code From f2a0687c459402d8d97219667ed744a224727569 Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:00:53 -0500 Subject: [PATCH 03/11] include hello world in the same code block --- docs/gateway.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/gateway.md b/docs/gateway.md index 530ef258f2..78f43238c1 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -119,18 +119,21 @@ export PYDANTIC_AI_GATEWAY_API_KEY="YOUR_PYDANTIC_AI_GATEWAY_API_KEY" You can access multiple models with the same API key, as shown in the code snippet below. -```python {title="hello_world.py"} -from pydantic_ai import Agent +=== "Hello World" -agent = Agent('gateway/openai:gpt-5') + ```python {title="hello_world.py"} + from pydantic_ai import Agent -result = agent.run_sync('Where does "hello world" come from?') -print(result.output) -""" -The first known use of "hello, world" was in a 1974 textbook about the C programming language. -""" -``` -=== "Passing API Key Directly" + agent = Agent('gateway/openai:gpt-5') + + result = agent.run_sync('Where does "hello world" come from?') + print(result.output) + """ + The first known use of "hello, world" was in a 1974 textbook about the C programming language. + """ + ``` + +=== "Passing API Key directly" Pass your API key directly using the provider: From 0b4cb930f5bd43f9d142c3eb64a1f5cd7b58a0f6 Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:02:00 -0500 Subject: [PATCH 04/11] better formatting for third example --- docs/gateway.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/gateway.md b/docs/gateway.md index 78f43238c1..806dc00b3b 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -138,8 +138,6 @@ You can access multiple models with the same API key, as shown in the code snipp Pass your API key directly using the provider: ```python {title="passing_api_key.py"} - from pydantic_ai import Agent - from pydantic_ai import Agent from pydantic_ai.providers.gateway import gateway_provider from pydantic_ai.models.openai import OpenAIChatModel @@ -160,13 +158,15 @@ You can access multiple models with the same API key, as shown in the code snipp If you're using a different upstream provider, you can specify it in the route parameter: ```python {title="routing_via_provider.py"} - from pydantic_ai import Agent - from pydantic_ai import Agent from pydantic_ai.providers.gateway import gateway_provider from pydantic_ai.models.openai import OpenAIChatModel - provider = gateway_provider('openai', api_key='PYDANTIC_AI_GATEWAY_API_KEY', route='modal-ai') + provider = gateway_provider( + 'openai', + api_key='PYDANTIC_AI_GATEWAY_API_KEY', + route='modal-ai' + ) model = OpenAIChatModel('gpt-5', provider=provider) agent = Agent(model) From 21ebce025fa64f2a19dc5ee3d56f0451b9aff051 Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:23:50 -0500 Subject: [PATCH 05/11] sort imports in codeblocks --- docs/gateway.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/gateway.md b/docs/gateway.md index 806dc00b3b..e4d600eaa6 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -139,8 +139,8 @@ You can access multiple models with the same API key, as shown in the code snipp ```python {title="passing_api_key.py"} from pydantic_ai import Agent - from pydantic_ai.providers.gateway import gateway_provider from pydantic_ai.models.openai import OpenAIChatModel + from pydantic_ai.providers.gateway import gateway_provider provider = gateway_provider('openai', api_key='PYDANTIC_AI_GATEWAY_API_KEY') model = OpenAIChatModel('gpt-5', provider=provider) @@ -159,8 +159,8 @@ You can access multiple models with the same API key, as shown in the code snipp ```python {title="routing_via_provider.py"} from pydantic_ai import Agent - from pydantic_ai.providers.gateway import gateway_provider from pydantic_ai.models.openai import OpenAIChatModel + from pydantic_ai.providers.gateway import gateway_provider provider = gateway_provider( 'openai', From 9659237cec635fb00736bea3922c5ccea9ab27e7 Mon Sep 17 00:00:00 2001 From: David <64162682+dsfaccini@users.noreply.github.com> Date: Fri, 21 Nov 2025 07:42:38 -0500 Subject: [PATCH 06/11] add link to api reference --- docs/gateway.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gateway.md b/docs/gateway.md index e4d600eaa6..bc1c284379 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -135,7 +135,7 @@ You can access multiple models with the same API key, as shown in the code snipp === "Passing API Key directly" - Pass your API key directly using the provider: + Pass your API key directly using the [gateway_provider](https://ai.pydantic.dev/api/providers/#pydantic_ai.providers.gateway): ```python {title="passing_api_key.py"} from pydantic_ai import Agent From 1974ce00fee24f3f25692f75f65db8641c586cc6 Mon Sep 17 00:00:00 2001 From: David <64162682+dsfaccini@users.noreply.github.com> Date: Fri, 21 Nov 2025 07:43:38 -0500 Subject: [PATCH 07/11] add gateway provider to the api/providers docs --- docs/api/providers.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api/providers.md b/docs/api/providers.md index aabf10f068..8887c417c5 100644 --- a/docs/api/providers.md +++ b/docs/api/providers.md @@ -2,6 +2,8 @@ ::: pydantic_ai.providers.Provider +::: pydantic_ai.providers.gateway + ::: pydantic_ai.providers.google ::: pydantic_ai.providers.openai From 2d15d5ec2e111d4fc3884c74e51ef7522f635d7e Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Fri, 21 Nov 2025 12:32:42 -0500 Subject: [PATCH 08/11] add heading --- docs/api/providers.md | 4 +++- docs/gateway.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/api/providers.md b/docs/api/providers.md index 8887c417c5..7c946b56c9 100644 --- a/docs/api/providers.md +++ b/docs/api/providers.md @@ -2,7 +2,9 @@ ::: pydantic_ai.providers.Provider -::: pydantic_ai.providers.gateway +## Pydantic AI Gateway Provider + +::: pydantic_ai.providers.gateway.gateway_provider ::: pydantic_ai.providers.google diff --git a/docs/gateway.md b/docs/gateway.md index bc1c284379..ce9ad94663 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -135,7 +135,7 @@ You can access multiple models with the same API key, as shown in the code snipp === "Passing API Key directly" - Pass your API key directly using the [gateway_provider](https://ai.pydantic.dev/api/providers/#pydantic_ai.providers.gateway): + Pass your API key directly using the [gateway_provider](https://ai.pydantic.dev/api/providers/#pydantic-ai-gateway-provider): ```python {title="passing_api_key.py"} from pydantic_ai import Agent From 4a493d4f2b5640452e33cb52ae53944af9efc7cd Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Fri, 21 Nov 2025 12:34:43 -0500 Subject: [PATCH 09/11] narrow wording --- docs/gateway.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gateway.md b/docs/gateway.md index ce9ad94663..f708b7d06a 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -155,7 +155,7 @@ You can access multiple models with the same API key, as shown in the code snipp === "Using a different upstream provider" - If you're using a different upstream provider, you can specify it in the route parameter: + To use an alternate provider or routing group, you can specify it in the route parameter: ```python {title="routing_via_provider.py"} from pydantic_ai import Agent From 4a3e103747291984179ec8fb6d61448ce878cf00 Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Fri, 21 Nov 2025 18:49:17 -0500 Subject: [PATCH 10/11] implement review changes --- docs/gateway.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/gateway.md b/docs/gateway.md index f708b7d06a..2719b351fa 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -111,10 +111,10 @@ Before you start, make sure you are on version 1.16 or later of `pydantic-ai`. T pip install -U pydantic-ai ``` -Set the `PYDANTIC_AI_GATEWAY_API_KEY` environment variable to your Gateway API key: +Set the `PYDANTIC_AI_GATEWAY_API_KEY` environment variable to your Gateway API key: ```bash -export PYDANTIC_AI_GATEWAY_API_KEY="YOUR_PYDANTIC_AI_GATEWAY_API_KEY" +export PYDANTIC_AI_GATEWAY_API_KEY="paig_" ``` You can access multiple models with the same API key, as shown in the code snippet below. @@ -142,7 +142,7 @@ You can access multiple models with the same API key, as shown in the code snipp from pydantic_ai.models.openai import OpenAIChatModel from pydantic_ai.providers.gateway import gateway_provider - provider = gateway_provider('openai', api_key='PYDANTIC_AI_GATEWAY_API_KEY') + provider = gateway_provider('openai', api_key='paig_') model = OpenAIChatModel('gpt-5', provider=provider) agent = Agent(model) @@ -164,8 +164,8 @@ You can access multiple models with the same API key, as shown in the code snipp provider = gateway_provider( 'openai', - api_key='PYDANTIC_AI_GATEWAY_API_KEY', - route='modal-ai' + api_key='paig_', + route='builtin-openai' ) model = OpenAIChatModel('gpt-5', provider=provider) agent = Agent(model) From ef40b87482c01b2259a6d641ad6751ffcfae5542 Mon Sep 17 00:00:00 2001 From: David Sanchez <64162682+dsfaccini@users.noreply.github.com> Date: Sat, 22 Nov 2025 11:52:59 -0500 Subject: [PATCH 11/11] grammatical mistake --- docs/deferred-tools.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/deferred-tools.md b/docs/deferred-tools.md index 4a50027cf7..ceebb2eb09 100644 --- a/docs/deferred-tools.md +++ b/docs/deferred-tools.md @@ -19,7 +19,7 @@ Note that handling deferred tool calls requires `DeferredToolRequests` to be in If a tool function always requires approval, you can pass the `requires_approval=True` argument to the [`@agent.tool`][pydantic_ai.Agent.tool] decorator, [`@agent.tool_plain`][pydantic_ai.Agent.tool_plain] decorator, [`Tool`][pydantic_ai.tools.Tool] class, [`FunctionToolset.tool`][pydantic_ai.toolsets.FunctionToolset.tool] decorator, or [`FunctionToolset.add_function()`][pydantic_ai.toolsets.FunctionToolset.add_function] method. Inside the function, you can then assume that the tool call has been approved. -If whether a tool function requires approval depends on the tool call arguments or the agent [run context][pydantic_ai.tools.RunContext] (e.g. [dependencies](dependencies.md) or message history), you can raise the [`ApprovalRequired`][pydantic_ai.exceptions.ApprovalRequired] exception from the tool function. The [`RunContext.tool_call_approved`][pydantic_ai.tools.RunContext.tool_call_approved] property will be `True` if the tool call has already been approved. +Whether a tool function requires approval depends on the tool call arguments or the agent [run context][pydantic_ai.tools.RunContext] (e.g. [dependencies](dependencies.md) or message history), you can raise the [`ApprovalRequired`][pydantic_ai.exceptions.ApprovalRequired] exception from the tool function. The [`RunContext.tool_call_approved`][pydantic_ai.tools.RunContext.tool_call_approved] property will be `True` if the tool call has already been approved. To require approval for calls to tools provided by a [toolset](toolsets.md) (like an [MCP server](mcp/client.md)), see the [`ApprovalRequiredToolset` documentation](toolsets.md#requiring-tool-approval). @@ -185,7 +185,7 @@ _(This example is complete, it can be run "as is")_ When the result of a tool call cannot be generated inside the same agent run in which it was called, the tool is considered to be external. Examples of external tools are client-side tools implemented by a web or app frontend, and slow tasks that are passed off to a background worker or external service instead of keeping the agent process running. -If whether a tool call should be executed externally depends on the tool call arguments, the agent [run context][pydantic_ai.tools.RunContext] (e.g. [dependencies](dependencies.md) or message history), or how long the task is expected to take, you can define a tool function and conditionally raise the [`CallDeferred`][pydantic_ai.exceptions.CallDeferred] exception. Before raising the exception, the tool function would typically schedule some background task and pass along the [`RunContext.tool_call_id`][pydantic_ai.tools.RunContext.tool_call_id] so that the result can be matched to the deferred tool call later. +Whether a tool call should be executed externally depends on the tool call arguments, the agent [run context][pydantic_ai.tools.RunContext] (e.g. [dependencies](dependencies.md) or message history), or how long the task is expected to take, you can define a tool function and conditionally raise the [`CallDeferred`][pydantic_ai.exceptions.CallDeferred] exception. Before raising the exception, the tool function would typically schedule some background task and pass along the [`RunContext.tool_call_id`][pydantic_ai.tools.RunContext.tool_call_id] so that the result can be matched to the deferred tool call later. If a tool is always executed externally and its definition is provided to your code along with a JSON schema for its arguments, you can use an [`ExternalToolset`](toolsets.md#external-toolset). If the external tools are known up front and you don't have the arguments JSON schema handy, you can also define a tool function with the appropriate signature that does nothing but raise the [`CallDeferred`][pydantic_ai.exceptions.CallDeferred] exception.