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

from __future__ import annotations
from .applypatchservertool import ApplyPatchServerTool, ApplyPatchServerToolTypedDict
from .baseinputs_union import BaseInputsUnion, BaseInputsUnionTypedDict
from .basereasoningconfig import BaseReasoningConfig, BaseReasoningConfigTypedDict
from .codeinterpreterservertool import (
    CodeInterpreterServerTool,
    CodeInterpreterServerToolTypedDict,
)
from .codexlocalshelltool import CodexLocalShellTool, CodexLocalShellToolTypedDict
from .computeruseservertool import ComputerUseServerTool, ComputerUseServerToolTypedDict
from .customtool import CustomTool, CustomToolTypedDict
from .filesearchservertool import FileSearchServerTool, FileSearchServerToolTypedDict
from .imagegenerationservertool import (
    ImageGenerationServerTool,
    ImageGenerationServerToolTypedDict,
)
from .incompletedetails import IncompleteDetails, IncompleteDetailsTypedDict
from .legacy_websearchservertool import (
    LegacyWebSearchServerTool,
    LegacyWebSearchServerToolTypedDict,
)
from .mcpservertool import McpServerTool, McpServerToolTypedDict
from .openairesponsesresponsestatus import OpenAIResponsesResponseStatus
from .openairesponsestoolchoice_union import (
    OpenAIResponsesToolChoiceUnion,
    OpenAIResponsesToolChoiceUnionTypedDict,
)
from .outputitems import OutputItems, OutputItemsTypedDict
from .preview_20250311_websearchservertool import (
    Preview20250311WebSearchServerTool,
    Preview20250311WebSearchServerToolTypedDict,
)
from .preview_websearchservertool import (
    PreviewWebSearchServerTool,
    PreviewWebSearchServerToolTypedDict,
)
from .responseserrorfield import ResponsesErrorField, ResponsesErrorFieldTypedDict
from .shellservertool import ShellServerTool, ShellServerToolTypedDict
from .storedprompttemplate import StoredPromptTemplate, StoredPromptTemplateTypedDict
from .textconfig import TextConfig, TextConfigTypedDict
from .truncationenum import TruncationEnum
from .usage import Usage, UsageTypedDict
from .websearchservertool import WebSearchServerTool, WebSearchServerToolTypedDict
from openrouter.types import (
    BaseModel,
    Nullable,
    OptionalNullable,
    UNSET,
    UNSET_SENTINEL,
)
from openrouter.utils import get_discriminator, validate_open_enum
from pydantic import Discriminator, Tag, model_serializer
from pydantic.functional_validators import PlainValidator
from typing import Any, Dict, List, Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict


OpenResponsesResultObject = Literal["response",]


OpenResponsesResultType = Literal["function",]


class OpenResponsesResultToolFunctionTypedDict(TypedDict):
    r"""Function tool definition"""

    type: OpenResponsesResultType
    name: str
    parameters: Nullable[Dict[str, Nullable[Any]]]
    description: NotRequired[Nullable[str]]
    strict: NotRequired[Nullable[bool]]


class OpenResponsesResultToolFunction(BaseModel):
    r"""Function tool definition"""

    type: OpenResponsesResultType

    name: str

    parameters: Nullable[Dict[str, Nullable[Any]]]

    description: OptionalNullable[str] = UNSET

    strict: OptionalNullable[bool] = UNSET

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["description", "strict"]
        nullable_fields = ["description", "strict", "parameters"]
        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


OpenResponsesResultToolUnionTypedDict = TypeAliasType(
    "OpenResponsesResultToolUnionTypedDict",
    Union[
        CodexLocalShellToolTypedDict,
        ApplyPatchServerToolTypedDict,
        ShellServerToolTypedDict,
        CodeInterpreterServerToolTypedDict,
        CustomToolTypedDict,
        ComputerUseServerToolTypedDict,
        OpenResponsesResultToolFunctionTypedDict,
        FileSearchServerToolTypedDict,
        LegacyWebSearchServerToolTypedDict,
        WebSearchServerToolTypedDict,
        Preview20250311WebSearchServerToolTypedDict,
        PreviewWebSearchServerToolTypedDict,
        McpServerToolTypedDict,
        ImageGenerationServerToolTypedDict,
    ],
)


OpenResponsesResultToolUnion = Annotated[
    Union[
        Annotated[OpenResponsesResultToolFunction, Tag("function")],
        Annotated[PreviewWebSearchServerTool, Tag("web_search_preview")],
        Annotated[
            Preview20250311WebSearchServerTool, Tag("web_search_preview_2025_03_11")
        ],
        Annotated[LegacyWebSearchServerTool, Tag("web_search")],
        Annotated[WebSearchServerTool, Tag("web_search_2025_08_26")],
        Annotated[FileSearchServerTool, Tag("file_search")],
        Annotated[ComputerUseServerTool, Tag("computer_use_preview")],
        Annotated[CodeInterpreterServerTool, Tag("code_interpreter")],
        Annotated[McpServerTool, Tag("mcp")],
        Annotated[ImageGenerationServerTool, Tag("image_generation")],
        Annotated[CodexLocalShellTool, Tag("local_shell")],
        Annotated[ShellServerTool, Tag("shell")],
        Annotated[ApplyPatchServerTool, Tag("apply_patch")],
        Annotated[CustomTool, Tag("custom")],
    ],
    Discriminator(lambda m: get_discriminator(m, "type", "type")),
]


