"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from .basesdk import BaseSDK
from enum import Enum
from openrouter import components, errors, operations, utils
from openrouter._hooks import HookContext
from openrouter.types import OptionalNullable, UNSET
from openrouter.utils import eventstreaming, get_security_from_env
from openrouter.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, Dict, List, Literal, Mapping, Optional, Union, overload


class SendAcceptEnum(str, Enum):
    APPLICATION_JSON = "application/json"
    TEXT_EVENT_STREAM = "text/event-stream"


class Chat(BaseSDK):
    @overload
    def send(
        self,
        *,
        messages: Union[
            List[components.ChatMessages], List[components.ChatMessagesTypedDict]
        ],
        http_referer: Optional[str] = None,
        x_open_router_title: Optional[str] = None,
        x_open_router_categories: Optional[str] = None,
        x_open_router_metadata: Optional[components.MetadataLevel] = None,
        cache_control: Optional[
            Union[
                components.AnthropicCacheControlDirective,
                components.AnthropicCacheControlDirectiveTypedDict,
            ]
        ] = None,
        debug: Optional[
            Union[components.ChatDebugOptions, components.ChatDebugOptionsTypedDict]
        ] = None,
        frequency_penalty: OptionalNullable[float] = UNSET,
        image_config: Optional[
            Union[
                Dict[str, components.ImageConfig],
                Dict[str, components.ImageConfigTypedDict],
            ]
        ] = None,
        logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
        logprobs: OptionalNullable[bool] = UNSET,
        max_completion_tokens: OptionalNullable[int] = UNSET,
        max_tokens: OptionalNullable[int] = UNSET,
        metadata: Optional[Dict[str, str]] = None,
        min_p: OptionalNullable[float] = UNSET,
        modalities: Optional[List[components.Modality]] = None,
        model: Optional[str] = None,
        models: Optional[List[str]] = None,
        parallel_tool_calls: OptionalNullable[bool] = UNSET,
        plugins: Optional[
            Union[
                List[components.ChatRequestPlugin],
                List[components.ChatRequestPluginTypedDict],
            ]
        ] = None,
        presence_penalty: OptionalNullable[float] = UNSET,
        provider: OptionalNullable[
            Union[
                components.ProviderPreferences, components.ProviderPreferencesTypedDict
            ]
        ] = UNSET,
        reasoning: Optional[
            Union[
                components.ChatRequestReasoning,
                components.ChatRequestReasoningTypedDict,
            ]
        ] = None,
        reasoning_effort: OptionalNullable[
            components.ChatRequestReasoningEffort
        ] = UNSET,
        repetition_penalty: OptionalNullable[float] = UNSET,
        response_format: Optional[
            Union[components.ResponseFormat, components.ResponseFormatTypedDict]
        ] = None,
        seed: OptionalNullable[int] = UNSET,
        service_tier: OptionalNullable[components.ChatRequestServiceTier] = UNSET,
        session_id: Optional[str] = None,
        stop: OptionalNullable[
            Union[components.Stop, components.StopTypedDict]
        ] = UNSET,
        stop_server_tools_when: Optional[
            Union[
                List[components.StopServerToolsWhenCondition],
                List[components.StopServerToolsWhenConditionTypedDict],
            ]
        ] = None,
        stream: Union[Literal[False], None] = None,
        stream_options: OptionalNullable[
            Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
        ] = UNSET,
        temperature: OptionalNullable[float] = UNSET,
        tool_choice: Optional[
            Union[components.ChatToolChoice, components.ChatToolChoiceTypedDict]
        ] = None,
        tools: Optional[
            Union[
                List[components.ChatFunctionTool],
                List[components.ChatFunctionToolTypedDict],
            ]
        ] = None,
        top_a: OptionalNullable[float] = UNSET,
        top_k: OptionalNullable[int] = UNSET,
        top_logprobs: OptionalNullable[int] = UNSET,
        top_p: OptionalNullable[float] = UNSET,
        trace: Optional[
            Union[components.TraceConfig, components.TraceConfigTypedDict]
        ] = None,
        user: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> components.ChatResult:
        r"""Create a chat completion

        Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.

        :param messages: List of messages for the conversation
        :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
            This is used to track API usage per application.

        :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.

        :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.

        :param x_open_router_metadata: Opt-in to surface routing metadata on the response under `openrouter_metadata`. Defaults to `disabled`. The legacy header `X-OpenRouter-Experimental-Metadata` is also accepted for backward compatibility.
        :param cache_control: Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models.
        :param debug: Debug options for inspecting request transformations (streaming only)
        :param frequency_penalty: Frequency penalty (-2.0 to 2.0)
        :param image_config: Provider-specific image configuration options. Keys and values vary by model/provider. See https://openrouter.ai/docs/guides/overview/multimodal/image-generation for more details.
        :param logit_bias: Token logit bias adjustments
        :param logprobs: Return log probabilities
        :param max_completion_tokens: Maximum tokens in completion
        :param max_tokens: Maximum tokens (deprecated, use max_completion_tokens). Note: some providers enforce a minimum of 16.
        :param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
        :param min_p: Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter.
        :param modalities: Output modalities for the response. Supported values are \"text\", \"image\", and \"audio\".
        :param model: Model to use for completion
        :param models: Models to use for completion
        :param parallel_tool_calls: Whether to enable parallel function calling during tool use. When true, the model may generate multiple tool calls in a single response.
        :param plugins: Plugins you want to enable for this request, including their settings.
        :param presence_penalty: Presence penalty (-2.0 to 2.0)
        :param provider: When multiple model providers are available, optionally indicate your routing preference.
        :param reasoning: Configuration options for reasoning models
        :param reasoning_effort: Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ.
        :param repetition_penalty: Penalizes tokens based on how much they have already appeared in the text. A value of 1.0 means no penalty. Values above 1.0 penalize repeated tokens more strongly. Not all providers support this parameter.
        :param response_format: Response format configuration
        :param seed: Random seed for deterministic outputs
        :param service_tier: The service tier to use for processing this request.
        :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). When provided, OpenRouter uses it as the sticky routing key, routing all requests in the session to the same provider to maximize prompt cache hits. Also used for observability grouping. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
        :param stop: Stop sequences (up to 4)
        :param stop_server_tools_when: Stop conditions for the server-tool agent loop. Any condition firing halts the loop (OR logic). When set, this overrides `max_tool_calls`.
        :param stream: Enable streaming response
        :param stream_options: Streaming configuration options
        :param temperature: Sampling temperature (0-2)
        :param tool_choice: Tool choice configuration
        :param tools: Available tools for function calling
        :param top_a: Consider only tokens with \"sufficiently high\" probabilities based on the probability of the most likely token. Not all providers support this parameter.
        :param top_k: Limits the model to choose from the top K most likely tokens at each step. A value of 1 means the model will always pick the most likely next token. Not all providers support this parameter.
        :param top_logprobs: Number of top log probabilities to return (0-20)
        :param top_p: Nucleus sampling parameter (0-1)
        :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
        :param user: Unique user identifier
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """

    @overload
    def send(
        self,
        *,
        messages: Union[
            List[components.ChatMessages], List[components.ChatMessagesTypedDict]
        ],
        http_referer: Optional[str] = None,
        x_open_router_title: Optional[str] = None,
        x_open_router_categories: Optional[str] = None,
        x_open_router_metadata: Optional[components.MetadataLevel] = None,
        cache_control: Optional[
            Union[
                components.AnthropicCacheControlDirective,
                components.AnthropicCacheControlDirectiveTypedDict,
            ]
        ] = None,
        debug: Optional[
            Union[components.ChatDebugOptions, components.ChatDebugOptionsTypedDict]
        ] = None,
        frequency_penalty: OptionalNullable[float] = UNSET,
        image_config: Optional[
            Union[
                Dict[str, components.ImageConfig],
                Dict[str, components.ImageConfigTypedDict],
            ]
        ] = None,
        logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
        logprobs: OptionalNullable[bool] = UNSET,
        max_completion_tokens: OptionalNullable[int] = UNSET,
        max_tokens: OptionalNullable[int] = UNSET,
        metadata: Optional[Dict[str, str]] = None,
        min_p: OptionalNullable[float] = UNSET,
        modalities: Optional[List[components.Modality]] = None,
        model: Optional[str] = None,
        models: Optional[List[str]] = None,
        parallel_tool_calls: OptionalNullable[bool] = UNSET,
        plugins: Optional[
            Union[
                List[components.ChatRequestPlugin],
                List[components.ChatRequestPluginTypedDict],
            ]
        ] = None,
        presence_penalty: OptionalNullable[float] = UNSET,
        provider: OptionalNullable[
            Union[
                components.ProviderPreferences, components.ProviderPreferencesTypedDict
            ]
        ] = UNSET,
        reasoning: Optional[
            Union[
                components.ChatRequestReasoning,
                components.ChatRequestReasoningTypedDict,
            ]
        ] = None,
        reasoning_effort: OptionalNullable[
            components.ChatRequestReasoningEffort
        ] = UNSET,
        repetition_penalty: OptionalNullable[float] = UNSET,
        response_format: Optional[
            Union[components.ResponseFormat, components.ResponseFormatTypedDict]
        ] = None,
        seed: OptionalNullable[int] = UNSET,
        service_tier: OptionalNullable[components.ChatRequestServiceTier] = UNSET,
        session_id: Optional[str] = None,
        stop: OptionalNullable[
            Union[components.Stop, components.StopTypedDict]
        ] = UNSET,
        stop_server_tools_when: Optional[
            Union[
                List[components.StopServerToolsWhenCondition],
                List[components.StopServerToolsWhenConditionTypedDict],
            ]
        ] = None,
        stream: Literal[True],
        stream_options: OptionalNullable[
            Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
        ] = UNSET,
        temperature: OptionalNullable[float] = UNSET,
        tool_choice: Optional[
            Union[components.ChatToolChoice, components.ChatToolChoiceTypedDict]
        ] = None,
        tools: Optional[
            Union[
                List[components.ChatFunctionTool],
                List[components.ChatFunctionToolTypedDict],
            ]
        ] = None,
        top_a: OptionalNullable[float] = UNSET,
        top_k: OptionalNullable[int] = UNSET,
        top_logprobs: OptionalNullable[int] = UNSET,
        top_p: OptionalNullable[float] = UNSET,
        trace: Optional[
            Union[components.TraceConfig, components.TraceConfigTypedDict]
        ] = None,
        user: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> eventstreaming.EventStream[components.ChatStreamChunk]:
        r"""Create a chat completion

        Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.

        :param messages: List of messages for the conversation
        :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
            This is used to track API usage per application.

        :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.

        :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.

        :param x_open_router_metadata: Opt-in to surface routing metadata on the response under `openrouter_metadata`. Defaults to `disabled`. The legacy header `X-OpenRouter-Experimental-Metadata` is also accepted for backward compatibility.
        :param cache_control: Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models.
        :param debug: Debug options for inspecting request transformations (streaming only)
        :param frequency_penalty: Frequency penalty (-2.0 to 2.0)
        :param image_config: Provider-specific image configuration options. Keys and values vary by model/provider. See https://openrouter.ai/docs/guides/overview/multimodal/image-generation for more details.
        :param logit_bias: Token logit bias adjustments
        :param logprobs: Return log probabilities
        :param max_completion_tokens: Maximum tokens in completion
        :param max_tokens: Maximum tokens (deprecated, use max_completion_tokens). Note: some providers enforce a minimum of 16.
        :param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
        :param min_p: Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter.
        :param modalities: Output modalities for the response. Supported values are \"text\", \"image\", and \"audio\".
        :param model: Model to use for completion
        :param models: Models to use for completion
        :param parallel_tool_calls: Whether to enable parallel function calling during tool use. When true, the model may generate multiple tool calls in a single response.
        :param plugins: Plugins you want to enable for this request, including their settings.
        :param presence_penalty: Presence penalty (-2.0 to 2.0)
        :param provider: When multiple model providers are available, optionally indicate your routing preference.
        :param reasoning: Configuration options for reasoning models
        :param reasoning_effort: Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ.
        :param repetition_penalty: Penalizes tokens based on how much they have already appeared in the text. A value of 1.0 means no penalty. Values above 1.0 penalize repeated tokens more strongly. Not all providers support this parameter.
        :param response_format: Response format configuration
        :param seed: Random seed for deterministic outputs
        :param service_tier: The service tier to use for processing this request.
        :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). When provided, OpenRouter uses it as the sticky routing key, routing all requests in the session to the same provider to maximize prompt cache hits. Also used for observability grouping. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
        :param stop: Stop sequences (up to 4)
        :param stop_server_tools_when: Stop conditions for the server-tool agent loop. Any condition firing halts the loop (OR logic). When set, this overrides `max_tool_calls`.
        :param stream: Enable streaming response
        :param stream_options: Streaming configuration options
        :param temperature: Sampling temperature (0-2)
        :param tool_choice: Tool choice configuration
        :param tools: Available tools for function calling
        :param top_a: Consider only tokens with \"sufficiently high\" probabilities based on the probability of the most likely token. Not all providers support this parameter.
        :param top_k: Limits the model to choose from the top K most likely tokens at each step. A value of 1 means the model will always pick the most likely next token. Not all providers support this parameter.
        :param top_logprobs: Number of top log probabilities to return (0-20)
        :param top_p: Nucleus sampling parameter (0-1)
        :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
        :param user: Unique user identifier
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """

    def send(
        self,
        *,
        messages: Union[
            List[components.ChatMessages], List[components.ChatMessagesTypedDict]
        ],
        http_referer: Optional[str] = None,
        x_open_router_title: Optional[str] = None,
        x_open_router_categories: Optional[str] = None,
        x_open_router_metadata: Optional[components.MetadataLevel] = None,
        cache_control: Optional[
            Union[
                components.AnthropicCacheControlDirective,
                components.AnthropicCacheControlDirectiveTypedDict,
            ]
        ] = None,
        debug: Optional[
            Union[components.ChatDebugOptions, components.ChatDebugOptionsTypedDict]
        ] = None,
        frequency_penalty: OptionalNullable[float] = UNSET,
        image_config: Optional[
            Union[
                Dict[str, components.ImageConfig],
                Dict[str, components.ImageConfigTypedDict],
            ]
        ] = None,
        logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
        logprobs: OptionalNullable[bool] = UNSET,
        max_completion_tokens: OptionalNullable[int] = UNSET,
        max_tokens: OptionalNullable[int] = UNSET,
        metadata: Optional[Dict[str, str]] = None,
        min_p: OptionalNullable[float] = UNSET,
        modalities: Optional[List[components.Modality]] = None,
        model: Optional[str] = None,
        models: Optional[List[str]] = None,
        parallel_tool_calls: OptionalNullable[bool] = UNSET,
        plugins: Optional[
            Union[
                List[components.ChatRequestPlugin],
                List[components.ChatRequestPluginTypedDict],
            ]
        ] = None,
        presence_penalty: OptionalNullable[float] = UNSET,
        provider: OptionalNullable[
            Union[
                components.ProviderPreferences, components.ProviderPreferencesTypedDict
            ]
        ] = UNSET,
        reasoning: Optional[
            Union[
                components.ChatRequestReasoning,
                components.ChatRequestReasoningTypedDict,
            ]
        ] = None,
        reasoning_effort: OptionalNullable[
            components.ChatRequestReasoningEffort
        ] = UNSET,
        repetition_penalty: OptionalNullable[float] = UNSET,
        response_format: Optional[
            Union[components.ResponseFormat, components.ResponseFormatTypedDict]
        ] = None,
        seed: OptionalNullable[int] = UNSET,
        service_tier: OptionalNullable[components.ChatRequestServiceTier] = UNSET,
        session_id: Optional[str] = None,
        stop: OptionalNullable[
            Union[components.Stop, components.StopTypedDict]
        ] = UNSET,
        stop_server_tools_when: Optional[
            Union[
                List[components.StopServerToolsWhenCondition],
                List[components.StopServerToolsWhenConditionTypedDict],
            ]
        ] = None,
        stream: Optional[bool] = False,
        stream_options: OptionalNullable[
            Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
        ] = UNSET,
        temperature: OptionalNullable[float] = UNSET,
        tool_choice: Optional[
            Union[components.ChatToolChoice, components.ChatToolChoiceTypedDict]
        ] = None,
        tools: Optional[
            Union[
                List[components.ChatFunctionTool],
                List[components.ChatFunctionToolTypedDict],
            ]
        ] = None,
        top_a: OptionalNullable[float] = UNSET,
        top_k: OptionalNullable[int] = UNSET,
        top_logprobs: OptionalNullable[int] = UNSET,
        top_p: OptionalNullable[float] = UNSET,
        trace: Optional[
            Union[components.TraceConfig, components.TraceConfigTypedDict]
        ] = None,
        user: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.SendChatCompletionRequestResponse:
        r"""Create a chat completion

        Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.

        :param messages: List of messages for the conversation
        :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
            This is used to track API usage per application.

        :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.

        :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.

        :param x_open_router_metadata: Opt-in to surface routing metadata on the response under `openrouter_metadata`. Defaults to `disabled`. The legacy header `X-OpenRouter-Experimental-Metadata` is also accepted for backward compatibility.
        :param cache_control: Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models.
        :param debug: Debug options for inspecting request transformations (streaming only)
        :param frequency_penalty: Frequency penalty (-2.0 to 2.0)
        :param image_config: Provider-specific image configuration options. Keys and values vary by model/provider. See https://openrouter.ai/docs/guides/overview/multimodal/image-generation for more details.
        :param logit_bias: Token logit bias adjustments
        :param logprobs: Return log probabilities
        :param max_completion_tokens: Maximum tokens in completion
        :param max_tokens: Maximum tokens (deprecated, use max_completion_tokens). Note: some providers enforce a minimum of 16.
        :param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
        :param min_p: Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter.
        :param modalities: Output modalities for the response. Supported values are \"text\", \"image\", and \"audio\".
        :param model: Model to use for completion
        :param models: Models to use for completion
        :param parallel_tool_calls: Whether to enable parallel function calling during tool use. When true, the model may generate multiple tool calls in a single response.
        :param plugins: Plugins you want to enable for this request, including their settings.
        :param presence_penalty: Presence penalty (-2.0 to 2.0)
        :param provider: When multiple model providers are available, optionally indicate your routing preference.
        :param reasoning: Configuration options for reasoning models
        :param reasoning_effort: Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ.
        :param repetition_penalty: Penalizes tokens based on how much they have already appeared in the text. A value of 1.0 means no penalty. Values above 1.0 penalize repeated tokens more strongly. Not all providers support this parameter.
        :param response_format: Response format configuration
        :param seed: Random seed for deterministic outputs
        :param service_tier: The service tier to use for processing this request.
        :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). When provided, OpenRouter uses it as the sticky routing key, routing all requests in the session to the same provider to maximize prompt cache hits. Also used for observability grouping. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
        :param stop: Stop sequences (up to 4)
        :param stop_server_tools_when: Stop conditions for the server-tool agent loop. Any condition firing halts the loop (OR logic). When set, this overrides `max_tool_calls`.
        :param stream: Enable streaming response
        :param stream_options: Streaming configuration options
        :param temperature: Sampling temperature (0-2)
        :param tool_choice: Tool choice configuration
        :param tools: Available tools for function calling
        :param top_a: Consider only tokens with \"sufficiently high\" probabilities based on the probability of the most likely token. Not all providers support this parameter.
        :param top_k: Limits the model to choose from the top K most likely tokens at each step. A value of 1 means the model will always pick the most likely next token. Not all providers support this parameter.
        :param top_logprobs: Number of top log probabilities to return (0-20)
        :param top_p: Nucleus sampling parameter (0-1)
        :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
        :param user: Unique user identifier
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = operations.SendChatCompletionRequestRequest(
            http_referer=http_referer,
            x_open_router_title=x_open_router_title,
            x_open_router_categories=x_open_router_categories,
            x_open_router_metadata=x_open_router_metadata,
            chat_request=components.ChatRequest(
                cache_control=utils.get_pydantic_model(
                    cache_control, Optional[components.AnthropicCacheControlDirective]
                ),
                debug=utils.get_pydantic_model(
                    debug, Optional[components.ChatDebugOptions]
                ),
                frequency_penalty=frequency_penalty,
                image_config=image_config,
                logit_bias=logit_bias,
                logprobs=logprobs,
                max_completion_tokens=max_completion_tokens,
                max_tokens=max_tokens,
                messages=utils.get_pydantic_model(
                    messages, List[components.ChatMessages]
                ),
                metadata=metadata,
                min_p=min_p,
                modalities=modalities,
                model=model,
                models=models,
                parallel_tool_calls=parallel_tool_calls,
                plugins=utils.get_pydantic_model(
                    plugins, Optional[List[components.ChatRequestPlugin]]
                ),
                presence_penalty=presence_penalty,
                provider=utils.get_pydantic_model(
                    provider, OptionalNullable[components.ProviderPreferences]
                ),
                reasoning=utils.get_pydantic_model(
                    reasoning, Optional[components.ChatRequestReasoning]
                ),
                reasoning_effort=reasoning_effort,
                repetition_penalty=repetition_penalty,
                response_format=utils.get_pydantic_model(
                    response_format, Optional[components.ResponseFormat]
                ),
                seed=seed,
                service_tier=service_tier,
                session_id=session_id,
                stop=stop,
                stop_server_tools_when=utils.get_pydantic_model(
                    stop_server_tools_when,
                    Optional[List[components.StopServerToolsWhenCondition]],
                ),
                stream=stream,
                stream_options=utils.get_pydantic_model(
                    stream_options, OptionalNullable[components.ChatStreamOptions]
                ),
                temperature=temperature,
                tool_choice=utils.get_pydantic_model(
                    tool_choice, Optional[components.ChatToolChoice]
                ),
                tools=utils.get_pydantic_model(
                    tools, Optional[List[components.ChatFunctionTool]]
                ),
                top_a=top_a,
                top_k=top_k,
                top_logprobs=top_logprobs,
                top_p=top_p,
                trace=utils.get_pydantic_model(trace, Optional[components.TraceConfig]),
                user=user,
            ),
        )

        req = self._build_request(
            method="POST",
            path="/chat/completions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="text/event-stream" if stream else "application/json",
            http_headers=http_headers,
            _globals=operations.SendChatCompletionRequestGlobals(
                http_referer=self.sdk_configuration.globals.http_referer,
                x_open_router_title=self.sdk_configuration.globals.x_open_router_title,
                x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.chat_request, False, False, "json", components.ChatRequest
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="sendChatCompletionRequest",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "402",
                "403",
                "404",
                "408",
                "413",
                "422",
                "429",
                "4XX",
                "500",
                "502",
                "503",
                "524",
                "529",
                "5XX",
            ],
            stream=True,
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            return unmarshal_json_response(
                components.ChatResult, http_res, http_res_text
            )
        if utils.match_response(http_res, "200", "text/event-stream"):
            return eventstreaming.EventStream(
                http_res,
                lambda raw: utils.unmarshal_json(
                    raw, components.ChatStreamingResponse
                ).data,
                sentinel="[DONE]",
                client_ref=self,
            )
        if utils.match_response(http_res, "400", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.BadRequestResponseErrorData, http_res, http_res_text
            )
            raise errors.BadRequestResponseError(response_data, http_res, http_res_text)
        if utils.match_response(http_res, "401", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.UnauthorizedResponseErrorData, http_res, http_res_text
            )
            raise errors.UnauthorizedResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "402", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.PaymentRequiredResponseErrorData, http_res, http_res_text
            )
            raise errors.PaymentRequiredResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "403", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.ForbiddenResponseErrorData, http_res, http_res_text
            )
            raise errors.ForbiddenResponseError(response_data, http_res, http_res_text)
        if utils.match_response(http_res, "404", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.NotFoundResponseErrorData, http_res, http_res_text
            )
            raise errors.NotFoundResponseError(response_data, http_res, http_res_text)
        if utils.match_response(http_res, "408", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.RequestTimeoutResponseErrorData, http_res, http_res_text
            )
            raise errors.RequestTimeoutResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "413", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.PayloadTooLargeResponseErrorData, http_res, http_res_text
            )
            raise errors.PayloadTooLargeResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "422", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.UnprocessableEntityResponseErrorData, http_res, http_res_text
            )
            raise errors.UnprocessableEntityResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "429", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.TooManyRequestsResponseErrorData, http_res, http_res_text
            )
            raise errors.TooManyRequestsResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "500", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.InternalServerResponseErrorData, http_res, http_res_text
            )
            raise errors.InternalServerResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "502", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.BadGatewayResponseErrorData, http_res, http_res_text
            )
            raise errors.BadGatewayResponseError(response_data, http_res, http_res_text)
        if utils.match_response(http_res, "503", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.ServiceUnavailableResponseErrorData, http_res, http_res_text
            )
            raise errors.ServiceUnavailableResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "524", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.EdgeNetworkTimeoutResponseErrorData, http_res, http_res_text
            )
            raise errors.EdgeNetworkTimeoutResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "529", "application/json"):
            http_res_text = utils.stream_to_text(http_res)
            response_data = unmarshal_json_response(
                errors.ProviderOverloadedResponseErrorData, http_res, http_res_text
            )
            raise errors.ProviderOverloadedResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.OpenRouterDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.OpenRouterDefaultError(
                "API error occurred", http_res, http_res_text
            )

        http_res_text = utils.stream_to_text(http_res)
        raise errors.OpenRouterDefaultError(
            "Unexpected response received", http_res, http_res_text
        )

    @overload
    async def send_async(
        self,
        *,
        messages: Union[
            List[components.ChatMessages], List[components.ChatMessagesTypedDict]
        ],
        http_referer: Optional[str] = None,
        x_open_router_title: Optional[str] = None,
        x_open_router_categories: Optional[str] = None,
        x_open_router_metadata: Optional[components.MetadataLevel] = None,
        cache_control: Optional[
            Union[
                components.AnthropicCacheControlDirective,
                components.AnthropicCacheControlDirectiveTypedDict,
            ]
        ] = None,
        debug: Optional[
            Union[components.ChatDebugOptions, components.ChatDebugOptionsTypedDict]
        ] = None,
        frequency_penalty: OptionalNullable[float] = UNSET,
        image_config: Optional[
            Union[
                Dict[str, components.ImageConfig],
                Dict[str, components.ImageConfigTypedDict],
            ]
        ] = None,
        logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
        logprobs: OptionalNullable[bool] = UNSET,
        max_completion_tokens: OptionalNullable[int] = UNSET,
        max_tokens: OptionalNullable[int] = UNSET,
        metadata: Optional[Dict[str, str]] = None,
        min_p: OptionalNullable[float] = UNSET,
        modalities: Optional[List[components.Modality]] = None,
        model: Optional[str] = None,
        models: Optional[List[str]] = None,
        parallel_tool_calls: OptionalNullable[bool] = UNSET,
        plugins: Optional[
            Union[
                List[components.ChatRequestPlugin],
                List[components.ChatRequestPluginTypedDict],
            ]
        ] = None,
        presence_penalty: OptionalNullable[float] = UNSET,
        provider: OptionalNullable[
            Union[
                components.ProviderPreferences, components.ProviderPreferencesTypedDict
            ]
        ] = UNSET,
        reasoning: Optional[
            Union[
                components.ChatRequestReasoning,
                components.ChatRequestReasoningTypedDict,
            ]
        ] = None,
        reasoning_effort: OptionalNullable[
            components.ChatRequestReasoningEffort
        ] = UNSET,
        repetition_penalty: OptionalNullable[float] = UNSET,
        response_format: Optional[
            Union[components.ResponseFormat, components.ResponseFormatTypedDict]
        ] = None,
        seed: OptionalNullable[int] = UNSET,
        service_tier: OptionalNullable[components.ChatRequestServiceTier] = UNSET,
        session_id: Optional[str] = None,
        stop: OptionalNullable[
            Union[components.Stop, components.StopTypedDict]
        ] = UNSET,
        stop_server_tools_when: Optional[
            Union[
                List[components.StopServerToolsWhenCondition],
                List[components.StopServerToolsWhenConditionTypedDict],
            ]
        ] = None,
        stream: Union[Literal[False], None] = None,
        stream_options: OptionalNullable[
            Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
        ] = UNSET,
        temperature: OptionalNullable[float] = UNSET,
        tool_choice: Optional[
            Union[components.ChatToolChoice, components.ChatToolChoiceTypedDict]
        ] = None,
        tools: Optional[
            Union[
                List[components.ChatFunctionTool],
                List[components.ChatFunctionToolTypedDict],
            ]
        ] = None,
        top_a: OptionalNullable[float] = UNSET,
        top_k: OptionalNullable[int] = UNSET,
        top_logprobs: OptionalNullable[int] = UNSET,
        top_p: OptionalNullable[float] = UNSET,
        trace: Optional[
            Union[components.TraceConfig, components.TraceConfigTypedDict]
        ] = None,
        user: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> components.ChatResult:
        r"""Create a chat completion

        Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.

        :param messages: List of messages for the conversation
        :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
            This is used to track API usage per application.

        :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.

        :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.

        :param x_open_router_metadata: Opt-in to surface routing metadata on the response under `openrouter_metadata`. Defaults to `disabled`. The legacy header `X-OpenRouter-Experimental-Metadata` is also accepted for backward compatibility.
        :param cache_control: Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models.
        :param debug: Debug options for inspecting request transformations (streaming only)
        :param frequency_penalty: Frequency penalty (-2.0 to 2.0)
        :param image_config: Provider-specific image configuration options. Keys and values vary by model/provider. See https://openrouter.ai/docs/guides/overview/multimodal/image-generation for more details.
        :param logit_bias: Token logit bias adjustments
        :param logprobs: Return log probabilities
        :param max_completion_tokens: Maximum tokens in completion
        :param max_tokens: Maximum tokens (deprecated, use max_completion_tokens). Note: some providers enforce a minimum of 16.
        :param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
        :param min_p: Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter.
        :param modalities: Output modalities for the response. Supported values are \"text\", \"image\", and \"audio\".
        :param model: Model to use for completion
        :param models: Models to use for completion
        :param parallel_tool_calls: Whether to enable parallel function calling during tool use. When true, the model may generate multiple tool calls in a single response.
        :param plugins: Plugins you want to enable for this request, including their settings.
        :param presence_penalty: Presence penalty (-2.0 to 2.0)
        :param provider: When multiple model providers are available, optionally indicate your routing preference.
        :param reasoning: Configuration options for reasoning models
        :param reasoning_effort: Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ.
        :param repetition_penalty: Penalizes tokens based on how much they have already appeared in the text. A value of 1.0 means no penalty. Values above 1.0 penalize repeated tokens more strongly. Not all providers support this parameter.
        :param response_format: Response format configuration
        :param seed: Random seed for deterministic outputs
        :param service_tier: The service tier to use for processing this request.
        :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). When provided, OpenRouter uses it as the sticky routing key, routing all requests in the session to the same provider to maximize prompt cache hits. Also used for observability grouping. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
        :param stop: Stop sequences (up to 4)
        :param stop_server_tools_when: Stop conditions for the server-tool agent loop. Any condition firing halts the loop (OR logic). When set, this overrides `max_tool_calls`.
        :param stream: Enable streaming response
        :param stream_options: Streaming configuration options
        :param temperature: Sampling temperature (0-2)
        :param tool_choice: Tool choice configuration
        :param tools: Available tools for function calling
        :param top_a: Consider only tokens with \"sufficiently high\" probabilities based on the probability of the most likely token. Not all providers support this parameter.
        :param top_k: Limits the model to choose from the top K most likely tokens at each step. A value of 1 means the model will always pick the most likely next token. Not all providers support this parameter.
        :param top_logprobs: Number of top log probabilities to return (0-20)
        :param top_p: Nucleus sampling parameter (0-1)
        :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
        :param user: Unique user identifier
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """

    @overload
    async def send_async(
        self,
        *,
        messages: Union[
            List[components.ChatMessages], List[components.ChatMessagesTypedDict]
        ],
        http_referer: Optional[str] = None,
        x_open_router_title: Optional[str] = None,
        x_open_router_categories: Optional[str] = None,
        x_open_router_metadata: Optional[components.MetadataLevel] = None,
        cache_control: Optional[
            Union[
                components.AnthropicCacheControlDirective,
                components.AnthropicCacheControlDirectiveTypedDict,
            ]
        ] = None,
        debug: Optional[
            Union[components.ChatDebugOptions, components.ChatDebugOptionsTypedDict]
        ] = None,
        frequency_penalty: OptionalNullable[float] = UNSET,
        image_config: Optional[
            Union[
                Dict[str, components.ImageConfig],
                Dict[str, components.ImageConfigTypedDict],
            ]
        ] = None,
        logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
        logprobs: OptionalNullable[bool] = UNSET,
        max_completion_tokens: OptionalNullable[int] = UNSET,
        max_tokens: OptionalNullable[int] = UNSET,
        metadata: Optional[Dict[str, str]] = None,
        min_p: OptionalNullable[float] = UNSET,
        modalities: Optional[List[components.Modality]] = None,
        model: Optional[str] = None,
        models: Optional[List[str]] = None,
        parallel_tool_calls: OptionalNullable[bool] = UNSET,
        plugins: Optional[
            Union[
                List[components.ChatRequestPlugin],
                List[components.ChatRequestPluginTypedDict],
            ]
        ] = None,
        presence_penalty: OptionalNullable[float] = UNSET,
        provider: OptionalNullable[
            Union[
                components.ProviderPreferences, components.ProviderPreferencesTypedDict
            ]
        ] = UNSET,
        reasoning: Optional[
            Union[
                components.ChatRequestReasoning,
                components.ChatRequestReasoningTypedDict,
            ]
        ] = None,
        reasoning_effort: OptionalNullable[
            components.ChatRequestReasoningEffort
        ] = UNSET,
        repetition_penalty: OptionalNullable[float] = UNSET,
        response_format: Optional[
            Union[components.ResponseFormat, components.ResponseFormatTypedDict]
        ] = None,
        seed: OptionalNullable[int] = UNSET,
        service_tier: OptionalNullable[components.ChatRequestServiceTier] = UNSET,
        session_id: Optional[str] = None,
        stop: OptionalNullable[
            Union[components.Stop, components.StopTypedDict]
        ] = UNSET,
        stop_server_tools_when: Optional[
            Union[
                List[components.StopServerToolsWhenCondition],
                List[components.StopServerToolsWhenConditionTypedDict],
            ]
        ] = None,
        stream: Literal[True],
        stream_options: OptionalNullable[
            Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
        ] = UNSET,
        temperature: OptionalNullable[float] = UNSET,
        tool_choice: Optional[
            Union[components.ChatToolChoice, components.ChatToolChoiceTypedDict]
        ] = None,
        tools: Optional[
            Union[
                List[components.ChatFunctionTool],
                List[components.ChatFunctionToolTypedDict],
            ]
        ] = None,
        top_a: OptionalNullable[float] = UNSET,
        top_k: OptionalNullable[int] = UNSET,
        top_logprobs: OptionalNullable[int] = UNSET,
        top_p: OptionalNullable[float] = UNSET,
        trace: Optional[
            Union[components.TraceConfig, components.TraceConfigTypedDict]
        ] = None,
        user: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> eventstreaming.EventStreamAsync[components.ChatStreamChunk]:
        r"""Create a chat completion

        Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.

        :param messages: List of messages for the conversation
        :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
            This is used to track API usage per application.

        :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.

        :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.

        :param x_open_router_metadata: Opt-in to surface routing metadata on the response under `openrouter_metadata`. Defaults to `disabled`. The legacy header `X-OpenRouter-Experimental-Metadata` is also accepted for backward compatibility.
        :param cache_control: Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models.
        :param debug: Debug options for inspecting request transformations (streaming only)
        :param frequency_penalty: Frequency penalty (-2.0 to 2.0)
        :param image_config: Provider-specific image configuration options. Keys and values vary by model/provider. See https://openrouter.ai/docs/guides/overview/multimodal/image-generation for more details.
        :param logit_bias: Token logit bias adjustments
        :param logprobs: Return log probabilities
        :param max_completion_tokens: Maximum tokens in completion
        :param max_tokens: Maximum tokens (deprecated, use max_completion_tokens). Note: some providers enforce a minimum of 16.
        :param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
        :param min_p: Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter.
        :param modalities: Output modalities for the response. Supported values are \"text\", \"image\", and \"audio\".
        :param model: Model to use for completion
        :param models: Models to use for completion
        :param parallel_tool_calls: Whether to enable parallel function calling during tool use. When true, the model may generate multiple tool calls in a single response.
        :param plugins: Plugins you want to enable for this request, including their settings.
        :param presence_penalty: Presence penalty (-2.0 to 2.0)
        :param provider: When multiple model providers are available, optionally indicate your routing preference.
        :param reasoning: Configuration options for reasoning models
        :param reasoning_effort: Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ.
        :param repetition_penalty: Penalizes tokens based on how much they have already appeared in the text. A value of 1.0 means no penalty. Values above 1.0 penalize repeated tokens more strongly. Not all providers support this parameter.
        :param response_format: Response format configuration
        :param seed: Random seed for deterministic outputs
        :param service_tier: The service tier to use for processing this request.
        :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). When provided, OpenRouter uses it as the sticky routing key, routing all requests in the session to the same provider to maximize prompt cache hits. Also used for observability grouping. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
        :param stop: Stop sequences (up to 4)
        :param stop_server_tools_when: Stop conditions for the server-tool agent loop. Any condition firing halts the loop (OR logic). When set, this overrides `max_tool_calls`.
        :param stream: Enable streaming response
        :param stream_options: Streaming configuration options
        :param temperature: Sampling temperature (0-2)
        :param tool_choice: Tool choice configuration
        :param tools: Available tools for function calling
        :param top_a: Consider only tokens with \"sufficiently high\" probabilities based on the probability of the most likely token. Not all providers support this parameter.
        :param top_k: Limits the model to choose from the top K most likely tokens at each step. A value of 1 means the model will always pick the most likely next token. Not all providers support this parameter.
        :param top_logprobs: Number of top log probabilities to return (0-20)
        :param top_p: Nucleus sampling parameter (0-1)
        :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
        :param user: Unique user identifier
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """

    async def send_async(
        self,
        *,
        messages: Union[
            List[components.ChatMessages], List[components.ChatMessagesTypedDict]
        ],
        http_referer: Optional[str] = None,
        x_open_router_title: Optional[str] = None,
        x_open_router_categories: Optional[str] = None,
        x_open_router_metadata: Optional[components.MetadataLevel] = None,
        cache_control: Optional[
            Union[
                components.AnthropicCacheControlDirective,
                components.AnthropicCacheControlDirectiveTypedDict,
            ]
        ] = None,
        debug: Optional[
            Union[components.ChatDebugOptions, components.ChatDebugOptionsTypedDict]
        ] = None,
        frequency_penalty: OptionalNullable[float] = UNSET,
        image_config: Optional[
            Union[
                Dict[str, components.ImageConfig],
                Dict[str, components.ImageConfigTypedDict],
            ]
        ] = None,
        logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
        logprobs: OptionalNullable[bool] = UNSET,
        max_completion_tokens: OptionalNullable[int] = UNSET,
        max_tokens: OptionalNullable[int] = UNSET,
        metadata: Optional[Dict[str, str]] = None,
        min_p: OptionalNullable[float] = UNSET,
        modalities: Optional[List[components.Modality]] = None,
        model: Optional[str] = None,
        models: Optional[List[str]] = None,
        parallel_tool_calls: OptionalNullable[bool] = UNSET,
        plugins: Optional[
            Union[
                List[components.ChatRequestPlugin],
                List[components.ChatRequestPluginTypedDict],
            ]
        ] = None,
        presence_penalty: OptionalNullable[float] = UNSET,
        provider: OptionalNullable[
            Union[
                components.ProviderPreferences, components.ProviderPreferencesTypedDict
            ]
        ] = UNSET,
        reasoning: Optional[
            Union[
                components.ChatRequestReasoning,
                components.ChatRequestReasoningTypedDict,
            ]
        ] = None,
        reasoning_effort: OptionalNullable[
            components.ChatRequestReasoningEffort
        ] = UNSET,
        repetition_penalty: OptionalNullable[float] = UNSET,
        response_format: Optional[
            Union[components.ResponseFormat, components.ResponseFormatTypedDict]
        ] = None,
        seed: OptionalNullable[int] = UNSET,
        service_tier: OptionalNullable[components.ChatRequestServiceTier] = UNSET,
        session_id: Optional[str] = None,
        stop: OptionalNullable[
            Union[components.Stop, components.StopTypedDict]
        ] = UNSET,
        stop_server_tools_when: Optional[
            Union[
                List[components.StopServerToolsWhenCondition],
                List[components.StopServerToolsWhenConditionTypedDict],
            ]
        ] = None,
        stream: Optional[bool] = False,
        stream_options: OptionalNullable[
            Union[components.ChatStreamOptions, components.ChatStreamOptionsTypedDict]
        ] = UNSET,
        temperature: OptionalNullable[float] = UNSET,
        tool_choice: Optional[
            Union[components.ChatToolChoice, components.ChatToolChoiceTypedDict]
        ] = None,
        tools: Optional[
            Union[
                List[components.ChatFunctionTool],
                List[components.ChatFunctionToolTypedDict],
            ]
        ] = None,
        top_a: OptionalNullable[float] = UNSET,
        top_k: OptionalNullable[int] = UNSET,
        top_logprobs: OptionalNullable[int] = UNSET,
        top_p: OptionalNullable[float] = UNSET,
        trace: Optional[
            Union[components.TraceConfig, components.TraceConfigTypedDict]
        ] = None,
        user: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> operations.SendChatCompletionRequestResponse:
        r"""Create a chat completion

        Sends a request for a model response for the given chat conversation. Supports both streaming and non-streaming modes.

        :param messages: List of messages for the conversation
        :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
            This is used to track API usage per application.

        :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.

        :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.

        :param x_open_router_metadata: Opt-in to surface routing metadata on the response under `openrouter_metadata`. Defaults to `disabled`. The legacy header `X-OpenRouter-Experimental-Metadata` is also accepted for backward compatibility.
        :param cache_control: Enable automatic prompt caching. When set at the top level, the system automatically applies cache breakpoints to the last cacheable block in the request. Currently supported for Anthropic Claude models.
        :param debug: Debug options for inspecting request transformations (streaming only)
        :param frequency_penalty: Frequency penalty (-2.0 to 2.0)
        :param image_config: Provider-specific image configuration options. Keys and values vary by model/provider. See https://openrouter.ai/docs/guides/overview/multimodal/image-generation for more details.
        :param logit_bias: Token logit bias adjustments
        :param logprobs: Return log probabilities
        :param max_completion_tokens: Maximum tokens in completion
        :param max_tokens: Maximum tokens (deprecated, use max_completion_tokens). Note: some providers enforce a minimum of 16.
        :param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
        :param min_p: Minimum probability threshold relative to the most likely token. Tokens with probability below min_p * (probability of top token) are filtered out. Not all providers support this parameter.
        :param modalities: Output modalities for the response. Supported values are \"text\", \"image\", and \"audio\".
        :param model: Model to use for completion
        :param models: Models to use for completion
        :param parallel_tool_calls: Whether to enable parallel function calling during tool use. When true, the model may generate multiple tool calls in a single response.
        :param plugins: Plugins you want to enable for this request, including their settings.
        :param presence_penalty: Presence penalty (-2.0 to 2.0)
        :param provider: When multiple model providers are available, optionally indicate your routing preference.
        :param reasoning: Configuration options for reasoning models
        :param reasoning_effort: Shorthand for setting reasoning effort. Equivalent to setting reasoning.effort. Cannot be used simultaneously with reasoning.effort if they differ.
        :param repetition_penalty: Penalizes tokens based on how much they have already appeared in the text. A value of 1.0 means no penalty. Values above 1.0 penalize repeated tokens more strongly. Not all providers support this parameter.
        :param response_format: Response format configuration
        :param seed: Random seed for deterministic outputs
        :param service_tier: The service tier to use for processing this request.
        :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). When provided, OpenRouter uses it as the sticky routing key, routing all requests in the session to the same provider to maximize prompt cache hits. Also used for observability grouping. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
        :param stop: Stop sequences (up to 4)
        :param stop_server_tools_when: Stop conditions for the server-tool agent loop. Any condition firing halts the loop (OR logic). When set, this overrides `max_tool_calls`.
        :param stream: Enable streaming response
        :param stream_options: Streaming configuration options
        :param temperature: Sampling temperature (0-2)
        :param tool_choice: Tool choice configuration
        :param tools: Available tools for function calling
        :param top_a: Consider only tokens with \"sufficiently high\" probabilities based on the probability of the most likely token. Not all providers support this parameter.
        :param top_k: Limits the model to choose from the top K most likely tokens at each step. A value of 1 means the model will always pick the most likely next token. Not all providers support this parameter.
        :param top_logprobs: Number of top log probabilities to return (0-20)
        :param top_p: Nucleus sampling parameter (0-1)
        :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
        :param user: Unique user identifier
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = operations.SendChatCompletionRequestRequest(
            http_referer=http_referer,
            x_open_router_title=x_open_router_title,
            x_open_router_categories=x_open_router_categories,
            x_open_router_metadata=x_open_router_metadata,
            chat_request=components.ChatRequest(
                cache_control=utils.get_pydantic_model(
                    cache_control, Optional[components.AnthropicCacheControlDirective]
                ),
                debug=utils.get_pydantic_model(
                    debug, Optional[components.ChatDebugOptions]
                ),
                frequency_penalty=frequency_penalty,
                image_config=image_config,
                logit_bias=logit_bias,
                logprobs=logprobs,
                max_completion_tokens=max_completion_tokens,
                max_tokens=max_tokens,
                messages=utils.get_pydantic_model(
                    messages, List[components.ChatMessages]
                ),
                metadata=metadata,
                min_p=min_p,
                modalities=modalities,
                model=model,
                models=models,
                parallel_tool_calls=parallel_tool_calls,
                plugins=utils.get_pydantic_model(
                    plugins, Optional[List[components.ChatRequestPlugin]]
                ),
                presence_penalty=presence_penalty,
                provider=utils.get_pydantic_model(
                    provider, OptionalNullable[components.ProviderPreferences]
                ),
                reasoning=utils.get_pydantic_model(
                    reasoning, Optional[components.ChatRequestReasoning]
                ),
                reasoning_effort=reasoning_effort,
                repetition_penalty=repetition_penalty,
                response_format=utils.get_pydantic_model(
                    response_format, Optional[components.ResponseFormat]
                ),
                seed=seed,
                service_tier=service_tier,
                session_id=session_id,
                stop=stop,
                stop_server_tools_when=utils.get_pydantic_model(
                    stop_server_tools_when,
                    Optional[List[components.StopServerToolsWhenCondition]],
                ),
                stream=stream,
                stream_options=utils.get_pydantic_model(
                    stream_options, OptionalNullable[components.ChatStreamOptions]
                ),
                temperature=temperature,
                tool_choice=utils.get_pydantic_model(
                    tool_choice, Optional[components.ChatToolChoice]
                ),
                tools=utils.get_pydantic_model(
                    tools, Optional[List[components.ChatFunctionTool]]
                ),
                top_a=top_a,
                top_k=top_k,
                top_logprobs=top_logprobs,
                top_p=top_p,
                trace=utils.get_pydantic_model(trace, Optional[components.TraceConfig]),
                user=user,
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/chat/completions",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="text/event-stream" if stream else "application/json",
            http_headers=http_headers,
            _globals=operations.SendChatCompletionRequestGlobals(
                http_referer=self.sdk_configuration.globals.http_referer,
                x_open_router_title=self.sdk_configuration.globals.x_open_router_title,
                x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories,
            ),
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.chat_request, False, False, "json", components.ChatRequest
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="sendChatCompletionRequest",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, components.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "402",
                "403",
                "404",
                "408",
                "413",
                "422",
                "429",
                "4XX",
                "500",
                "502",
                "503",
                "524",
                "529",
                "5XX",
            ],
            stream=True,
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            return unmarshal_json_response(
                components.ChatResult, http_res, http_res_text
            )
        if utils.match_response(http_res, "200", "text/event-stream"):
            return eventstreaming.EventStreamAsync(
                http_res,
                lambda raw: utils.unmarshal_json(
                    raw, components.ChatStreamingResponse
                ).data,
                sentinel="[DONE]",
                client_ref=self,
            )
        if utils.match_response(http_res, "400", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.BadRequestResponseErrorData, http_res, http_res_text
            )
            raise errors.BadRequestResponseError(response_data, http_res, http_res_text)
        if utils.match_response(http_res, "401", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.UnauthorizedResponseErrorData, http_res, http_res_text
            )
            raise errors.UnauthorizedResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "402", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.PaymentRequiredResponseErrorData, http_res, http_res_text
            )
            raise errors.PaymentRequiredResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "403", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.ForbiddenResponseErrorData, http_res, http_res_text
            )
            raise errors.ForbiddenResponseError(response_data, http_res, http_res_text)
        if utils.match_response(http_res, "404", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.NotFoundResponseErrorData, http_res, http_res_text
            )
            raise errors.NotFoundResponseError(response_data, http_res, http_res_text)
        if utils.match_response(http_res, "408", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.RequestTimeoutResponseErrorData, http_res, http_res_text
            )
            raise errors.RequestTimeoutResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "413", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.PayloadTooLargeResponseErrorData, http_res, http_res_text
            )
            raise errors.PayloadTooLargeResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "422", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.UnprocessableEntityResponseErrorData, http_res, http_res_text
            )
            raise errors.UnprocessableEntityResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "429", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.TooManyRequestsResponseErrorData, http_res, http_res_text
            )
            raise errors.TooManyRequestsResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "500", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.InternalServerResponseErrorData, http_res, http_res_text
            )
            raise errors.InternalServerResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "502", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.BadGatewayResponseErrorData, http_res, http_res_text
            )
            raise errors.BadGatewayResponseError(response_data, http_res, http_res_text)
        if utils.match_response(http_res, "503", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.ServiceUnavailableResponseErrorData, http_res, http_res_text
            )
            raise errors.ServiceUnavailableResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "524", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.EdgeNetworkTimeoutResponseErrorData, http_res, http_res_text
            )
            raise errors.EdgeNetworkTimeoutResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "529", "application/json"):
            http_res_text = await utils.stream_to_text_async(http_res)
            response_data = unmarshal_json_response(
                errors.ProviderOverloadedResponseErrorData, http_res, http_res_text
            )
            raise errors.ProviderOverloadedResponseError(
                response_data, http_res, http_res_text
            )
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.OpenRouterDefaultError(
                "API error occurred", http_res, http_res_text
            )
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.OpenRouterDefaultError(
                "API error occurred", http_res, http_res_text
            )

        http_res_text = await utils.stream_to_text_async(http_res)
        raise errors.OpenRouterDefaultError(
            "Unexpected response received", http_res, http_res_text
        )
