diff --git a/pydantic_ai_slim/pydantic_ai/models/__init__.py b/pydantic_ai_slim/pydantic_ai/models/__init__.py index 3bc676559a..0c32083143 100644 --- a/pydantic_ai_slim/pydantic_ai/models/__init__.py +++ b/pydantic_ai_slim/pydantic_ai/models/__init__.py @@ -145,6 +145,196 @@ 'cohere:command-r7b-12-2024', 'deepseek:deepseek-chat', 'deepseek:deepseek-reasoner', + 'gateway/anthropic:claude-3-5-haiku-20241022', + 'gateway/anthropic:claude-3-5-haiku-latest', + 'gateway/anthropic:claude-3-7-sonnet-20250219', + 'gateway/anthropic:claude-3-7-sonnet-latest', + 'gateway/anthropic:claude-3-haiku-20240307', + 'gateway/anthropic:claude-3-opus-20240229', + 'gateway/anthropic:claude-3-opus-latest', + 'gateway/anthropic:claude-4-opus-20250514', + 'gateway/anthropic:claude-4-sonnet-20250514', + 'gateway/anthropic:claude-haiku-4-5', + 'gateway/anthropic:claude-haiku-4-5-20251001', + 'gateway/anthropic:claude-opus-4-0', + 'gateway/anthropic:claude-opus-4-1-20250805', + 'gateway/anthropic:claude-opus-4-20250514', + 'gateway/anthropic:claude-opus-4-5', + 'gateway/anthropic:claude-opus-4-5-20251101', + 'gateway/anthropic:claude-sonnet-4-0', + 'gateway/anthropic:claude-sonnet-4-20250514', + 'gateway/anthropic:claude-sonnet-4-5', + 'gateway/anthropic:claude-sonnet-4-5-20250929', + 'gateway/bedrock:amazon.titan-text-express-v1', + 'gateway/bedrock:amazon.titan-text-lite-v1', + 'gateway/bedrock:amazon.titan-tg1-large', + 'gateway/bedrock:anthropic.claude-3-5-haiku-20241022-v1:0', + 'gateway/bedrock:anthropic.claude-3-5-sonnet-20240620-v1:0', + 'gateway/bedrock:anthropic.claude-3-5-sonnet-20241022-v2:0', + 'gateway/bedrock:anthropic.claude-3-7-sonnet-20250219-v1:0', + 'gateway/bedrock:anthropic.claude-3-haiku-20240307-v1:0', + 'gateway/bedrock:anthropic.claude-3-opus-20240229-v1:0', + 'gateway/bedrock:anthropic.claude-3-sonnet-20240229-v1:0', + 'gateway/bedrock:anthropic.claude-haiku-4-5-20251001-v1:0', + 'gateway/bedrock:anthropic.claude-instant-v1', + 'gateway/bedrock:anthropic.claude-opus-4-20250514-v1:0', + 'gateway/bedrock:anthropic.claude-sonnet-4-20250514-v1:0', + 'gateway/bedrock:anthropic.claude-sonnet-4-5-20250929-v1:0', + 'gateway/bedrock:anthropic.claude-v2', + 'gateway/bedrock:anthropic.claude-v2:1', + 'gateway/bedrock:cohere.command-light-text-v14', + 'gateway/bedrock:cohere.command-r-plus-v1:0', + 'gateway/bedrock:cohere.command-r-v1:0', + 'gateway/bedrock:cohere.command-text-v14', + 'gateway/bedrock:eu.anthropic.claude-haiku-4-5-20251001-v1:0', + 'gateway/bedrock:eu.anthropic.claude-sonnet-4-20250514-v1:0', + 'gateway/bedrock:eu.anthropic.claude-sonnet-4-5-20250929-v1:0', + 'gateway/bedrock:global.anthropic.claude-opus-4-5-20251101-v1:0', + 'gateway/bedrock:meta.llama3-1-405b-instruct-v1:0', + 'gateway/bedrock:meta.llama3-1-70b-instruct-v1:0', + 'gateway/bedrock:meta.llama3-1-8b-instruct-v1:0', + 'gateway/bedrock:meta.llama3-70b-instruct-v1:0', + 'gateway/bedrock:meta.llama3-8b-instruct-v1:0', + 'gateway/bedrock:mistral.mistral-7b-instruct-v0:2', + 'gateway/bedrock:mistral.mistral-large-2402-v1:0', + 'gateway/bedrock:mistral.mistral-large-2407-v1:0', + 'gateway/bedrock:mistral.mixtral-8x7b-instruct-v0:1', + 'gateway/bedrock:us.amazon.nova-lite-v1:0', + 'gateway/bedrock:us.amazon.nova-micro-v1:0', + 'gateway/bedrock:us.amazon.nova-pro-v1:0', + 'gateway/bedrock:us.anthropic.claude-3-5-haiku-20241022-v1:0', + 'gateway/bedrock:us.anthropic.claude-3-5-sonnet-20240620-v1:0', + 'gateway/bedrock:us.anthropic.claude-3-5-sonnet-20241022-v2:0', + 'gateway/bedrock:us.anthropic.claude-3-7-sonnet-20250219-v1:0', + 'gateway/bedrock:us.anthropic.claude-3-haiku-20240307-v1:0', + 'gateway/bedrock:us.anthropic.claude-3-opus-20240229-v1:0', + 'gateway/bedrock:us.anthropic.claude-3-sonnet-20240229-v1:0', + 'gateway/bedrock:us.anthropic.claude-haiku-4-5-20251001-v1:0', + 'gateway/bedrock:us.anthropic.claude-opus-4-20250514-v1:0', + 'gateway/bedrock:us.anthropic.claude-sonnet-4-20250514-v1:0', + 'gateway/bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0', + 'gateway/bedrock:us.meta.llama3-1-70b-instruct-v1:0', + 'gateway/bedrock:us.meta.llama3-1-8b-instruct-v1:0', + 'gateway/bedrock:us.meta.llama3-2-11b-instruct-v1:0', + 'gateway/bedrock:us.meta.llama3-2-1b-instruct-v1:0', + 'gateway/bedrock:us.meta.llama3-2-3b-instruct-v1:0', + 'gateway/bedrock:us.meta.llama3-2-90b-instruct-v1:0', + 'gateway/bedrock:us.meta.llama3-3-70b-instruct-v1:0', + 'gateway/google-vertex:gemini-2.0-flash', + 'gateway/google-vertex:gemini-2.0-flash-lite', + 'gateway/google-vertex:gemini-2.5-flash', + 'gateway/google-vertex:gemini-2.5-flash-image', + 'gateway/google-vertex:gemini-2.5-flash-lite', + 'gateway/google-vertex:gemini-2.5-flash-lite-preview-09-2025', + 'gateway/google-vertex:gemini-2.5-flash-preview-09-2025', + 'gateway/google-vertex:gemini-2.5-pro', + 'gateway/google-vertex:gemini-3-pro-image-preview', + 'gateway/google-vertex:gemini-3-pro-preview', + 'gateway/google-vertex:gemini-flash-latest', + 'gateway/google-vertex:gemini-flash-lite-latest', + 'gateway/groq:deepseek-r1-distill-llama-70b', + 'gateway/groq:deepseek-r1-distill-qwen-32b', + 'gateway/groq:distil-whisper-large-v3-en', + 'gateway/groq:gemma2-9b-it', + 'gateway/groq:llama-3.1-8b-instant', + 'gateway/groq:llama-3.2-11b-vision-preview', + 'gateway/groq:llama-3.2-1b-preview', + 'gateway/groq:llama-3.2-3b-preview', + 'gateway/groq:llama-3.2-90b-vision-preview', + 'gateway/groq:llama-3.3-70b-specdec', + 'gateway/groq:llama-3.3-70b-versatile', + 'gateway/groq:llama-guard-3-8b', + 'gateway/groq:llama3-70b-8192', + 'gateway/groq:llama3-8b-8192', + 'gateway/groq:mistral-saba-24b', + 'gateway/groq:moonshotai/kimi-k2-instruct', + 'gateway/groq:playai-tts', + 'gateway/groq:playai-tts-arabic', + 'gateway/groq:qwen-2.5-32b', + 'gateway/groq:qwen-2.5-coder-32b', + 'gateway/groq:qwen-qwq-32b', + 'gateway/groq:whisper-large-v3', + 'gateway/groq:whisper-large-v3-turbo', + 'gateway/openai:chatgpt-4o-latest', + 'gateway/openai:codex-mini-latest', + 'gateway/openai:computer-use-preview', + 'gateway/openai:computer-use-preview-2025-03-11', + 'gateway/openai:gpt-3.5-turbo', + 'gateway/openai:gpt-3.5-turbo-0125', + 'gateway/openai:gpt-3.5-turbo-0301', + 'gateway/openai:gpt-3.5-turbo-0613', + 'gateway/openai:gpt-3.5-turbo-1106', + 'gateway/openai:gpt-3.5-turbo-16k', + 'gateway/openai:gpt-3.5-turbo-16k-0613', + 'gateway/openai:gpt-4', + 'gateway/openai:gpt-4-0125-preview', + 'gateway/openai:gpt-4-0314', + 'gateway/openai:gpt-4-0613', + 'gateway/openai:gpt-4-1106-preview', + 'gateway/openai:gpt-4-32k', + 'gateway/openai:gpt-4-32k-0314', + 'gateway/openai:gpt-4-32k-0613', + 'gateway/openai:gpt-4-turbo', + 'gateway/openai:gpt-4-turbo-2024-04-09', + 'gateway/openai:gpt-4-turbo-preview', + 'gateway/openai:gpt-4-vision-preview', + 'gateway/openai:gpt-4.1', + 'gateway/openai:gpt-4.1-2025-04-14', + 'gateway/openai:gpt-4.1-mini', + 'gateway/openai:gpt-4.1-mini-2025-04-14', + 'gateway/openai:gpt-4.1-nano', + 'gateway/openai:gpt-4.1-nano-2025-04-14', + 'gateway/openai:gpt-4o', + 'gateway/openai:gpt-4o-2024-05-13', + 'gateway/openai:gpt-4o-2024-08-06', + 'gateway/openai:gpt-4o-2024-11-20', + 'gateway/openai:gpt-4o-audio-preview', + 'gateway/openai:gpt-4o-audio-preview-2024-10-01', + 'gateway/openai:gpt-4o-audio-preview-2024-12-17', + 'gateway/openai:gpt-4o-audio-preview-2025-06-03', + 'gateway/openai:gpt-4o-mini', + 'gateway/openai:gpt-4o-mini-2024-07-18', + 'gateway/openai:gpt-4o-mini-audio-preview', + 'gateway/openai:gpt-4o-mini-audio-preview-2024-12-17', + 'gateway/openai:gpt-4o-mini-search-preview', + 'gateway/openai:gpt-4o-mini-search-preview-2025-03-11', + 'gateway/openai:gpt-4o-search-preview', + 'gateway/openai:gpt-4o-search-preview-2025-03-11', + 'gateway/openai:gpt-5', + 'gateway/openai:gpt-5-2025-08-07', + 'gateway/openai:gpt-5-chat-latest', + 'gateway/openai:gpt-5-codex', + 'gateway/openai:gpt-5-mini', + 'gateway/openai:gpt-5-mini-2025-08-07', + 'gateway/openai:gpt-5-nano', + 'gateway/openai:gpt-5-nano-2025-08-07', + 'gateway/openai:gpt-5-pro', + 'gateway/openai:gpt-5-pro-2025-10-06', + 'gateway/openai:gpt-5.1', + 'gateway/openai:gpt-5.1-2025-11-13', + 'gateway/openai:gpt-5.1-chat-latest', + 'gateway/openai:gpt-5.1-codex', + 'gateway/openai:gpt-5.1-mini', + 'gateway/openai:o1', + 'gateway/openai:o1-2024-12-17', + 'gateway/openai:o1-mini', + 'gateway/openai:o1-mini-2024-09-12', + 'gateway/openai:o1-preview', + 'gateway/openai:o1-preview-2024-09-12', + 'gateway/openai:o1-pro', + 'gateway/openai:o1-pro-2025-03-19', + 'gateway/openai:o3', + 'gateway/openai:o3-2025-04-16', + 'gateway/openai:o3-deep-research', + 'gateway/openai:o3-deep-research-2025-06-26', + 'gateway/openai:o3-mini', + 'gateway/openai:o3-mini-2025-01-31', + 'gateway/openai:o3-pro', + 'gateway/openai:o3-pro-2025-06-10', + 'gateway/openai:o4-mini', + 'gateway/openai:o4-mini-2025-04-16', + 'gateway/openai:o4-mini-deep-research', + 'gateway/openai:o4-mini-deep-research-2025-06-26', 'google-gla:gemini-flash-latest', 'google-gla:gemini-flash-lite-latest', 'google-gla:gemini-2.0-flash', diff --git a/pydantic_ai_slim/pydantic_ai/providers/gateway.py b/pydantic_ai_slim/pydantic_ai/providers/gateway.py index bc29606799..6eab55bcaa 100644 --- a/pydantic_ai_slim/pydantic_ai/providers/gateway.py +++ b/pydantic_ai_slim/pydantic_ai/providers/gateway.py @@ -3,7 +3,7 @@ from __future__ import annotations as _annotations import os -from collections.abc import Awaitable, Callable +from collections.abc import Awaitable, Callable, Mapping from typing import TYPE_CHECKING, Any, Literal, overload import httpx @@ -93,13 +93,38 @@ def gateway_provider( ) -> Provider[Any]: ... -UpstreamProvider = Literal[ +ModelProviders = Literal[ 'openai', 'groq', 'anthropic', 'bedrock', 'google-vertex', - # Those are only API formats, but we still support them for convenience. +] + + +def gateway_provider_to_model_names() -> Mapping[ModelProviders, object]: + """Get the gateway model name for a given provider. + + Args: + provider: The provider to get the model name for. + """ + from pydantic_ai.models.anthropic import AnthropicModelName + from pydantic_ai.models.bedrock import BedrockModelName + from pydantic_ai.models.google import GoogleModelName + from pydantic_ai.models.groq import GroqModelName + from pydantic_ai.models.openai import OpenAIModelName + + return { + 'openai': OpenAIModelName, + 'groq': GroqModelName, + 'anthropic': AnthropicModelName, + 'bedrock': BedrockModelName, + 'google-vertex': GoogleModelName, + } + + +# These are only API formats, but we still support them for convenience. +ApiFormatProviders = Literal[ 'openai-chat', 'openai-responses', 'chat', @@ -108,6 +133,8 @@ def gateway_provider( 'gemini', ] +UpstreamProvider = ModelProviders | ApiFormatProviders + def gateway_provider( upstream_provider: UpstreamProvider | str, diff --git a/tests/models/test_model_names.py b/tests/models/test_model_names.py index 058ffe28c7..72cf99c50f 100644 --- a/tests/models/test_model_names.py +++ b/tests/models/test_model_names.py @@ -20,6 +20,7 @@ from pydantic_ai.models.huggingface import HuggingFaceModelName from pydantic_ai.models.mistral import MistralModelName from pydantic_ai.models.openai import OpenAIModelName + from pydantic_ai.providers.gateway import gateway_provider_to_model_names from pydantic_ai.providers.grok import GrokModelName from pydantic_ai.providers.moonshotai import MoonshotAIModelName @@ -70,6 +71,11 @@ def get_model_names(model_name_type: Any) -> Iterator[str]: openai_names = [f'openai:{n}' for n in get_model_names(OpenAIModelName)] bedrock_names = [f'bedrock:{n}' for n in get_model_names(BedrockModelName)] deepseek_names = ['deepseek:deepseek-chat', 'deepseek:deepseek-reasoner'] + gateway_names = [ + f'gateway/{provider}:{model_name}' + for provider, model_names in gateway_provider_to_model_names().items() + for model_name in get_model_names(model_names) + ] huggingface_names = [f'huggingface:{n}' for n in get_model_names(HuggingFaceModelName)] heroku_names = get_heroku_model_names() cerebras_names = get_cerebras_model_names() @@ -86,6 +92,7 @@ def get_model_names(model_name_type: Any) -> Iterator[str]: + openai_names + bedrock_names + deepseek_names + + gateway_names + huggingface_names + heroku_names + cerebras_names diff --git a/tests/test_cli.py b/tests/test_cli.py index e95ff09141..3a76c71102 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -144,6 +144,7 @@ def test_list_models(capfd: CaptureFixture[str]): 'mistral', 'cohere', 'deepseek', + 'gateway/', 'heroku', 'moonshotai', 'grok',