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

from __future__ import annotations
from .functioncallconfiguration import (
    FunctionCallConfiguration,
    FunctionCallConfigurationTypedDict,
)
from .tmodel import TModel, TModelTypedDict
from opperai.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
from pydantic import model_serializer
from typing import Any, Dict, Optional
from typing_extensions import NotRequired, TypedDict


class UpdateFunctionResponseTypedDict(TypedDict):
    name: str
    r"""The name of the function. Must be unique within the project and can only contain letters, numbers, underscores and hyphens."""
    instructions: str
    r"""The instructions for the function, this is the prompt that will be sent to the model to complete the task. Recommended to be concise and to the point"""
    id: str
    r"""The ID of the function"""
    description: NotRequired[Nullable[str]]
    r"""Optional description of the function. This is used to describe the function to a user."""
    input_schema: NotRequired[Nullable[Dict[str, Any]]]
    r"""Optional input schema for the function. Can preferably include field descriptions to allow the model to reason about the input variables. Schema is validated against the input data and issues an error if it does not match. With the Opper SDKs you can define these schemas through libraries like Pydantic and Zod. For schemas with definitions, prefer using '$defs' and '#/$defs/...' references."""
    output_schema: NotRequired[Nullable[Dict[str, Any]]]
    r"""Optional output schema for the function. Can preferably include field descriptions to allow the model to reason about the output variables. Schema is validated against the output data and issues an error if it does not match. With the Opper SDKs you can define these schemas through libraries like Pydantic and Zod. For schemas with definitions, prefer using '$defs' and '#/$defs/...' references."""
    model: NotRequired[TModelTypedDict]
    configuration: NotRequired[Nullable[FunctionCallConfigurationTypedDict]]
    r"""Optional configuration for the function.Configuration is a dictionary of key-value pairs that can be used to override the default configuration for the function."""
    dataset_id: NotRequired[Nullable[str]]
    r"""The ID of the dataset associated with the function"""
    revision_id: NotRequired[Nullable[str]]
    r"""The ID of the latest revision of the function"""


class UpdateFunctionResponse(BaseModel):
    name: str
    r"""The name of the function. Must be unique within the project and can only contain letters, numbers, underscores and hyphens."""

    instructions: str
    r"""The instructions for the function, this is the prompt that will be sent to the model to complete the task. Recommended to be concise and to the point"""

    id: str
    r"""The ID of the function"""

    description: OptionalNullable[str] = UNSET
    r"""Optional description of the function. This is used to describe the function to a user."""

    input_schema: OptionalNullable[Dict[str, Any]] = UNSET
    r"""Optional input schema for the function. Can preferably include field descriptions to allow the model to reason about the input variables. Schema is validated against the input data and issues an error if it does not match. With the Opper SDKs you can define these schemas through libraries like Pydantic and Zod. For schemas with definitions, prefer using '$defs' and '#/$defs/...' references."""

    output_schema: OptionalNullable[Dict[str, Any]] = UNSET
    r"""Optional output schema for the function. Can preferably include field descriptions to allow the model to reason about the output variables. Schema is validated against the output data and issues an error if it does not match. With the Opper SDKs you can define these schemas through libraries like Pydantic and Zod. For schemas with definitions, prefer using '$defs' and '#/$defs/...' references."""

    model: Optional[TModel] = None

    configuration: OptionalNullable[FunctionCallConfiguration] = UNSET
    r"""Optional configuration for the function.Configuration is a dictionary of key-value pairs that can be used to override the default configuration for the function."""

    dataset_id: OptionalNullable[str] = UNSET
    r"""The ID of the dataset associated with the function"""

    revision_id: OptionalNullable[str] = UNSET
    r"""The ID of the latest revision of the function"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "description",
            "input_schema",
            "output_schema",
            "model",
            "configuration",
            "dataset_id",
            "revision_id",
        ]
        nullable_fields = [
            "description",
            "input_schema",
            "output_schema",
            "configuration",
            "dataset_id",
            "revision_id",
        ]
        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