class OpenResponsesResultTypedDict(TypedDict):
    r"""Complete non-streaming response from the Responses API"""

    id: str
    object: OpenResponsesResultObject
    created_at: float
    model: str
    status: OpenAIResponsesResponseStatus
    completed_at: Nullable[float]
    output: List[OutputItemsTypedDict]
    error: Nullable[ResponsesErrorFieldTypedDict]
    r"""Error information returned from the API"""
    incomplete_details: Nullable[IncompleteDetailsTypedDict]
    temperature: Nullable[float]
    top_p: Nullable[float]
    presence_penalty: Nullable[float]
    frequency_penalty: Nullable[float]
    instructions: Nullable[BaseInputsUnionTypedDict]
    metadata: Nullable[Dict[str, str]]
    r"""Metadata key-value pairs for the request. Keys must be ≤64 characters and cannot contain brackets. Values must be ≤512 characters. Maximum 16 pairs allowed."""
    tools: List[OpenResponsesResultToolUnionTypedDict]
    tool_choice: OpenAIResponsesToolChoiceUnionTypedDict
    parallel_tool_calls: bool
    user: NotRequired[Nullable[str]]
    output_text: NotRequired[str]
    prompt_cache_key: NotRequired[Nullable[str]]
    safety_identifier: NotRequired[Nullable[str]]
    usage: NotRequired[Nullable[UsageTypedDict]]
    r"""Token usage information for the response"""
    max_tool_calls: NotRequired[Nullable[float]]
    top_logprobs: NotRequired[float]
    max_output_tokens: NotRequired[Nullable[float]]
    prompt: NotRequired[Nullable[StoredPromptTemplateTypedDict]]
    background: NotRequired[Nullable[bool]]
    previous_response_id: NotRequired[Nullable[str]]
    reasoning: NotRequired[Nullable[BaseReasoningConfigTypedDict]]
    service_tier: NotRequired[Nullable[str]]
    store: NotRequired[bool]
    truncation: NotRequired[Nullable[TruncationEnum]]
    text: NotRequired[TextConfigTypedDict]
    r"""Text output configuration including format and verbosity"""


class OpenResponsesResult(BaseModel):
    r"""Complete non-streaming response from the Responses API"""

    id: str

    object: OpenResponsesResultObject

    created_at: float

    model: str

    status: Annotated[
        OpenAIResponsesResponseStatus, PlainValidator(validate_open_enum(False))
    ]

    completed_at: Nullable[float]

    output: List[OutputItems]

    error: Nullable[ResponsesErrorField]
    r"""Error information returned from the API"""

    incomplete_details: Nullable[IncompleteDetails]

    temperature: Nullable[float]

    top_p: Nullable[float]

    presence_penalty: Nullable[float]

    frequency_penalty: Nullable[float]

    instructions: Nullable[BaseInputsUnion]

    metadata: Nullable[Dict[str, str]]
    r"""Metadata key-value pairs for the request. Keys must be ≤64 characters and cannot contain brackets. Values must be ≤512 characters. Maximum 16 pairs allowed."""

    tools: List[OpenResponsesResultToolUnion]

    tool_choice: OpenAIResponsesToolChoiceUnion

    parallel_tool_calls: bool

    user: OptionalNullable[str] = UNSET

    output_text: Optional[str] = None

    prompt_cache_key: OptionalNullable[str] = UNSET

    safety_identifier: OptionalNullable[str] = UNSET

    usage: OptionalNullable[Usage] = UNSET
    r"""Token usage information for the response"""

    max_tool_calls: OptionalNullable[float] = UNSET

    top_logprobs: Optional[float] = None

    max_output_tokens: OptionalNullable[float] = UNSET

    prompt: OptionalNullable[StoredPromptTemplate] = UNSET

    background: OptionalNullable[bool] = UNSET

    previous_response_id: OptionalNullable[str] = UNSET

    reasoning: OptionalNullable[BaseReasoningConfig] = UNSET

    service_tier: OptionalNullable[str] = UNSET

    store: Optional[bool] = None

    truncation: Annotated[
        OptionalNullable[TruncationEnum], PlainValidator(validate_open_enum(False))
    ] = UNSET

    text: Optional[TextConfig] = None
    r"""Text output configuration including format and verbosity"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "user",
            "output_text",
            "prompt_cache_key",
            "safety_identifier",
            "usage",
            "max_tool_calls",
            "top_logprobs",
            "max_output_tokens",
            "prompt",
            "background",
            "previous_response_id",
            "reasoning",
            "service_tier",
            "store",
            "truncation",
            "text",
        ]
        nullable_fields = [
            "completed_at",
            "user",
            "prompt_cache_key",
            "safety_identifier",
            "error",
            "incomplete_details",
            "usage",
            "max_tool_calls",
            "max_output_tokens",
            "temperature",
            "top_p",
            "presence_penalty",
            "frequency_penalty",
            "instructions",
            "metadata",
            "prompt",
            "background",
            "previous_response_id",
            "reasoning",
            "service_tier",
            "truncation",
        ]
        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
