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

import typing

from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.request_options import RequestOptions
from ...types.agent_platform_settings_request_model import AgentPlatformSettingsRequestModel
from ...types.agent_simulated_chat_test_response_model import AgentSimulatedChatTestResponseModel
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.prompt_evaluation_criteria import PromptEvaluationCriteria
from .knowledge_base.client import AsyncKnowledgeBaseClient, KnowledgeBaseClient
from .link.client import AsyncLinkClient, LinkClient
from .llm_usage.client import AsyncLlmUsageClient, LlmUsageClient
from .raw_client import AsyncRawAgentsClient, RawAgentsClient
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.widget = WidgetClient(client_wrapper=client_wrapper)

        self.link = LinkClient(client_wrapper=client_wrapper)

        self.knowledge_base = KnowledgeBaseClient(client_wrapper=client_wrapper)

        self.llm_usage = LlmUsageClient(client_wrapper=client_wrapper)

    @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,
        platform_settings: typing.Optional[AgentPlatformSettingsRequestModel] = OMIT,
        workflow: typing.Optional[typing.Optional[typing.Any]] = 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

        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[typing.Optional[typing.Any]]

        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(
            conversation_config=ConversationalConfig(),
        )
        """
        _response = self._raw_client.create(
            conversation_config=conversation_config,
            platform_settings=platform_settings,
            workflow=workflow,
            name=name,
            tags=tags,
            request_options=request_options,
        )
        return _response.data

    def get(self, agent_id: str, *, 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.

        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="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._raw_client.get(agent_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="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._raw_client.delete(agent_id, request_options=request_options)
        return _response.data

    def update(
        self,
        agent_id: str,
        *,
        conversation_config: typing.Optional[ConversationalConfig] = OMIT,
        platform_settings: typing.Optional[AgentPlatformSettingsRequestModel] = OMIT,
        workflow: typing.Optional[typing.Optional[typing.Any]] = OMIT,
        name: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[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.

        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[typing.Optional[typing.Any]]

        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
        -------
        GetAgentResponseModel
            Successful Response

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

        client = ElevenLabs(
            api_key="YOUR_API_KEY",
        )
        client.conversational_ai.agents.update(
            agent_id="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _response = self._raw_client.update(
            agent_id,
            conversation_config=conversation_config,
            platform_settings=platform_settings,
            workflow=workflow,
            name=name,
            tags=tags,
            request_options=request_options,
        )
        return _response.data

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

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

        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.

        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()
        """
        _response = self._raw_client.list(
            cursor=cursor, page_size=page_size, search=search, 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="21m00Tcm4TlvDq8ikWAM",
        )
        """
        _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="21m00Tcm4TlvDq8ikWAM",
            simulation_specification=ConversationSimulationSpecification(
                simulated_user_config=AgentConfig(
                    first_message="Hello, how can I help you today?",
                    language="en",
                ),
            ),
        )
        """
        _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="21m00Tcm4TlvDq8ikWAM",
            simulation_specification=ConversationSimulationSpecification(
                simulated_user_config=AgentConfig(
                    first_message="Hello, how can I help you today?",
                    language="en",
                ),
            ),
        )
        """
        _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


class AsyncAgentsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawAgentsClient(client_wrapper=client_wrapper)
        self.widget = AsyncWidgetClient(client_wrapper=client_wrapper)

        self.link = AsyncLinkClient(client_wrapper=client_wrapper)

        self.knowledge_base = AsyncKnowledgeBaseClient(client_wrapper=client_wrapper)

        self.llm_usage = AsyncLlmUsageClient(client_wrapper=client_wrapper)

    @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,
        platform_settings: typing.Optional[AgentPlatformSettingsRequestModel] = OMIT,
        workflow: typing.Optional[typing.Optional[typing.Any]] = 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

        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[typing.Optional[typing.Any]]

        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(
                conversation_config=ConversationalConfig(),
            )


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

    async def get(
        self, agent_id: str, *, 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.

        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="21m00Tcm4TlvDq8ikWAM",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get(agent_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="21m00Tcm4TlvDq8ikWAM",
            )


        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,
        *,
        conversation_config: typing.Optional[ConversationalConfig] = OMIT,
        platform_settings: typing.Optional[AgentPlatformSettingsRequestModel] = OMIT,
        workflow: typing.Optional[typing.Optional[typing.Any]] = OMIT,
        name: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Sequence[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.

        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[typing.Optional[typing.Any]]

        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
        -------
        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="21m00Tcm4TlvDq8ikWAM",
            )


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

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

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

        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.

        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()


        asyncio.run(main())
        """
        _response = await self._raw_client.list(
            cursor=cursor, page_size=page_size, search=search, 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="21m00Tcm4TlvDq8ikWAM",
            )


        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="21m00Tcm4TlvDq8ikWAM",
                simulation_specification=ConversationSimulationSpecification(
                    simulated_user_config=AgentConfig(
                        first_message="Hello, how can I help you today?",
                        language="en",
                    ),
                ),
            )


        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="21m00Tcm4TlvDq8ikWAM",
                simulation_specification=ConversationSimulationSpecification(
                    simulated_user_config=AgentConfig(
                        first_message="Hello, how can I help you today?",
                        language="en",
                    ),
                ),
            )


        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
