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

import typing
from json.decoder import JSONDecodeError

from .. import core
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 ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.audio_model_info import AudioModelInfo
from ..types.diarize_response import DiarizeResponse
from ..types.emotion_detection_response import EmotionDetectionResponse
from ..types.speaker_identify_response import SpeakerIdentifyResponse
from ..types.topic_segment_response import TopicSegmentResponse
from ..types.transcribe_response import TranscribeResponse
from ..types.utterance import Utterance

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


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

    def transcribe(
        self,
        *,
        audio_file: core.File,
        language: typing.Optional[str] = OMIT,
        word_timestamps: typing.Optional[bool] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[TranscribeResponse]:
        """
        Transcribe an audio file to text with timestamps.

        Parameters
        ----------
        audio_file : core.File
            See core.File for more documentation

        language : typing.Optional[str]
            Language code (e.g., en, de, fr). Auto-detected if omitted.

        word_timestamps : typing.Optional[bool]
            Include word-level timestamps in the response

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        HttpResponse[TranscribeResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/audio/transcribe",
            method="POST",
            data={
                "language": language,
                "word_timestamps": word_timestamps,
                "model": model,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TranscribeResponse,
                    parse_obj_as(
                        type_=TranscribeResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    def diarize(
        self,
        *,
        audio_file: core.File,
        num_speakers: typing.Optional[int] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[DiarizeResponse]:
        """
        Segment audio by speaker identity.

        Parameters
        ----------
        audio_file : core.File
            See core.File for more documentation

        num_speakers : typing.Optional[int]
            Expected number of speakers (helps accuracy). Auto-detected if omitted.

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        HttpResponse[DiarizeResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/audio/diarize",
            method="POST",
            data={
                "num_speakers": num_speakers,
                "model": model,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DiarizeResponse,
                    parse_obj_as(
                        type_=DiarizeResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    def detect_emotion(
        self,
        *,
        audio_file: core.File,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[EmotionDetectionResponse]:
        """
        Detect the dominant emotion in a speech audio clip.

        Parameters
        ----------
        audio_file : core.File
            See core.File for more documentation

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        HttpResponse[EmotionDetectionResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/audio/detect-emotion",
            method="POST",
            data={
                "model": model,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EmotionDetectionResponse,
                    parse_obj_as(
                        type_=EmotionDetectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    def identify_speaker(
        self,
        *,
        audio_file: core.File,
        known_embeddings_json: typing.Optional[str] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[SpeakerIdentifyResponse]:
        """
        Identify a speaker by comparing against known voice embeddings, or extract a new embedding.

        Parameters
        ----------
        audio_file : core.File
            See core.File for more documentation

        known_embeddings_json : typing.Optional[str]
            JSON object mapping speaker names to embedding vectors, e.g. {"Alice": [0.1, ...]}. Omit to extract embedding only.

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        HttpResponse[SpeakerIdentifyResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/audio/identify-speaker",
            method="POST",
            data={
                "known_embeddings_json": known_embeddings_json,
                "model": model,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SpeakerIdentifyResponse,
                    parse_obj_as(
                        type_=SpeakerIdentifyResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    def synthesize(
        self,
        *,
        text: str,
        voice: typing.Optional[str] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        repetition_penalty: typing.Optional[float] = OMIT,
        output_format: typing.Optional[str] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.Any]:
        """
        Convert text to speech audio.

        Parameters
        ----------
        text : str
            Text to synthesize. Supports emotion tags: <laugh>, <chuckle>, <sigh>, <cough>, <sniffle>, <groan>, <yawn>, <gasp>.

        voice : typing.Optional[str]
            Voice preset (tara, leah, jess, leo, dan, mia, zac, zoe)

        temperature : typing.Optional[float]
            Sampling temperature. Lower = more deterministic.

        repetition_penalty : typing.Optional[float]
            Repetition penalty factor

        output_format : typing.Optional[str]
            Audio output format (wav or mp3)

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        HttpResponse[typing.Any]
            Audio file in the requested format
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/audio/synthesize",
            method="POST",
            json={
                "text": text,
                "voice": voice,
                "temperature": temperature,
                "repetition_penalty": repetition_penalty,
                "output_format": output_format,
                "model": model,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    def synthesize_stream(
        self,
        *,
        text: str,
        voice: typing.Optional[str] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        repetition_penalty: typing.Optional[float] = OMIT,
        output_format: typing.Optional[str] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.Any]:
        """
        Convert text to speech audio with streaming output.

        Parameters
        ----------
        text : str
            Text to synthesize. Supports emotion tags: <laugh>, <chuckle>, <sigh>, <cough>, <sniffle>, <groan>, <yawn>, <gasp>.

        voice : typing.Optional[str]
            Voice preset (tara, leah, jess, leo, dan, mia, zac, zoe)

        temperature : typing.Optional[float]
            Sampling temperature. Lower = more deterministic.

        repetition_penalty : typing.Optional[float]
            Repetition penalty factor

        output_format : typing.Optional[str]
            Audio output format (wav or mp3)

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        HttpResponse[typing.Any]
            Streaming audio in the requested format
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/audio/synthesize/stream",
            method="POST",
            json={
                "text": text,
                "voice": voice,
                "temperature": temperature,
                "repetition_penalty": repetition_penalty,
                "output_format": output_format,
                "model": model,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    def segment_topics(
        self,
        *,
        utterances: typing.Sequence[Utterance],
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[TopicSegmentResponse]:
        """
        Segment transcript utterances into coherent topics.

        Parameters
        ----------
        utterances : typing.Sequence[Utterance]
            List of utterances to segment into topics

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        HttpResponse[TopicSegmentResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/audio/segment-topics",
            method="POST",
            json={
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[Utterance], direction="write"
                ),
                "model": model,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TopicSegmentResponse,
                    parse_obj_as(
                        type_=TopicSegmentResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    def list_audio_models(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[AudioModelInfo]]:
        """
        List all available audio processing models and their categories.

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

        Returns
        -------
        HttpResponse[typing.List[AudioModelInfo]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/audio/models",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[AudioModelInfo],
                    parse_obj_as(
                        type_=typing.List[AudioModelInfo],  # 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 AsyncRawAudioServicesClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def transcribe(
        self,
        *,
        audio_file: core.File,
        language: typing.Optional[str] = OMIT,
        word_timestamps: typing.Optional[bool] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[TranscribeResponse]:
        """
        Transcribe an audio file to text with timestamps.

        Parameters
        ----------
        audio_file : core.File
            See core.File for more documentation

        language : typing.Optional[str]
            Language code (e.g., en, de, fr). Auto-detected if omitted.

        word_timestamps : typing.Optional[bool]
            Include word-level timestamps in the response

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        AsyncHttpResponse[TranscribeResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/audio/transcribe",
            method="POST",
            data={
                "language": language,
                "word_timestamps": word_timestamps,
                "model": model,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TranscribeResponse,
                    parse_obj_as(
                        type_=TranscribeResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    async def diarize(
        self,
        *,
        audio_file: core.File,
        num_speakers: typing.Optional[int] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[DiarizeResponse]:
        """
        Segment audio by speaker identity.

        Parameters
        ----------
        audio_file : core.File
            See core.File for more documentation

        num_speakers : typing.Optional[int]
            Expected number of speakers (helps accuracy). Auto-detected if omitted.

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        AsyncHttpResponse[DiarizeResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/audio/diarize",
            method="POST",
            data={
                "num_speakers": num_speakers,
                "model": model,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DiarizeResponse,
                    parse_obj_as(
                        type_=DiarizeResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    async def detect_emotion(
        self,
        *,
        audio_file: core.File,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[EmotionDetectionResponse]:
        """
        Detect the dominant emotion in a speech audio clip.

        Parameters
        ----------
        audio_file : core.File
            See core.File for more documentation

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        AsyncHttpResponse[EmotionDetectionResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/audio/detect-emotion",
            method="POST",
            data={
                "model": model,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EmotionDetectionResponse,
                    parse_obj_as(
                        type_=EmotionDetectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    async def identify_speaker(
        self,
        *,
        audio_file: core.File,
        known_embeddings_json: typing.Optional[str] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[SpeakerIdentifyResponse]:
        """
        Identify a speaker by comparing against known voice embeddings, or extract a new embedding.

        Parameters
        ----------
        audio_file : core.File
            See core.File for more documentation

        known_embeddings_json : typing.Optional[str]
            JSON object mapping speaker names to embedding vectors, e.g. {"Alice": [0.1, ...]}. Omit to extract embedding only.

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        AsyncHttpResponse[SpeakerIdentifyResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/audio/identify-speaker",
            method="POST",
            data={
                "known_embeddings_json": known_embeddings_json,
                "model": model,
            },
            files={
                "audio_file": audio_file,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SpeakerIdentifyResponse,
                    parse_obj_as(
                        type_=SpeakerIdentifyResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    async def synthesize(
        self,
        *,
        text: str,
        voice: typing.Optional[str] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        repetition_penalty: typing.Optional[float] = OMIT,
        output_format: typing.Optional[str] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.Any]:
        """
        Convert text to speech audio.

        Parameters
        ----------
        text : str
            Text to synthesize. Supports emotion tags: <laugh>, <chuckle>, <sigh>, <cough>, <sniffle>, <groan>, <yawn>, <gasp>.

        voice : typing.Optional[str]
            Voice preset (tara, leah, jess, leo, dan, mia, zac, zoe)

        temperature : typing.Optional[float]
            Sampling temperature. Lower = more deterministic.

        repetition_penalty : typing.Optional[float]
            Repetition penalty factor

        output_format : typing.Optional[str]
            Audio output format (wav or mp3)

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        AsyncHttpResponse[typing.Any]
            Audio file in the requested format
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/audio/synthesize",
            method="POST",
            json={
                "text": text,
                "voice": voice,
                "temperature": temperature,
                "repetition_penalty": repetition_penalty,
                "output_format": output_format,
                "model": model,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    async def synthesize_stream(
        self,
        *,
        text: str,
        voice: typing.Optional[str] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        repetition_penalty: typing.Optional[float] = OMIT,
        output_format: typing.Optional[str] = OMIT,
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.Any]:
        """
        Convert text to speech audio with streaming output.

        Parameters
        ----------
        text : str
            Text to synthesize. Supports emotion tags: <laugh>, <chuckle>, <sigh>, <cough>, <sniffle>, <groan>, <yawn>, <gasp>.

        voice : typing.Optional[str]
            Voice preset (tara, leah, jess, leo, dan, mia, zac, zoe)

        temperature : typing.Optional[float]
            Sampling temperature. Lower = more deterministic.

        repetition_penalty : typing.Optional[float]
            Repetition penalty factor

        output_format : typing.Optional[str]
            Audio output format (wav or mp3)

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        AsyncHttpResponse[typing.Any]
            Streaming audio in the requested format
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/audio/synthesize/stream",
            method="POST",
            json={
                "text": text,
                "voice": voice,
                "temperature": temperature,
                "repetition_penalty": repetition_penalty,
                "output_format": output_format,
                "model": model,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    async def segment_topics(
        self,
        *,
        utterances: typing.Sequence[Utterance],
        model: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[TopicSegmentResponse]:
        """
        Segment transcript utterances into coherent topics.

        Parameters
        ----------
        utterances : typing.Sequence[Utterance]
            List of utterances to segment into topics

        model : typing.Optional[str]
            Model key override. Uses platform default if omitted.

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

        Returns
        -------
        AsyncHttpResponse[TopicSegmentResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/audio/segment-topics",
            method="POST",
            json={
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[Utterance], direction="write"
                ),
                "model": model,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TopicSegmentResponse,
                    parse_obj_as(
                        type_=TopicSegmentResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)

    async def list_audio_models(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[AudioModelInfo]]:
        """
        List all available audio processing models and their categories.

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

        Returns
        -------
        AsyncHttpResponse[typing.List[AudioModelInfo]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/audio/models",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[AudioModelInfo],
                    parse_obj_as(
                        type_=typing.List[AudioModelInfo],  # 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)
