Repository: pydantic/pydantic-ai
File: pydantic_ai_slim/pydantic_ai/providers/gateway.py (Python)

Code before:
    base_url: str | None = None,
) -> Provider[Any]: ...


ModelProviders = Literal[
    'openai',
    'groq',
    'anthropic',
    'bedrock',
    'google-vertex',
]


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',
    'responses',
    'converse',
    'gemini',
]

UpstreamProvider = ModelProviders | ApiFormatProviders


def gateway_provider(
    upstream_provider: UpstreamProvider | str,
    /,
    *,

Review comment (refactor):
Let's move this mapping to `test_model_names.py` so that the `get_model_names` used there can also take a provider name.

Then `[f'grok:{n}' for n in get_model_names(GrokModelName)]` could become `[f'grok:{n}' for n in get_model_names('grok')]`, or `prefixed_model_names('grok')`. And then if we have the complete dict, we can basically just to `model_names = [prefixed_model_names(provider) for provider in provider_model_names.keys()]` or something like that. 

Basically clean up all this duplication:

```py
anthropic_names = [f'anthropic:{n}' for n in get_model_names(AnthropicModelName)]
    cohere_names = [f'cohere:{n}' for n in get_model_names(CohereModelName)]
    google_names = [f'google-gla:{n}' for n in get_model_names(GoogleModelName)] + [
        f'google-vertex:{n}' for n in get_model_names(GoogleModelName)
    ]
    grok_names = [f'grok:{n}' for n in get_model_names(GrokModelName)]
    groq_names = [f'groq:{n}' for n in get_model_names(GroqModelName)]
    moonshotai_names = [f'moonshotai:{n}' for n in get_model_names(MoonshotAIModelName)]
    mistral_names = [f'mistral:{n}' for n in get_model_names(MistralModelName)]
    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)]
```

By having just a dict of provider names to model name types (or functions like in the case of `get_heroku_model_names`)

Code after:
    base_url: str | None = None,
) -> Provider[Any]: ...


ModelProvider = Literal[
    'openai',
    'groq',
    'anthropic',
    'bedrock',
    'google-vertex',
]


# These are only API flavors, we support them for convenience.
APIFlavor = Literal[
    'openai-chat',
    'openai-responses',
    'chat',
    'responses',
    'converse',
    'gemini',
]

UpstreamProvider = ModelProvider | APIFlavor


def gateway_provider(
    upstream_provider: UpstreamProvider | str,
    /,
    *,
    # Every provider
    route: str | None = None,
    api_key: str | None = None,
    base_url: str | None = None,
    # OpenAI, Groq, Anthropic & Gemini - Only Bedrock doesn't have an HTTPX client.
    http_client: httpx.AsyncClient | None = None,
) -> Provider[Any]:
    """Create a new Gateway provider.

    Args:
        upstream_provider: The upstream provider to use.
        route: The name of the provider or routing group to use to handle the request. If not provided, the default
            routing group for the API format will be used.
        api_key: The API key to use for authentication. If not provided, the `PYDANTIC_AI_GATEWAY_API_KEY`
            environment variable will be used if available.
        base_url: The base URL to use for the Gateway. If not provided, the `PYDANTIC_AI_GATEWAY_BASE_URL`
            environment variable will be used if available. Otherwise, defaults to `https://gateway.pydantic.dev/proxy`.
        http_client: The HTTP client to use for the Gateway.
    """
    api_key = api_key or os.getenv('PYDANTIC_AI_GATEWAY_API_KEY', os.getenv('PAIG_API_KEY'))
    if not api_key: