# This file was auto-generated by Fern from our API Definition.

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..types.chat_completion_response import ChatCompletionResponse
from ..types.function import Function
from ..types.function_call import FunctionCall
from ..types.message import Message
from ..types.response_format import ResponseFormat
from ..types.stream_options import StreamOptions
from ..types.tool import Tool

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawChatCompletionsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create_chat_completions(
        self,
        *,
        model: typing.Optional[str] = OMIT,
        messages: typing.Optional[typing.Sequence[Message]] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        top_p: typing.Optional[float] = OMIT,
        n: typing.Optional[int] = OMIT,
        stream: typing.Optional[bool] = OMIT,
        stream_options: typing.Optional[StreamOptions] = OMIT,
        stop: typing.Optional[typing.Sequence[str]] = OMIT,
        max_tokens: typing.Optional[int] = OMIT,
        max_completion_tokens: typing.Optional[int] = OMIT,
        presence_penalty: typing.Optional[float] = OMIT,
        frequency_penalty: typing.Optional[float] = OMIT,
        logit_bias: typing.Optional[typing.Dict[str, int]] = OMIT,
        user: typing.Optional[str] = OMIT,
        response_format: typing.Optional[ResponseFormat] = OMIT,
        seed: typing.Optional[int] = OMIT,
        tools: typing.Optional[typing.Sequence[Tool]] = OMIT,
        tool_choice: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        parallel_tool_calls: typing.Optional[bool] = OMIT,
        store: typing.Optional[bool] = OMIT,
        metadata: typing.Optional[typing.Dict[str, str]] = OMIT,
        reasoning_effort: typing.Optional[str] = OMIT,
        service_tier: typing.Optional[str] = OMIT,
        functions: typing.Optional[typing.Sequence[Function]] = OMIT,
        function_call: typing.Optional[FunctionCall] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ChatCompletionResponse]:
        """
        Create chat completions

        Parameters
        ----------
        model : typing.Optional[str]

        messages : typing.Optional[typing.Sequence[Message]]

        temperature : typing.Optional[float]

        top_p : typing.Optional[float]

        n : typing.Optional[int]

        stream : typing.Optional[bool]

        stream_options : typing.Optional[StreamOptions]

        stop : typing.Optional[typing.Sequence[str]]

        max_tokens : typing.Optional[int]

        max_completion_tokens : typing.Optional[int]

        presence_penalty : typing.Optional[float]

        frequency_penalty : typing.Optional[float]

        logit_bias : typing.Optional[typing.Dict[str, int]]

        user : typing.Optional[str]

        response_format : typing.Optional[ResponseFormat]

        seed : typing.Optional[int]

        tools : typing.Optional[typing.Sequence[Tool]]

        tool_choice : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]

        parallel_tool_calls : typing.Optional[bool]

        store : typing.Optional[bool]

        metadata : typing.Optional[typing.Dict[str, str]]

        reasoning_effort : typing.Optional[str]

        service_tier : typing.Optional[str]

        functions : typing.Optional[typing.Sequence[Function]]

        function_call : typing.Optional[FunctionCall]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ChatCompletionResponse]
            Chat completions response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/private/chat/completions",
            method="POST",
            json={
                "model": model,
                "messages": messages,
                "temperature": temperature,
                "top_p": top_p,
                "n": n,
                "stream": stream,
                "stream_options": convert_and_respect_annotation_metadata(
                    object_=stream_options, annotation=StreamOptions, direction="write"
                ),
                "stop": stop,
                "max_tokens": max_tokens,
                "max_completion_tokens": max_completion_tokens,
                "presence_penalty": presence_penalty,
                "frequency_penalty": frequency_penalty,
                "logit_bias": logit_bias,
                "user": user,
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=ResponseFormat, direction="write"
                ),
                "seed": seed,
                "tools": convert_and_respect_annotation_metadata(
                    object_=tools, annotation=typing.Sequence[Tool], direction="write"
                ),
                "tool_choice": tool_choice,
                "parallel_tool_calls": parallel_tool_calls,
                "store": store,
                "metadata": metadata,
                "reasoning_effort": reasoning_effort,
                "service_tier": service_tier,
                "functions": convert_and_respect_annotation_metadata(
                    object_=functions, annotation=typing.Sequence[Function], direction="write"
                ),
                "function_call": convert_and_respect_annotation_metadata(
                    object_=function_call, annotation=FunctionCall, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ChatCompletionResponse,
                    parse_obj_as(
                        type_=ChatCompletionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawChatCompletionsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create_chat_completions(
        self,
        *,
        model: typing.Optional[str] = OMIT,
        messages: typing.Optional[typing.Sequence[Message]] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        top_p: typing.Optional[float] = OMIT,
        n: typing.Optional[int] = OMIT,
        stream: typing.Optional[bool] = OMIT,
        stream_options: typing.Optional[StreamOptions] = OMIT,
        stop: typing.Optional[typing.Sequence[str]] = OMIT,
        max_tokens: typing.Optional[int] = OMIT,
        max_completion_tokens: typing.Optional[int] = OMIT,
        presence_penalty: typing.Optional[float] = OMIT,
        frequency_penalty: typing.Optional[float] = OMIT,
        logit_bias: typing.Optional[typing.Dict[str, int]] = OMIT,
        user: typing.Optional[str] = OMIT,
        response_format: typing.Optional[ResponseFormat] = OMIT,
        seed: typing.Optional[int] = OMIT,
        tools: typing.Optional[typing.Sequence[Tool]] = OMIT,
        tool_choice: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        parallel_tool_calls: typing.Optional[bool] = OMIT,
        store: typing.Optional[bool] = OMIT,
        metadata: typing.Optional[typing.Dict[str, str]] = OMIT,
        reasoning_effort: typing.Optional[str] = OMIT,
        service_tier: typing.Optional[str] = OMIT,
        functions: typing.Optional[typing.Sequence[Function]] = OMIT,
        function_call: typing.Optional[FunctionCall] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ChatCompletionResponse]:
        """
        Create chat completions

        Parameters
        ----------
        model : typing.Optional[str]

        messages : typing.Optional[typing.Sequence[Message]]

        temperature : typing.Optional[float]

        top_p : typing.Optional[float]

        n : typing.Optional[int]

        stream : typing.Optional[bool]

        stream_options : typing.Optional[StreamOptions]

        stop : typing.Optional[typing.Sequence[str]]

        max_tokens : typing.Optional[int]

        max_completion_tokens : typing.Optional[int]

        presence_penalty : typing.Optional[float]

        frequency_penalty : typing.Optional[float]

        logit_bias : typing.Optional[typing.Dict[str, int]]

        user : typing.Optional[str]

        response_format : typing.Optional[ResponseFormat]

        seed : typing.Optional[int]

        tools : typing.Optional[typing.Sequence[Tool]]

        tool_choice : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]

        parallel_tool_calls : typing.Optional[bool]

        store : typing.Optional[bool]

        metadata : typing.Optional[typing.Dict[str, str]]

        reasoning_effort : typing.Optional[str]

        service_tier : typing.Optional[str]

        functions : typing.Optional[typing.Sequence[Function]]

        function_call : typing.Optional[FunctionCall]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ChatCompletionResponse]
            Chat completions response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/private/chat/completions",
            method="POST",
            json={
                "model": model,
                "messages": messages,
                "temperature": temperature,
                "top_p": top_p,
                "n": n,
                "stream": stream,
                "stream_options": convert_and_respect_annotation_metadata(
                    object_=stream_options, annotation=StreamOptions, direction="write"
                ),
                "stop": stop,
                "max_tokens": max_tokens,
                "max_completion_tokens": max_completion_tokens,
                "presence_penalty": presence_penalty,
                "frequency_penalty": frequency_penalty,
                "logit_bias": logit_bias,
                "user": user,
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=ResponseFormat, direction="write"
                ),
                "seed": seed,
                "tools": convert_and_respect_annotation_metadata(
                    object_=tools, annotation=typing.Sequence[Tool], direction="write"
                ),
                "tool_choice": tool_choice,
                "parallel_tool_calls": parallel_tool_calls,
                "store": store,
                "metadata": metadata,
                "reasoning_effort": reasoning_effort,
                "service_tier": service_tier,
                "functions": convert_and_respect_annotation_metadata(
                    object_=functions, annotation=typing.Sequence[Function], direction="write"
                ),
                "function_call": convert_and_respect_annotation_metadata(
                    object_=function_call, annotation=FunctionCall, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ChatCompletionResponse,
                    parse_obj_as(
                        type_=ChatCompletionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
