# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from __future__ import annotations

from typing import Iterable, Optional
from typing_extensions import Literal

import httpx

from ..types import assistant_create_params, assistant_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
    to_raw_response_wrapper,
    to_streamed_response_wrapper,
    async_to_raw_response_wrapper,
    async_to_streamed_response_wrapper,
)
from .._base_client import make_request_options
from ..types.assistant_list_response import AssistantListResponse
from ..types.assistant_create_response import AssistantCreateResponse
from ..types.assistant_delete_response import AssistantDeleteResponse
from ..types.assistant_update_response import AssistantUpdateResponse
from ..types.assistant_retrieve_response import AssistantRetrieveResponse

__all__ = ["AssistantsResource", "AsyncAssistantsResource"]


class AssistantsResource(SyncAPIResource):
    @cached_property
    def with_raw_response(self) -> AssistantsResourceWithRawResponse:
        """
        This property can be used as a prefix for any HTTP method call to return
        the raw response object instead of the parsed content.

        For more information, see https://www.github.com/revoxai/revox-python#accessing-raw-response-data-eg-headers
        """
        return AssistantsResourceWithRawResponse(self)

    @cached_property
    def with_streaming_response(self) -> AssistantsResourceWithStreamingResponse:
        """
        An alternative to `.with_raw_response` that doesn't eagerly read the response body.

        For more information, see https://www.github.com/revoxai/revox-python#with_streaming_response
        """
        return AssistantsResourceWithStreamingResponse(self)

    def create(
        self,
        *,
        name: str,
        prompt: str,
        background_sound: Optional[Literal["audio/office.ogg"]] | Omit = omit,
        calendly: assistant_create_params.Calendly | Omit = omit,
        call_retry_config: assistant_create_params.CallRetryConfig | Omit = omit,
        end_of_call_sentence: str | Omit = omit,
        faq_items: Iterable[assistant_create_params.FaqItem] | Omit = omit,
        first_sentence: str | Omit = omit,
        first_sentence_delay_ms: int | Omit = omit,
        first_sentence_mode: Literal["generated", "static", "none"] | Omit = omit,
        ivr_navigation_enabled: bool | Omit = omit,
        llm_model: assistant_create_params.LlmModel | Omit = omit,
        max_call_duration_secs: float | Omit = omit,
        structured_output_config: Iterable[assistant_create_params.StructuredOutputConfig] | Omit = omit,
        transfer_phone_number: Optional[str] | Omit = omit,
        voice: assistant_create_params.Voice | Omit = omit,
        voicemail_message: Optional[str] | Omit = omit,
        webhook_url: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantCreateResponse:
        """
        Create a new AI assistant with a custom prompt, voice, and behavior
        configuration. Assistants define how the AI agent behaves during calls,
        including the system prompt given to the LLM, the first sentence spoken, the
        voice provider and voice ID (Cartesia or ElevenLabs), and end-of-call behavior.
        Once created, reference the assistant by its ID when placing calls.

        Args:
          prompt: The prompt to use for the call. This will be given to the LLM (gpt-4.1)

          background_sound: The background sound to play during the call. Useful to give the impression that
              your AI agent is in an office, in the street, or anywhere else you want.

          call_retry_config: Configuration for call retry behavior including time windows, delays, and max
              iterations. If not provided, defaults will be used.

          end_of_call_sentence: Optional message to say when the agent decides to end the call.

          faq_items: FAQ items to associate with this assistant. When provided, replaces all existing
              FAQ items.

          first_sentence: The first sentence to use for the call. This will be given to the LLM

          first_sentence_delay_ms: Delay in milliseconds before speaking the first sentence. Default: 400.

          first_sentence_mode: How the first sentence should be handled. "generated" means the LLM will
              generate a response based on the first_sentence instruction. "static" means the
              first_sentence will be spoken exactly as provided. "none" means the agent will
              not speak first and will wait for the user.

          ivr_navigation_enabled: Enable IVR navigation tools. When enabled, the assistant can send DTMF tones and
              skip turns to navigate phone menus.

          max_call_duration_secs: The maximum duration of the call in seconds. This is the maximum time the call
              will be allowed to run.

          structured_output_config: The structured output config to use for the call. This is used to extract the
              data from the call (like email, name, company name, etc.).

          transfer_phone_number: Phone number to transfer calls to when users request to speak to a human agent
              in E.164 format (e.g. +1234567890).

          voice: The voice to use for the call. You can get the list of voices using the /voices
              endpoint

          voicemail_message: If set, when voicemail is detected the agent will speak this message then hang
              up; if null, hang up immediately.

          webhook_url: The webhook URL to call when the call is completed.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        return self._post(
            "/assistants",
            body=maybe_transform(
                {
                    "name": name,
                    "prompt": prompt,
                    "background_sound": background_sound,
                    "calendly": calendly,
                    "call_retry_config": call_retry_config,
                    "end_of_call_sentence": end_of_call_sentence,
                    "faq_items": faq_items,
                    "first_sentence": first_sentence,
                    "first_sentence_delay_ms": first_sentence_delay_ms,
                    "first_sentence_mode": first_sentence_mode,
                    "ivr_navigation_enabled": ivr_navigation_enabled,
                    "llm_model": llm_model,
                    "max_call_duration_secs": max_call_duration_secs,
                    "structured_output_config": structured_output_config,
                    "transfer_phone_number": transfer_phone_number,
                    "voice": voice,
                    "voicemail_message": voicemail_message,
                    "webhook_url": webhook_url,
                },
                assistant_create_params.AssistantCreateParams,
            ),
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantCreateResponse,
        )

    def retrieve(
        self,
        id: str,
        *,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantRetrieveResponse:
        """Retrieve a single assistant by its unique ID.

        Returns the full assistant
        configuration including prompt, voice settings, and first sentence mode. Useful
        for inspecting an assistant's current setup before updating it or placing a
        call.

        Args:
          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not id:
            raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
        return self._get(
            f"/assistants/{id}",
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantRetrieveResponse,
        )

    def update(
        self,
        id: str,
        *,
        background_sound: Optional[Literal["audio/office.ogg"]] | Omit = omit,
        calendly: assistant_update_params.Calendly | Omit = omit,
        call_retry_config: assistant_update_params.CallRetryConfig | Omit = omit,
        end_of_call_sentence: str | Omit = omit,
        faq_items: Iterable[assistant_update_params.FaqItem] | Omit = omit,
        first_sentence: str | Omit = omit,
        first_sentence_delay_ms: int | Omit = omit,
        first_sentence_mode: Literal["generated", "static", "none"] | Omit = omit,
        ivr_navigation_enabled: bool | Omit = omit,
        llm_model: assistant_update_params.LlmModel | Omit = omit,
        max_call_duration_secs: float | Omit = omit,
        name: str | Omit = omit,
        prompt: str | Omit = omit,
        structured_output_config: Iterable[assistant_update_params.StructuredOutputConfig] | Omit = omit,
        transfer_phone_number: Optional[str] | Omit = omit,
        voice: assistant_update_params.Voice | Omit = omit,
        voicemail_message: Optional[str] | Omit = omit,
        webhook_url: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantUpdateResponse:
        """Update one or more fields on an existing assistant.

        Supports partial updates —
        only the fields you include in the request body will be changed. You can update
        the prompt, voice, first sentence, name, or any other assistant property without
        affecting the rest of the configuration.

        Args:
          background_sound: The background sound to play during the call. Useful to give the impression that
              your AI agent is in an office, in the street, or anywhere else you want.

          call_retry_config: Configuration for call retry behavior including time windows, delays, and max
              iterations. If not provided, defaults will be used.

          end_of_call_sentence: Optional message to say when the agent decides to end the call.

          faq_items: FAQ items to associate with this assistant. When provided, replaces all existing
              FAQ items.

          first_sentence: The first sentence to use for the call. This will be given to the LLM

          first_sentence_delay_ms: Delay in milliseconds before speaking the first sentence. Default: 400.

          first_sentence_mode: How the first sentence should be handled. "generated" means the LLM will
              generate a response based on the first_sentence instruction. "static" means the
              first_sentence will be spoken exactly as provided. "none" means the agent will
              not speak first and will wait for the user.

          ivr_navigation_enabled: Enable IVR navigation tools. When enabled, the assistant can send DTMF tones and
              skip turns to navigate phone menus.

          max_call_duration_secs: The maximum duration of the call in seconds. This is the maximum time the call
              will be allowed to run.

          prompt: The prompt to use for the call. This will be given to the LLM (gpt-4.1)

          structured_output_config: The structured output config to use for the call. This is used to extract the
              data from the call (like email, name, company name, etc.).

          transfer_phone_number: Phone number to transfer calls to when users request to speak to a human agent
              in E.164 format (e.g. +1234567890).

          voice: The voice to use for the call. You can get the list of voices using the /voices
              endpoint

          voicemail_message: If set, when voicemail is detected the agent will speak this message then hang
              up; if null, hang up immediately.

          webhook_url: The webhook URL to call when the call is completed.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not id:
            raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
        return self._patch(
            f"/assistants/{id}",
            body=maybe_transform(
                {
                    "background_sound": background_sound,
                    "calendly": calendly,
                    "call_retry_config": call_retry_config,
                    "end_of_call_sentence": end_of_call_sentence,
                    "faq_items": faq_items,
                    "first_sentence": first_sentence,
                    "first_sentence_delay_ms": first_sentence_delay_ms,
                    "first_sentence_mode": first_sentence_mode,
                    "ivr_navigation_enabled": ivr_navigation_enabled,
                    "llm_model": llm_model,
                    "max_call_duration_secs": max_call_duration_secs,
                    "name": name,
                    "prompt": prompt,
                    "structured_output_config": structured_output_config,
                    "transfer_phone_number": transfer_phone_number,
                    "voice": voice,
                    "voicemail_message": voicemail_message,
                    "webhook_url": webhook_url,
                },
                assistant_update_params.AssistantUpdateParams,
            ),
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantUpdateResponse,
        )

    def list(
        self,
        *,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantListResponse:
        """Retrieve all assistants associated with your account.

        Each assistant in the
        response includes its full configuration: prompt, voice settings, and first
        sentence. Use this endpoint to list available assistants before placing calls.
        """
        return self._get(
            "/assistants",
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantListResponse,
        )

    def delete(
        self,
        id: str,
        *,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantDeleteResponse:
        """Permanently delete an assistant by its ID.

        Any future calls referencing this
        assistant ID will fail. Existing call records that used this assistant are not
        affected.

        Args:
          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not id:
            raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
        return self._delete(
            f"/assistants/{id}",
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantDeleteResponse,
        )


class AsyncAssistantsResource(AsyncAPIResource):
    @cached_property
    def with_raw_response(self) -> AsyncAssistantsResourceWithRawResponse:
        """
        This property can be used as a prefix for any HTTP method call to return
        the raw response object instead of the parsed content.

        For more information, see https://www.github.com/revoxai/revox-python#accessing-raw-response-data-eg-headers
        """
        return AsyncAssistantsResourceWithRawResponse(self)

    @cached_property
    def with_streaming_response(self) -> AsyncAssistantsResourceWithStreamingResponse:
        """
        An alternative to `.with_raw_response` that doesn't eagerly read the response body.

        For more information, see https://www.github.com/revoxai/revox-python#with_streaming_response
        """
        return AsyncAssistantsResourceWithStreamingResponse(self)

    async def create(
        self,
        *,
        name: str,
        prompt: str,
        background_sound: Optional[Literal["audio/office.ogg"]] | Omit = omit,
        calendly: assistant_create_params.Calendly | Omit = omit,
        call_retry_config: assistant_create_params.CallRetryConfig | Omit = omit,
        end_of_call_sentence: str | Omit = omit,
        faq_items: Iterable[assistant_create_params.FaqItem] | Omit = omit,
        first_sentence: str | Omit = omit,
        first_sentence_delay_ms: int | Omit = omit,
        first_sentence_mode: Literal["generated", "static", "none"] | Omit = omit,
        ivr_navigation_enabled: bool | Omit = omit,
        llm_model: assistant_create_params.LlmModel | Omit = omit,
        max_call_duration_secs: float | Omit = omit,
        structured_output_config: Iterable[assistant_create_params.StructuredOutputConfig] | Omit = omit,
        transfer_phone_number: Optional[str] | Omit = omit,
        voice: assistant_create_params.Voice | Omit = omit,
        voicemail_message: Optional[str] | Omit = omit,
        webhook_url: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantCreateResponse:
        """
        Create a new AI assistant with a custom prompt, voice, and behavior
        configuration. Assistants define how the AI agent behaves during calls,
        including the system prompt given to the LLM, the first sentence spoken, the
        voice provider and voice ID (Cartesia or ElevenLabs), and end-of-call behavior.
        Once created, reference the assistant by its ID when placing calls.

        Args:
          prompt: The prompt to use for the call. This will be given to the LLM (gpt-4.1)

          background_sound: The background sound to play during the call. Useful to give the impression that
              your AI agent is in an office, in the street, or anywhere else you want.

          call_retry_config: Configuration for call retry behavior including time windows, delays, and max
              iterations. If not provided, defaults will be used.

          end_of_call_sentence: Optional message to say when the agent decides to end the call.

          faq_items: FAQ items to associate with this assistant. When provided, replaces all existing
              FAQ items.

          first_sentence: The first sentence to use for the call. This will be given to the LLM

          first_sentence_delay_ms: Delay in milliseconds before speaking the first sentence. Default: 400.

          first_sentence_mode: How the first sentence should be handled. "generated" means the LLM will
              generate a response based on the first_sentence instruction. "static" means the
              first_sentence will be spoken exactly as provided. "none" means the agent will
              not speak first and will wait for the user.

          ivr_navigation_enabled: Enable IVR navigation tools. When enabled, the assistant can send DTMF tones and
              skip turns to navigate phone menus.

          max_call_duration_secs: The maximum duration of the call in seconds. This is the maximum time the call
              will be allowed to run.

          structured_output_config: The structured output config to use for the call. This is used to extract the
              data from the call (like email, name, company name, etc.).

          transfer_phone_number: Phone number to transfer calls to when users request to speak to a human agent
              in E.164 format (e.g. +1234567890).

          voice: The voice to use for the call. You can get the list of voices using the /voices
              endpoint

          voicemail_message: If set, when voicemail is detected the agent will speak this message then hang
              up; if null, hang up immediately.

          webhook_url: The webhook URL to call when the call is completed.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        return await self._post(
            "/assistants",
            body=await async_maybe_transform(
                {
                    "name": name,
                    "prompt": prompt,
                    "background_sound": background_sound,
                    "calendly": calendly,
                    "call_retry_config": call_retry_config,
                    "end_of_call_sentence": end_of_call_sentence,
                    "faq_items": faq_items,
                    "first_sentence": first_sentence,
                    "first_sentence_delay_ms": first_sentence_delay_ms,
                    "first_sentence_mode": first_sentence_mode,
                    "ivr_navigation_enabled": ivr_navigation_enabled,
                    "llm_model": llm_model,
                    "max_call_duration_secs": max_call_duration_secs,
                    "structured_output_config": structured_output_config,
                    "transfer_phone_number": transfer_phone_number,
                    "voice": voice,
                    "voicemail_message": voicemail_message,
                    "webhook_url": webhook_url,
                },
                assistant_create_params.AssistantCreateParams,
            ),
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantCreateResponse,
        )

    async def retrieve(
        self,
        id: str,
        *,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantRetrieveResponse:
        """Retrieve a single assistant by its unique ID.

        Returns the full assistant
        configuration including prompt, voice settings, and first sentence mode. Useful
        for inspecting an assistant's current setup before updating it or placing a
        call.

        Args:
          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not id:
            raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
        return await self._get(
            f"/assistants/{id}",
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantRetrieveResponse,
        )

    async def update(
        self,
        id: str,
        *,
        background_sound: Optional[Literal["audio/office.ogg"]] | Omit = omit,
        calendly: assistant_update_params.Calendly | Omit = omit,
        call_retry_config: assistant_update_params.CallRetryConfig | Omit = omit,
        end_of_call_sentence: str | Omit = omit,
        faq_items: Iterable[assistant_update_params.FaqItem] | Omit = omit,
        first_sentence: str | Omit = omit,
        first_sentence_delay_ms: int | Omit = omit,
        first_sentence_mode: Literal["generated", "static", "none"] | Omit = omit,
        ivr_navigation_enabled: bool | Omit = omit,
        llm_model: assistant_update_params.LlmModel | Omit = omit,
        max_call_duration_secs: float | Omit = omit,
        name: str | Omit = omit,
        prompt: str | Omit = omit,
        structured_output_config: Iterable[assistant_update_params.StructuredOutputConfig] | Omit = omit,
        transfer_phone_number: Optional[str] | Omit = omit,
        voice: assistant_update_params.Voice | Omit = omit,
        voicemail_message: Optional[str] | Omit = omit,
        webhook_url: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantUpdateResponse:
        """Update one or more fields on an existing assistant.

        Supports partial updates —
        only the fields you include in the request body will be changed. You can update
        the prompt, voice, first sentence, name, or any other assistant property without
        affecting the rest of the configuration.

        Args:
          background_sound: The background sound to play during the call. Useful to give the impression that
              your AI agent is in an office, in the street, or anywhere else you want.

          call_retry_config: Configuration for call retry behavior including time windows, delays, and max
              iterations. If not provided, defaults will be used.

          end_of_call_sentence: Optional message to say when the agent decides to end the call.

          faq_items: FAQ items to associate with this assistant. When provided, replaces all existing
              FAQ items.

          first_sentence: The first sentence to use for the call. This will be given to the LLM

          first_sentence_delay_ms: Delay in milliseconds before speaking the first sentence. Default: 400.

          first_sentence_mode: How the first sentence should be handled. "generated" means the LLM will
              generate a response based on the first_sentence instruction. "static" means the
              first_sentence will be spoken exactly as provided. "none" means the agent will
              not speak first and will wait for the user.

          ivr_navigation_enabled: Enable IVR navigation tools. When enabled, the assistant can send DTMF tones and
              skip turns to navigate phone menus.

          max_call_duration_secs: The maximum duration of the call in seconds. This is the maximum time the call
              will be allowed to run.

          prompt: The prompt to use for the call. This will be given to the LLM (gpt-4.1)

          structured_output_config: The structured output config to use for the call. This is used to extract the
              data from the call (like email, name, company name, etc.).

          transfer_phone_number: Phone number to transfer calls to when users request to speak to a human agent
              in E.164 format (e.g. +1234567890).

          voice: The voice to use for the call. You can get the list of voices using the /voices
              endpoint

          voicemail_message: If set, when voicemail is detected the agent will speak this message then hang
              up; if null, hang up immediately.

          webhook_url: The webhook URL to call when the call is completed.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not id:
            raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
        return await self._patch(
            f"/assistants/{id}",
            body=await async_maybe_transform(
                {
                    "background_sound": background_sound,
                    "calendly": calendly,
                    "call_retry_config": call_retry_config,
                    "end_of_call_sentence": end_of_call_sentence,
                    "faq_items": faq_items,
                    "first_sentence": first_sentence,
                    "first_sentence_delay_ms": first_sentence_delay_ms,
                    "first_sentence_mode": first_sentence_mode,
                    "ivr_navigation_enabled": ivr_navigation_enabled,
                    "llm_model": llm_model,
                    "max_call_duration_secs": max_call_duration_secs,
                    "name": name,
                    "prompt": prompt,
                    "structured_output_config": structured_output_config,
                    "transfer_phone_number": transfer_phone_number,
                    "voice": voice,
                    "voicemail_message": voicemail_message,
                    "webhook_url": webhook_url,
                },
                assistant_update_params.AssistantUpdateParams,
            ),
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantUpdateResponse,
        )

    async def list(
        self,
        *,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantListResponse:
        """Retrieve all assistants associated with your account.

        Each assistant in the
        response includes its full configuration: prompt, voice settings, and first
        sentence. Use this endpoint to list available assistants before placing calls.
        """
        return await self._get(
            "/assistants",
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantListResponse,
        )

    async def delete(
        self,
        id: str,
        *,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx.Timeout | None | NotGiven = not_given,
    ) -> AssistantDeleteResponse:
        """Permanently delete an assistant by its ID.

        Any future calls referencing this
        assistant ID will fail. Existing call records that used this assistant are not
        affected.

        Args:
          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not id:
            raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
        return await self._delete(
            f"/assistants/{id}",
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=AssistantDeleteResponse,
        )


class AssistantsResourceWithRawResponse:
    def __init__(self, assistants: AssistantsResource) -> None:
        self._assistants = assistants

        self.create = to_raw_response_wrapper(
            assistants.create,
        )
        self.retrieve = to_raw_response_wrapper(
            assistants.retrieve,
        )
        self.update = to_raw_response_wrapper(
            assistants.update,
        )
        self.list = to_raw_response_wrapper(
            assistants.list,
        )
        self.delete = to_raw_response_wrapper(
            assistants.delete,
        )


class AsyncAssistantsResourceWithRawResponse:
    def __init__(self, assistants: AsyncAssistantsResource) -> None:
        self._assistants = assistants

        self.create = async_to_raw_response_wrapper(
            assistants.create,
        )
        self.retrieve = async_to_raw_response_wrapper(
            assistants.retrieve,
        )
        self.update = async_to_raw_response_wrapper(
            assistants.update,
        )
        self.list = async_to_raw_response_wrapper(
            assistants.list,
        )
        self.delete = async_to_raw_response_wrapper(
            assistants.delete,
        )


class AssistantsResourceWithStreamingResponse:
    def __init__(self, assistants: AssistantsResource) -> None:
        self._assistants = assistants

        self.create = to_streamed_response_wrapper(
            assistants.create,
        )
        self.retrieve = to_streamed_response_wrapper(
            assistants.retrieve,
        )
        self.update = to_streamed_response_wrapper(
            assistants.update,
        )
        self.list = to_streamed_response_wrapper(
            assistants.list,
        )
        self.delete = to_streamed_response_wrapper(
            assistants.delete,
        )


class AsyncAssistantsResourceWithStreamingResponse:
    def __init__(self, assistants: AsyncAssistantsResource) -> None:
        self._assistants = assistants

        self.create = async_to_streamed_response_wrapper(
            assistants.create,
        )
        self.retrieve = async_to_streamed_response_wrapper(
            assistants.retrieve,
        )
        self.update = async_to_streamed_response_wrapper(
            assistants.update,
        )
        self.list = async_to_streamed_response_wrapper(
            assistants.list,
        )
        self.delete = async_to_streamed_response_wrapper(
            assistants.delete,
        )
