"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations from .anthropicspeed import AnthropicSpeed from .anthropicusageiteration import ( AnthropicUsageIteration, AnthropicUsageIterationTypedDict, ) from .costdetails import CostDetails, CostDetailsTypedDict from openrouter.types import ( BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL, ) from openrouter.utils import validate_open_enum from pydantic import model_serializer from pydantic.functional_validators import PlainValidator from typing import List, Optional from typing_extensions import Annotated, NotRequired, TypedDict class ImageGenerationUsageCompletionTokensDetailsTypedDict(TypedDict): audio_tokens: NotRequired[Nullable[int]] r"""Tokens generated by the model for audio output.""" image_tokens: NotRequired[Nullable[int]] r"""Tokens generated by the model for image output.""" reasoning_tokens: NotRequired[Nullable[int]] r"""Tokens generated by the model for reasoning.""" class ImageGenerationUsageCompletionTokensDetails(BaseModel): audio_tokens: OptionalNullable[int] = UNSET r"""Tokens generated by the model for audio output.""" image_tokens: OptionalNullable[int] = UNSET r"""Tokens generated by the model for image output.""" reasoning_tokens: OptionalNullable[int] = UNSET r"""Tokens generated by the model for reasoning.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = ["audio_tokens", "image_tokens", "reasoning_tokens"] nullable_fields = ["audio_tokens", "image_tokens", "reasoning_tokens"] null_default_fields = [] serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) optional_nullable = k in optional_fields and k in nullable_fields is_set = ( self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields ) # pylint: disable=no-member if val is not None and val != UNSET_SENTINEL: m[k] = val elif val != UNSET_SENTINEL and ( not k in optional_fields or (optional_nullable and is_set) ): m[k] = val return m class ImageGenerationUsagePromptTokensDetailsTypedDict(TypedDict): r"""Breakdown of tokens used in the prompt.""" audio_tokens: NotRequired[Nullable[int]] r"""Tokens used for input audio.""" cache_write_tokens: NotRequired[Nullable[int]] r"""Tokens written to cache. Only returned for models with explicit caching and cache write pricing.""" cached_tokens: NotRequired[Nullable[int]] r"""Tokens cached by the endpoint.""" file_tokens: NotRequired[Nullable[int]] r"""Tokens used for input files/documents.""" video_tokens: NotRequired[Nullable[int]] r"""Tokens used for input video.""" class ImageGenerationUsagePromptTokensDetails(BaseModel): r"""Breakdown of tokens used in the prompt.""" audio_tokens: OptionalNullable[int] = UNSET r"""Tokens used for input audio.""" cache_write_tokens: OptionalNullable[int] = UNSET r"""Tokens written to cache. Only returned for models with explicit caching and cache write pricing.""" cached_tokens: OptionalNullable[int] = UNSET r"""Tokens cached by the endpoint.""" file_tokens: OptionalNullable[int] = UNSET r"""Tokens used for input files/documents.""" video_tokens: OptionalNullable[int] = UNSET r"""Tokens used for input video.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = [ "audio_tokens", "cache_write_tokens", "cached_tokens", "file_tokens", "video_tokens", ] nullable_fields = [ "audio_tokens", "cache_write_tokens", "cached_tokens", "file_tokens", "video_tokens", ] null_default_fields = [] serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) optional_nullable = k in optional_fields and k in nullable_fields is_set = ( self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields ) # pylint: disable=no-member if val is not None and val != UNSET_SENTINEL: m[k] = val elif val != UNSET_SENTINEL and ( not k in optional_fields or (optional_nullable and is_set) ): m[k] = val return m class ServerToolUseTypedDict(TypedDict): r"""Usage for server-side tool execution (e.g., web search)""" tool_calls_executed: NotRequired[Nullable[int]] r"""Number of OpenRouter server tool calls that executed and produced a result.""" tool_calls_requested: NotRequired[Nullable[int]] r"""Total number of OpenRouter server-orchestrated tool calls the model requested, across all tool types. Provider-native tools (e.g. native web search) are not counted here.""" web_search_requests: NotRequired[Nullable[int]] r"""Number of web searches performed by server-side tools. For server-orchestrated tool calls a web search is also counted in tool_calls_requested; provider-native web search may report web_search_requests only. Do not sum the two.""" class ServerToolUse(BaseModel): r"""Usage for server-side tool execution (e.g., web search)""" tool_calls_executed: OptionalNullable[int] = UNSET r"""Number of OpenRouter server tool calls that executed and produced a result.""" tool_calls_requested: OptionalNullable[int] = UNSET r"""Total number of OpenRouter server-orchestrated tool calls the model requested, across all tool types. Provider-native tools (e.g. native web search) are not counted here.""" web_search_requests: OptionalNullable[int] = UNSET r"""Number of web searches performed by server-side tools. For server-orchestrated tool calls a web search is also counted in tool_calls_requested; provider-native web search may report web_search_requests only. Do not sum the two.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = [ "tool_calls_executed", "tool_calls_requested", "web_search_requests", ] nullable_fields = [ "tool_calls_executed", "tool_calls_requested", "web_search_requests", ] null_default_fields = [] serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) optional_nullable = k in optional_fields and k in nullable_fields is_set = ( self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields ) # pylint: disable=no-member if val is not None and val != UNSET_SENTINEL: m[k] = val elif val != UNSET_SENTINEL and ( not k in optional_fields or (optional_nullable and is_set) ): m[k] = val return m class ImageGenerationUsageTypedDict(TypedDict): r"""Token and cost usage for the image generation request, when available""" completion_tokens: int r"""The tokens generated""" prompt_tokens: int r"""Including images, input audio, and tools if any""" total_tokens: int r"""Sum of the above two fields""" completion_tokens_details: NotRequired[ Nullable[ImageGenerationUsageCompletionTokensDetailsTypedDict] ] cost: NotRequired[Nullable[float]] r"""Cost of the completion""" cost_details: NotRequired[Nullable[CostDetailsTypedDict]] r"""Breakdown of upstream inference costs""" is_byok: NotRequired[bool] r"""Whether a request was made using a Bring Your Own Key configuration""" iterations: NotRequired[Nullable[List[AnthropicUsageIterationTypedDict]]] prompt_tokens_details: NotRequired[ Nullable[ImageGenerationUsagePromptTokensDetailsTypedDict] ] r"""Breakdown of tokens used in the prompt.""" server_tool_use: NotRequired[Nullable[ServerToolUseTypedDict]] r"""Usage for server-side tool execution (e.g., web search)""" service_tier: NotRequired[Nullable[str]] r"""The service tier used by the upstream provider for this request""" speed: NotRequired[Nullable[AnthropicSpeed]] class ImageGenerationUsage(BaseModel): r"""Token and cost usage for the image generation request, when available""" completion_tokens: int r"""The tokens generated""" prompt_tokens: int r"""Including images, input audio, and tools if any""" total_tokens: int r"""Sum of the above two fields""" completion_tokens_details: OptionalNullable[ ImageGenerationUsageCompletionTokensDetails ] = UNSET cost: OptionalNullable[float] = UNSET r"""Cost of the completion""" cost_details: OptionalNullable[CostDetails] = UNSET r"""Breakdown of upstream inference costs""" is_byok: Optional[bool] = None r"""Whether a request was made using a Bring Your Own Key configuration""" iterations: OptionalNullable[List[AnthropicUsageIteration]] = UNSET prompt_tokens_details: OptionalNullable[ImageGenerationUsagePromptTokensDetails] = ( UNSET ) r"""Breakdown of tokens used in the prompt.""" server_tool_use: OptionalNullable[ServerToolUse] = UNSET r"""Usage for server-side tool execution (e.g., web search)""" service_tier: OptionalNullable[str] = UNSET r"""The service tier used by the upstream provider for this request""" speed: Annotated[ OptionalNullable[AnthropicSpeed], PlainValidator(validate_open_enum(False)) ] = UNSET @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = [ "completion_tokens_details", "cost", "cost_details", "is_byok", "iterations", "prompt_tokens_details", "server_tool_use", "service_tier", "speed", ] nullable_fields = [ "completion_tokens_details", "cost", "cost_details", "iterations", "prompt_tokens_details", "server_tool_use", "service_tier", "speed", ] null_default_fields = [] serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) serialized.pop(k, None) optional_nullable = k in optional_fields and k in nullable_fields is_set = ( self.__pydantic_fields_set__.intersection({n}) or k in null_default_fields ) # pylint: disable=no-member if val is not None and val != UNSET_SENTINEL: m[k] = val elif val != UNSET_SENTINEL and ( not k in optional_fields or (optional_nullable and is_set) ): m[k] = val return m