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

from __future__ import annotations

import typing

from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.request_options import RequestOptions
from ...types.adhoc_agent_config_override_for_test_request_model import AdhocAgentConfigOverrideForTestRequestModel
from ...types.agent_platform_settings_request_model import AgentPlatformSettingsRequestModel
from ...types.agent_simulated_chat_test_response_model import AgentSimulatedChatTestResponseModel
from ...types.agent_sort_by import AgentSortBy
from ...types.agent_workflow_request_model import AgentWorkflowRequestModel
from ...types.conversation_simulation_specification import ConversationSimulationSpecification
from ...types.conversational_config import ConversationalConfig
from ...types.create_agent_response_model import CreateAgentResponseModel
from ...types.get_agent_response_model import GetAgentResponseModel
from ...types.get_agents_page_response_model import GetAgentsPageResponseModel
from ...types.get_test_suite_invocation_response_model import GetTestSuiteInvocationResponseModel
from ...types.prompt_evaluation_criteria import PromptEvaluationCriteria
from ...types.single_test_run_request_model import SingleTestRunRequestModel
from ...types.sort_direction import SortDirection
from .raw_client import AsyncRawAgentsClient, RawAgentsClient

if typing.TYPE_CHECKING:
    from .branches.client import AsyncBranchesClient, BranchesClient
    from .deployments.client import AsyncDeploymentsClient, DeploymentsClient
    from .drafts.client import AsyncDraftsClient, DraftsClient
    from .knowledge_base.client import AsyncKnowledgeBaseClient, KnowledgeBaseClient
    from .link.client import AsyncLinkClient, LinkClient
    from .llm_usage.client import AsyncLlmUsageClient, LlmUsageClient
    from .summaries.client import AsyncSummariesClient, SummariesClient
    from .versions.client import AsyncVersionsClient, VersionsClient
    from .widget.client import AsyncWidgetClient, WidgetClient
# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class AgentsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawAgentsClient(client_wrapper=client_wrapper)
        self._client_wrapper = client_wrapper
        self._summaries: typing.Optional[SummariesClient] = None
        self._widget: typing.Optional[WidgetClient] = None
        self._link: typing.Optional[LinkClient] = None
        self._knowledge_base: typing.Optional[KnowledgeBaseClient] = None
        self._llm_usage: typing.Optional[LlmUsageClient] = None
        self._branches: typing.Optional[BranchesClient] = None
        self._versions: typing.Optional[VersionsClient] = None
        self._deployments: typing.Optional[DeploymentsClient] = None
        self._drafts: typing.Optional[DraftsClient] = None

    @property
    def with_raw_response(self) -> RawAgentsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawAgentsClient
        """
        return self._raw_client

    def create(
        self,
        *,
        conversation_config: ConversationalConfig,
        enable_versioning: typing.Optional[bool] = None,
        platform_settings: typing.Optional[AgentPlatformSettingsRequestModel] = OMIT,
        workflow: typing.Optional[AgentWorkflowRequestModel] = OMIT,
        name: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateAgentResponseModel:
        """
        Create an agent from a config object

        Parameters
        ----------
        conversation_config : ConversationalConfig
            Conversation configuration for an agent

        enable_versioning : typing.Optional[bool]
            Deprecated: all agents are versioned. This parameter is ignored.

        platform_settings : typing.Optional[AgentPlatformSettingsRequestModel]
            Platform settings for the agent are all settings that aren't related to the conversation orchestration and content.

        workflow : typing.Optional[AgentWorkflowRequestModel]
            Workflow for the agent. This is used to define the flow of the conversation and how the agent interacts with tools.

        name : typing.Optional[str]
            A name to make the agent easier to find

        tags : typing.Optional[typing.Sequence[str]]
            Tags to help classify and filter the agent

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

        Returns
        -------
        CreateAgentResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ConversationalConfig, ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.create(
            enable_versioning=True,
            conversation_config=ConversationalConfig(),
        )
        """
        _response = self._raw_client.create(
            conversation_config=conversation_config,
            enable_versioning=enable_versioning,
            platform_settings=platform_settings,
            workflow=workflow,
            name=name,
            tags=tags,
            request_options=request_options,
        )
        return _response.data

    def get(
        self,
        agent_id: str,
        *,
        version_id: typing.Optional[str] = None,
        branch_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetAgentResponseModel:
        """
        Retrieve config for an agent

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        version_id : typing.Optional[str]
            The ID of the agent version to use

        branch_id : typing.Optional[str]
            The ID of the branch to use

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

        Returns
        -------
        GetAgentResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.get(
            agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
            version_id="version_id",
            branch_id="branch_id",
        )
        """
        _response = self._raw_client.get(
            agent_id, version_id=version_id, branch_id=branch_id, request_options=request_options
        )
        return _response.data

    def delete(self, agent_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete an agent

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

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

        Returns
        -------
        None

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.delete(
            agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
        )
        """
        _response = self._raw_client.delete(agent_id, request_options=request_options)
        return _response.data

    def update(
        self,
        agent_id: str,
        *,
        enable_versioning_if_not_enabled: typing.Optional[bool] = None,
        branch_id: typing.Optional[str] = None,
        conversation_config: typing.Optional[ConversationalConfig] = OMIT,
        platform_settings: typing.Optional[AgentPlatformSettingsRequestModel] = OMIT,
        workflow: typing.Optional[AgentWorkflowRequestModel] = OMIT,
        name: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        version_description: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetAgentResponseModel:
        """
        Patches an Agent settings

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        enable_versioning_if_not_enabled : typing.Optional[bool]
            Deprecated: all agents are versioned. This parameter is ignored.

        branch_id : typing.Optional[str]
            The ID of the branch to use

        conversation_config : typing.Optional[ConversationalConfig]
            Conversation configuration for an agent

        platform_settings : typing.Optional[AgentPlatformSettingsRequestModel]
            Platform settings for the agent are all settings that aren't related to the conversation orchestration and content.

        workflow : typing.Optional[AgentWorkflowRequestModel]
            Workflow for the agent. This is used to define the flow of the conversation and how the agent interacts with tools.

        name : typing.Optional[str]
            A name to make the agent easier to find

        tags : typing.Optional[typing.Sequence[str]]
            Tags to help classify and filter the agent

        version_description : typing.Optional[str]
            Description for this version when publishing changes (only applicable for versioned agents)

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

        Returns
        -------
        GetAgentResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.update(
            agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
            enable_versioning_if_not_enabled=True,
            branch_id="branch_id",
        )
        """
        _response = self._raw_client.update(
            agent_id,
            enable_versioning_if_not_enabled=enable_versioning_if_not_enabled,
            branch_id=branch_id,
            conversation_config=conversation_config,
            platform_settings=platform_settings,
            workflow=workflow,
            name=name,
            tags=tags,
            version_description=version_description,
            request_options=request_options,
        )
        return _response.data

    def list(
        self,
        *,
        page_size: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        archived: typing.Optional[bool] = None,
        show_only_owned_agents: typing.Optional[bool] = None,
        created_by_user_id: typing.Optional[str] = None,
        sort_direction: typing.Optional[SortDirection] = None,
        sort_by: typing.Optional[AgentSortBy] = None,
        cursor: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetAgentsPageResponseModel:
        """
        Returns a list of your agents and their metadata.

        Parameters
        ----------
        page_size : typing.Optional[int]
            How many Agents to return at maximum. Can not exceed 100, defaults to 30.

        search : typing.Optional[str]
            Search by agents name.

        archived : typing.Optional[bool]
            Filter agents by archived status

        show_only_owned_agents : typing.Optional[bool]
            If set to true, the endpoint will omit any agents that were shared with you by someone else and include only the ones you own. Deprecated: use created_by_user_id instead.

        created_by_user_id : typing.Optional[str]
            Filter agents by creator user ID. When set, only agents created by this user are returned. Takes precedence over show_only_owned_agents. Use '@me' to refer to the authenticated user.

        sort_direction : typing.Optional[SortDirection]
            The direction to sort the results

        sort_by : typing.Optional[AgentSortBy]
            The field to sort the results by

        cursor : typing.Optional[str]
            Used for fetching next page. Cursor is returned in the response.

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

        Returns
        -------
        GetAgentsPageResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.list(
            page_size=1,
            search="search",
            archived=True,
            show_only_owned_agents=True,
            created_by_user_id="created_by_user_id",
            sort_direction="asc",
            sort_by="name",
            cursor="cursor",
        )
        """
        _response = self._raw_client.list(
            page_size=page_size,
            search=search,
            archived=archived,
            show_only_owned_agents=show_only_owned_agents,
            created_by_user_id=created_by_user_id,
            sort_direction=sort_direction,
            sort_by=sort_by,
            cursor=cursor,
            request_options=request_options,
        )
        return _response.data

    def duplicate(
        self,
        agent_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateAgentResponseModel:
        """
        Create a new agent by duplicating an existing one

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        name : typing.Optional[str]
            A name to make the agent easier to find

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

        Returns
        -------
        CreateAgentResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.duplicate(
            agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
        )
        """
        _response = self._raw_client.duplicate(agent_id, name=name, request_options=request_options)
        return _response.data

    def simulate_conversation(
        self,
        agent_id: str,
        *,
        simulation_specification: ConversationSimulationSpecification,
        extra_evaluation_criteria: typing.Optional[typing.Sequence[PromptEvaluationCriteria]] = OMIT,
        new_turns_limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentSimulatedChatTestResponseModel:
        """
        Run a conversation between the agent and a simulated user.

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        simulation_specification : ConversationSimulationSpecification
            A specification detailing how the conversation should be simulated

        extra_evaluation_criteria : typing.Optional[typing.Sequence[PromptEvaluationCriteria]]
            A list of evaluation criteria to test

        new_turns_limit : typing.Optional[int]
            Maximum number of new turns to generate in the conversation simulation

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

        Returns
        -------
        AgentSimulatedChatTestResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import (
            AgentConfig,
            ConversationSimulationSpecification,
            ElevenLabs,
        )

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.simulate_conversation(
            agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
            simulation_specification=ConversationSimulationSpecification(
                simulated_user_config=AgentConfig(
                    first_message="Hello, how can I help you today?",
                    language="en",
                    disable_first_message_interruptions=False,
                ),
            ),
        )
        """
        _response = self._raw_client.simulate_conversation(
            agent_id,
            simulation_specification=simulation_specification,
            extra_evaluation_criteria=extra_evaluation_criteria,
            new_turns_limit=new_turns_limit,
            request_options=request_options,
        )
        return _response.data

    def simulate_conversation_stream(
        self,
        agent_id: str,
        *,
        simulation_specification: ConversationSimulationSpecification,
        extra_evaluation_criteria: typing.Optional[typing.Sequence[PromptEvaluationCriteria]] = OMIT,
        new_turns_limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Run a conversation between the agent and a simulated user and stream back the response. Response is streamed back as partial lists of messages that should be concatenated and once the conversation has complete a single final message with the conversation analysis will be sent.

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        simulation_specification : ConversationSimulationSpecification
            A specification detailing how the conversation should be simulated

        extra_evaluation_criteria : typing.Optional[typing.Sequence[PromptEvaluationCriteria]]
            A list of evaluation criteria to test

        new_turns_limit : typing.Optional[int]
            Maximum number of new turns to generate in the conversation simulation

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

        Returns
        -------
        None

        Examples
        --------
        from elevenlabs import (
            AgentConfig,
            ConversationSimulationSpecification,
            ElevenLabs,
        )

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.simulate_conversation_stream(
            agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
            simulation_specification=ConversationSimulationSpecification(
                simulated_user_config=AgentConfig(
                    first_message="Hello, how can I help you today?",
                    language="en",
                    disable_first_message_interruptions=False,
                ),
            ),
        )
        """
        _response = self._raw_client.simulate_conversation_stream(
            agent_id,
            simulation_specification=simulation_specification,
            extra_evaluation_criteria=extra_evaluation_criteria,
            new_turns_limit=new_turns_limit,
            request_options=request_options,
        )
        return _response.data

    def run_tests(
        self,
        agent_id: str,
        *,
        tests: typing.Sequence[SingleTestRunRequestModel],
        agent_config_override: typing.Optional[AdhocAgentConfigOverrideForTestRequestModel] = OMIT,
        branch_id: typing.Optional[str] = OMIT,
        repeat_count: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetTestSuiteInvocationResponseModel:
        """
        Run selected tests on the agent with provided configuration. If the agent configuration is provided, it will be used to override default agent configuration.

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        tests : typing.Sequence[SingleTestRunRequestModel]
            List of tests to run on the agent

        agent_config_override : typing.Optional[AdhocAgentConfigOverrideForTestRequestModel]
            Configuration overrides to use for testing. If not provided, the agent's default configuration will be used.

        branch_id : typing.Optional[str]
            ID of the branch to run the tests on. If not provided, the tests will be run on the agent default configuration.

        repeat_count : typing.Optional[int]
            Number of times to run each test. When greater than 1, results are grouped and summarized.

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

        Returns
        -------
        GetTestSuiteInvocationResponseModel
            Successful Response

        Examples
        --------
        from elevenlabs import ElevenLabs, SingleTestRunRequestModel

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.run_tests(
            agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
            tests=[
                SingleTestRunRequestModel(
                    test_id="test_id",
                )
            ],
        )
        """
        _response = self._raw_client.run_tests(
            agent_id,
            tests=tests,
            agent_config_override=agent_config_override,
            branch_id=branch_id,
            repeat_count=repeat_count,
            request_options=request_options,
        )
        return _response.data

    @property
    def summaries(self):
        if self._summaries is None:
            from .summaries.client import SummariesClient  # noqa: E402

            self._summaries = SummariesClient(client_wrapper=self._client_wrapper)
        return self._summaries

    @property
    def widget(self):
        if self._widget is None:
            from .widget.client import WidgetClient  # noqa: E402

            self._widget = WidgetClient(client_wrapper=self._client_wrapper)
        return self._widget

    @property
    def link(self):
        if self._link is None:
            from .link.client import LinkClient  # noqa: E402

            self._link = LinkClient(client_wrapper=self._client_wrapper)
        return self._link

    @property
    def knowledge_base(self):
        if self._knowledge_base is None:
            from .knowledge_base.client import KnowledgeBaseClient  # noqa: E402

            self._knowledge_base = KnowledgeBaseClient(client_wrapper=self._client_wrapper)
        return self._knowledge_base

    @property
    def llm_usage(self):
        if self._llm_usage is None:
            from .llm_usage.client import LlmUsageClient  # noqa: E402

            self._llm_usage = LlmUsageClient(client_wrapper=self._client_wrapper)
        return self._llm_usage

    @property
    def branches(self):
        if self._branches is None:
            from .branches.client import BranchesClient  # noqa: E402

            self._branches = BranchesClient(client_wrapper=self._client_wrapper)
        return self._branches

    @property
    def versions(self):
        if self._versions is None:
            from .versions.client import VersionsClient  # noqa: E402

            self._versions = VersionsClient(client_wrapper=self._client_wrapper)
        return self._versions

    @property
    def deployments(self):
        if self._deployments is None:
            from .deployments.client import DeploymentsClient  # noqa: E402

            self._deployments = DeploymentsClient(client_wrapper=self._client_wrapper)
        return self._deployments

    @property
    def drafts(self):
        if self._drafts is None:
            from .drafts.client import DraftsClient  # noqa: E402

            self._drafts = DraftsClient(client_wrapper=self._client_wrapper)
        return self._drafts


class AsyncAgentsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawAgentsClient(client_wrapper=client_wrapper)
        self._client_wrapper = client_wrapper
        self._summaries: typing.Optional[AsyncSummariesClient] = None
        self._widget: typing.Optional[AsyncWidgetClient] = None
        self._link: typing.Optional[AsyncLinkClient] = None
        self._knowledge_base: typing.Optional[AsyncKnowledgeBaseClient] = None
        self._llm_usage: typing.Optional[AsyncLlmUsageClient] = None
        self._branches: typing.Optional[AsyncBranchesClient] = None
        self._versions: typing.Optional[AsyncVersionsClient] = None
        self._deployments: typing.Optional[AsyncDeploymentsClient] = None
        self._drafts: typing.Optional[AsyncDraftsClient] = None

    @property
    def with_raw_response(self) -> AsyncRawAgentsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawAgentsClient
        """
        return self._raw_client

    async def create(
        self,
        *,
        conversation_config: ConversationalConfig,
        enable_versioning: typing.Optional[bool] = None,
        platform_settings: typing.Optional[AgentPlatformSettingsRequestModel] = OMIT,
        workflow: typing.Optional[AgentWorkflowRequestModel] = OMIT,
        name: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateAgentResponseModel:
        """
        Create an agent from a config object

        Parameters
        ----------
        conversation_config : ConversationalConfig
            Conversation configuration for an agent

        enable_versioning : typing.Optional[bool]
            Deprecated: all agents are versioned. This parameter is ignored.

        platform_settings : typing.Optional[AgentPlatformSettingsRequestModel]
            Platform settings for the agent are all settings that aren't related to the conversation orchestration and content.

        workflow : typing.Optional[AgentWorkflowRequestModel]
            Workflow for the agent. This is used to define the flow of the conversation and how the agent interacts with tools.

        name : typing.Optional[str]
            A name to make the agent easier to find

        tags : typing.Optional[typing.Sequence[str]]
            Tags to help classify and filter the agent

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

        Returns
        -------
        CreateAgentResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs, ConversationalConfig

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.conversational_ai.agents.create(
                enable_versioning=True,
                conversation_config=ConversationalConfig(),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create(
            conversation_config=conversation_config,
            enable_versioning=enable_versioning,
            platform_settings=platform_settings,
            workflow=workflow,
            name=name,
            tags=tags,
            request_options=request_options,
        )
        return _response.data

    async def get(
        self,
        agent_id: str,
        *,
        version_id: typing.Optional[str] = None,
        branch_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetAgentResponseModel:
        """
        Retrieve config for an agent

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        version_id : typing.Optional[str]
            The ID of the agent version to use

        branch_id : typing.Optional[str]
            The ID of the branch to use

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

        Returns
        -------
        GetAgentResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.conversational_ai.agents.get(
                agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
                version_id="version_id",
                branch_id="branch_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get(
            agent_id, version_id=version_id, branch_id=branch_id, request_options=request_options
        )
        return _response.data

    async def delete(self, agent_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Delete an agent

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.conversational_ai.agents.delete(
                agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.delete(agent_id, request_options=request_options)
        return _response.data

    async def update(
        self,
        agent_id: str,
        *,
        enable_versioning_if_not_enabled: typing.Optional[bool] = None,
        branch_id: typing.Optional[str] = None,
        conversation_config: typing.Optional[ConversationalConfig] = OMIT,
        platform_settings: typing.Optional[AgentPlatformSettingsRequestModel] = OMIT,
        workflow: typing.Optional[AgentWorkflowRequestModel] = OMIT,
        name: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        version_description: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetAgentResponseModel:
        """
        Patches an Agent settings

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        enable_versioning_if_not_enabled : typing.Optional[bool]
            Deprecated: all agents are versioned. This parameter is ignored.

        branch_id : typing.Optional[str]
            The ID of the branch to use

        conversation_config : typing.Optional[ConversationalConfig]
            Conversation configuration for an agent

        platform_settings : typing.Optional[AgentPlatformSettingsRequestModel]
            Platform settings for the agent are all settings that aren't related to the conversation orchestration and content.

        workflow : typing.Optional[AgentWorkflowRequestModel]
            Workflow for the agent. This is used to define the flow of the conversation and how the agent interacts with tools.

        name : typing.Optional[str]
            A name to make the agent easier to find

        tags : typing.Optional[typing.Sequence[str]]
            Tags to help classify and filter the agent

        version_description : typing.Optional[str]
            Description for this version when publishing changes (only applicable for versioned agents)

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

        Returns
        -------
        GetAgentResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.conversational_ai.agents.update(
                agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
                enable_versioning_if_not_enabled=True,
                branch_id="branch_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update(
            agent_id,
            enable_versioning_if_not_enabled=enable_versioning_if_not_enabled,
            branch_id=branch_id,
            conversation_config=conversation_config,
            platform_settings=platform_settings,
            workflow=workflow,
            name=name,
            tags=tags,
            version_description=version_description,
            request_options=request_options,
        )
        return _response.data

    async def list(
        self,
        *,
        page_size: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        archived: typing.Optional[bool] = None,
        show_only_owned_agents: typing.Optional[bool] = None,
        created_by_user_id: typing.Optional[str] = None,
        sort_direction: typing.Optional[SortDirection] = None,
        sort_by: typing.Optional[AgentSortBy] = None,
        cursor: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetAgentsPageResponseModel:
        """
        Returns a list of your agents and their metadata.

        Parameters
        ----------
        page_size : typing.Optional[int]
            How many Agents to return at maximum. Can not exceed 100, defaults to 30.

        search : typing.Optional[str]
            Search by agents name.

        archived : typing.Optional[bool]
            Filter agents by archived status

        show_only_owned_agents : typing.Optional[bool]
            If set to true, the endpoint will omit any agents that were shared with you by someone else and include only the ones you own. Deprecated: use created_by_user_id instead.

        created_by_user_id : typing.Optional[str]
            Filter agents by creator user ID. When set, only agents created by this user are returned. Takes precedence over show_only_owned_agents. Use '@me' to refer to the authenticated user.

        sort_direction : typing.Optional[SortDirection]
            The direction to sort the results

        sort_by : typing.Optional[AgentSortBy]
            The field to sort the results by

        cursor : typing.Optional[str]
            Used for fetching next page. Cursor is returned in the response.

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

        Returns
        -------
        GetAgentsPageResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.conversational_ai.agents.list(
                page_size=1,
                search="search",
                archived=True,
                show_only_owned_agents=True,
                created_by_user_id="created_by_user_id",
                sort_direction="asc",
                sort_by="name",
                cursor="cursor",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.list(
            page_size=page_size,
            search=search,
            archived=archived,
            show_only_owned_agents=show_only_owned_agents,
            created_by_user_id=created_by_user_id,
            sort_direction=sort_direction,
            sort_by=sort_by,
            cursor=cursor,
            request_options=request_options,
        )
        return _response.data

    async def duplicate(
        self,
        agent_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateAgentResponseModel:
        """
        Create a new agent by duplicating an existing one

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        name : typing.Optional[str]
            A name to make the agent easier to find

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

        Returns
        -------
        CreateAgentResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.conversational_ai.agents.duplicate(
                agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.duplicate(agent_id, name=name, request_options=request_options)
        return _response.data

    async def simulate_conversation(
        self,
        agent_id: str,
        *,
        simulation_specification: ConversationSimulationSpecification,
        extra_evaluation_criteria: typing.Optional[typing.Sequence[PromptEvaluationCriteria]] = OMIT,
        new_turns_limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentSimulatedChatTestResponseModel:
        """
        Run a conversation between the agent and a simulated user.

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        simulation_specification : ConversationSimulationSpecification
            A specification detailing how the conversation should be simulated

        extra_evaluation_criteria : typing.Optional[typing.Sequence[PromptEvaluationCriteria]]
            A list of evaluation criteria to test

        new_turns_limit : typing.Optional[int]
            Maximum number of new turns to generate in the conversation simulation

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

        Returns
        -------
        AgentSimulatedChatTestResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import (
            AgentConfig,
            AsyncElevenLabs,
            ConversationSimulationSpecification,
        )

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.conversational_ai.agents.simulate_conversation(
                agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
                simulation_specification=ConversationSimulationSpecification(
                    simulated_user_config=AgentConfig(
                        first_message="Hello, how can I help you today?",
                        language="en",
                        disable_first_message_interruptions=False,
                    ),
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.simulate_conversation(
            agent_id,
            simulation_specification=simulation_specification,
            extra_evaluation_criteria=extra_evaluation_criteria,
            new_turns_limit=new_turns_limit,
            request_options=request_options,
        )
        return _response.data

    async def simulate_conversation_stream(
        self,
        agent_id: str,
        *,
        simulation_specification: ConversationSimulationSpecification,
        extra_evaluation_criteria: typing.Optional[typing.Sequence[PromptEvaluationCriteria]] = OMIT,
        new_turns_limit: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Run a conversation between the agent and a simulated user and stream back the response. Response is streamed back as partial lists of messages that should be concatenated and once the conversation has complete a single final message with the conversation analysis will be sent.

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        simulation_specification : ConversationSimulationSpecification
            A specification detailing how the conversation should be simulated

        extra_evaluation_criteria : typing.Optional[typing.Sequence[PromptEvaluationCriteria]]
            A list of evaluation criteria to test

        new_turns_limit : typing.Optional[int]
            Maximum number of new turns to generate in the conversation simulation

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from elevenlabs import (
            AgentConfig,
            AsyncElevenLabs,
            ConversationSimulationSpecification,
        )

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.conversational_ai.agents.simulate_conversation_stream(
                agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
                simulation_specification=ConversationSimulationSpecification(
                    simulated_user_config=AgentConfig(
                        first_message="Hello, how can I help you today?",
                        language="en",
                        disable_first_message_interruptions=False,
                    ),
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.simulate_conversation_stream(
            agent_id,
            simulation_specification=simulation_specification,
            extra_evaluation_criteria=extra_evaluation_criteria,
            new_turns_limit=new_turns_limit,
            request_options=request_options,
        )
        return _response.data

    async def run_tests(
        self,
        agent_id: str,
        *,
        tests: typing.Sequence[SingleTestRunRequestModel],
        agent_config_override: typing.Optional[AdhocAgentConfigOverrideForTestRequestModel] = OMIT,
        branch_id: typing.Optional[str] = OMIT,
        repeat_count: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetTestSuiteInvocationResponseModel:
        """
        Run selected tests on the agent with provided configuration. If the agent configuration is provided, it will be used to override default agent configuration.

        Parameters
        ----------
        agent_id : str
            The id of an agent. This is returned on agent creation.

        tests : typing.Sequence[SingleTestRunRequestModel]
            List of tests to run on the agent

        agent_config_override : typing.Optional[AdhocAgentConfigOverrideForTestRequestModel]
            Configuration overrides to use for testing. If not provided, the agent's default configuration will be used.

        branch_id : typing.Optional[str]
            ID of the branch to run the tests on. If not provided, the tests will be run on the agent default configuration.

        repeat_count : typing.Optional[int]
            Number of times to run each test. When greater than 1, results are grouped and summarized.

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

        Returns
        -------
        GetTestSuiteInvocationResponseModel
            Successful Response

        Examples
        --------
        import asyncio

        from elevenlabs import AsyncElevenLabs, SingleTestRunRequestModel

        client = AsyncElevenLabs(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.conversational_ai.agents.run_tests(
                agent_id="agent_3701k3ttaq12ewp8b7qv5rfyszkz",
                tests=[
                    SingleTestRunRequestModel(
                        test_id="test_id",
                    )
                ],
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.run_tests(
            agent_id,
            tests=tests,
            agent_config_override=agent_config_override,
            branch_id=branch_id,
            repeat_count=repeat_count,
            request_options=request_options,
        )
        return _response.data

    @property
    def summaries(self):
        if self._summaries is None:
            from .summaries.client import AsyncSummariesClient  # noqa: E402

            self._summaries = AsyncSummariesClient(client_wrapper=self._client_wrapper)
        return self._summaries

    @property
    def widget(self):
        if self._widget is None:
            from .widget.client import AsyncWidgetClient  # noqa: E402

            self._widget = AsyncWidgetClient(client_wrapper=self._client_wrapper)
        return self._widget

    @property
    def link(self):
        if self._link is None:
            from .link.client import AsyncLinkClient  # noqa: E402

            self._link = AsyncLinkClient(client_wrapper=self._client_wrapper)
        return self._link

    @property
    def knowledge_base(self):
        if self._knowledge_base is None:
            from .knowledge_base.client import AsyncKnowledgeBaseClient  # noqa: E402

            self._knowledge_base = AsyncKnowledgeBaseClient(client_wrapper=self._client_wrapper)
        return self._knowledge_base

    @property
    def llm_usage(self):
        if self._llm_usage is None:
            from .llm_usage.client import AsyncLlmUsageClient  # noqa: E402

            self._llm_usage = AsyncLlmUsageClient(client_wrapper=self._client_wrapper)
        return self._llm_usage

    @property
    def branches(self):
        if self._branches is None:
            from .branches.client import AsyncBranchesClient  # noqa: E402

            self._branches = AsyncBranchesClient(client_wrapper=self._client_wrapper)
        return self._branches

    @property
    def versions(self):
        if self._versions is None:
            from .versions.client import AsyncVersionsClient  # noqa: E402

            self._versions = AsyncVersionsClient(client_wrapper=self._client_wrapper)
        return self._versions

    @property
    def deployments(self):
        if self._deployments is None:
            from .deployments.client import AsyncDeploymentsClient  # noqa: E402

            self._deployments = AsyncDeploymentsClient(client_wrapper=self._client_wrapper)
        return self._deployments

    @property
    def drafts(self):
        if self._drafts is None:
            from .drafts.client import AsyncDraftsClient  # noqa: E402

            self._drafts = AsyncDraftsClient(client_wrapper=self._client_wrapper)
        return self._drafts
