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

import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.pagination import AsyncPager, SyncPager
from ..core.request_options import RequestOptions
from ..types.agent import Agent
from ..types.agent_key import AgentKey
from ..types.agent_model import AgentModel
from ..types.agent_name import AgentName
from ..types.agent_tool_configuration import AgentToolConfiguration
from ..types.components_schemas_conversational_agent_step import ComponentsSchemasConversationalAgentStep
from .raw_client import AsyncRawAgentsClient, RawAgentsClient

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

    @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 list(
        self,
        *,
        filter: typing.Optional[str] = None,
        enabled: typing.Optional[bool] = None,
        limit: typing.Optional[int] = None,
        page_key: typing.Optional[str] = None,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[Agent]:
        """
        List all agents available to the authenticated user, with optional filtering and pagination.

        Parameters
        ----------
        filter : typing.Optional[str]
            A regular expression against agent names and descriptions to filter the results.

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

        limit : typing.Optional[int]
            The maximum number of agents to return in the list.

        page_key : typing.Optional[str]
            Used to retrieve the next page of agents after the limit has been reached.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        SyncPager[Agent]
            List of available agents.

        Examples
        --------
        from vectara import Vectara

        client = Vectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        response = client.agents.list(
            filter="support.*",
            enabled=True,
        )
        for item in response:
            yield item
        # alternatively, you can paginate page-by-page
        for page in response.iter_pages():
            yield page
        """
        return self._raw_client.list(
            filter=filter,
            enabled=enabled,
            limit=limit,
            page_key=page_key,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            request_options=request_options,
        )

    def create(
        self,
        *,
        name: AgentName,
        tool_configurations: typing.Dict[str, AgentToolConfiguration],
        model: AgentModel,
        first_step: ComponentsSchemasConversationalAgentStep,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        key: typing.Optional[AgentKey] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Agent:
        """
        Create a new agent. An agent is compromised as 3 main things of functionality:
          1. The instructions an agent follows. Known as a system in prompt in other platforms.
          2. The steps an agent follows when receiving an input.
          3. The tools an agent can use to resolve those steps and instructions.
        Instructions are tied to each step, and should be well crafted so that the agent can perform the desired actions when given an input.

        To use an agent, create a new session (called thread or chat in other platforms), and send new inputs to the agent to get responses.

        Note: Only a single step is supported with no follow up steps. So the `first_step` will be only the only step. We will add multiple steps and step types to execute complex workflows, but many agents can work well with a single step.

        Parameters
        ----------
        name : AgentName

        tool_configurations : typing.Dict[str, AgentToolConfiguration]
            A map of tool configurations available to the agent. The key is the name of the tool configuration and the value is the AgentToolConfiguration.

        model : AgentModel

        first_step : ComponentsSchemasConversationalAgentStep

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        key : typing.Optional[AgentKey]
            A user provided key that uniquely identifies this agent. If not provided, one will be auto-generated based on the agent name.

        description : typing.Optional[str]
            A detailed description of the agent's purpose and capabilities.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the agent for customization and configuration.

        enabled : typing.Optional[bool]
            Whether the agent should be enabled upon creation.

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

        Returns
        -------
        Agent
            The agent has been created successfully.

        Examples
        --------
        from vectara import (
            AgentModel,
            ConversationalAgentStep,
            CorporaSearchQueryConfiguration,
            CorporaSearchToolParameters,
            DefaultOutputParser,
            InlineCorporaSearchToolConfiguration,
            ReferenceInstruction,
            SearchCorporaParameters,
            Vectara,
        )

        client = Vectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.agents.create(
            name="Customer Support Agent",
            tool_configurations={
                "customer_search": InlineCorporaSearchToolConfiguration(
                    argument_override=CorporaSearchToolParameters(
                        query="customer support documentation",
                    ),
                    query_configuration=CorporaSearchQueryConfiguration(
                        search=SearchCorporaParameters(),
                    ),
                )
            },
            model=AgentModel(
                name="gpt-4",
            ),
            first_step=ConversationalAgentStep(
                instructions=[
                    ReferenceInstruction(
                        id="ins_customer_support_init",
                    )
                ],
                output_parser=DefaultOutputParser(),
            ),
        )
        """
        _response = self._raw_client.create(
            name=name,
            tool_configurations=tool_configurations,
            model=model,
            first_step=first_step,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            key=key,
            description=description,
            metadata=metadata,
            enabled=enabled,
            request_options=request_options,
        )
        return _response.data

    def get(
        self,
        agent_key: AgentKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Agent:
        """
        Retrieve the details of a specific agent by its ID, including its configuration, capabilities, and associated resources.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to retrieve.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        Agent
            The requested agent details.

        Examples
        --------
        from vectara import Vectara

        client = Vectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.agents.get(
            agent_key="customer_support",
        )
        """
        _response = self._raw_client.get(
            agent_key,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            request_options=request_options,
        )
        return _response.data

    def replace(
        self,
        agent_key: AgentKey,
        *,
        name: AgentName,
        tool_configurations: typing.Dict[str, AgentToolConfiguration],
        model: AgentModel,
        first_step: ComponentsSchemasConversationalAgentStep,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Agent:
        """
        Completely replace an existing agent's configuration, including its corpora, tools, and generation presets.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to replace.

        name : AgentName

        tool_configurations : typing.Dict[str, AgentToolConfiguration]
            A map of tool configurations available to the agent. The key is the name of the tool configuration and the value is an agent tool configuration.

        model : AgentModel

        first_step : ComponentsSchemasConversationalAgentStep

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        description : typing.Optional[str]
            A detailed description of the agent's purpose and capabilities.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the agent for customization and configuration.

        enabled : typing.Optional[bool]
            Whether the agent is enabled.

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

        Returns
        -------
        Agent
            The agent has been replaced successfully.

        Examples
        --------
        from vectara import (
            AgentModel,
            ConversationalAgentStep,
            CorporaSearchQueryConfiguration,
            CorporaSearchToolParameters,
            DefaultOutputParser,
            InlineCorporaSearchToolConfiguration,
            ReferenceInstruction,
            SearchCorporaParameters,
            Vectara,
        )

        client = Vectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.agents.replace(
            agent_key="customer_support",
            name="Customer Support Agent",
            tool_configurations={
                "customer_search": InlineCorporaSearchToolConfiguration(
                    argument_override=CorporaSearchToolParameters(
                        query="customer support documentation",
                    ),
                    query_configuration=CorporaSearchQueryConfiguration(
                        search=SearchCorporaParameters(),
                    ),
                )
            },
            model=AgentModel(
                name="gpt-4",
            ),
            first_step=ConversationalAgentStep(
                instructions=[
                    ReferenceInstruction(
                        id="ins_customer_support_init",
                    )
                ],
                output_parser=DefaultOutputParser(),
            ),
        )
        """
        _response = self._raw_client.replace(
            agent_key,
            name=name,
            tool_configurations=tool_configurations,
            model=model,
            first_step=first_step,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            description=description,
            metadata=metadata,
            enabled=enabled,
            request_options=request_options,
        )
        return _response.data

    def delete(
        self,
        agent_key: AgentKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Permanently delete an agent and all its associated configuration. This action cannot be undone.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to delete.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        None

        Examples
        --------
        from vectara import Vectara

        client = Vectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.agents.delete(
            agent_key="customer_support",
        )
        """
        _response = self._raw_client.delete(
            agent_key,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            request_options=request_options,
        )
        return _response.data

    def update(
        self,
        agent_key: AgentKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        name: typing.Optional[AgentName] = OMIT,
        description: typing.Optional[str] = OMIT,
        tool_configurations: typing.Optional[typing.Dict[str, AgentToolConfiguration]] = OMIT,
        model: typing.Optional[AgentModel] = OMIT,
        first_step: typing.Optional[ComponentsSchemasConversationalAgentStep] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Agent:
        """
        Update an existing agent's configuration, including its corpora, tools, and generation presets.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to update.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        name : typing.Optional[AgentName]

        description : typing.Optional[str]
            A detailed description of the agent's purpose and capabilities.

        tool_configurations : typing.Optional[typing.Dict[str, AgentToolConfiguration]]
            A map of tool configurations available to the agent. The key is the name of the tool configuration and the value is an agent tool configuration.

        model : typing.Optional[AgentModel]

        first_step : typing.Optional[ComponentsSchemasConversationalAgentStep]

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the agent for customization and configuration.

        enabled : typing.Optional[bool]
            Whether the agent is enabled.

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

        Returns
        -------
        Agent
            The agent has been updated successfully.

        Examples
        --------
        from vectara import Vectara

        client = Vectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.agents.update(
            agent_key="customer_support",
        )
        """
        _response = self._raw_client.update(
            agent_key,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            name=name,
            description=description,
            tool_configurations=tool_configurations,
            model=model,
            first_step=first_step,
            metadata=metadata,
            enabled=enabled,
            request_options=request_options,
        )
        return _response.data


class AsyncAgentsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawAgentsClient(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 list(
        self,
        *,
        filter: typing.Optional[str] = None,
        enabled: typing.Optional[bool] = None,
        limit: typing.Optional[int] = None,
        page_key: typing.Optional[str] = None,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[Agent]:
        """
        List all agents available to the authenticated user, with optional filtering and pagination.

        Parameters
        ----------
        filter : typing.Optional[str]
            A regular expression against agent names and descriptions to filter the results.

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

        limit : typing.Optional[int]
            The maximum number of agents to return in the list.

        page_key : typing.Optional[str]
            Used to retrieve the next page of agents after the limit has been reached.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        AsyncPager[Agent]
            List of available agents.

        Examples
        --------
        import asyncio

        from vectara import AsyncVectara

        client = AsyncVectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            response = await client.agents.list(
                filter="support.*",
                enabled=True,
            )
            async for item in response:
                yield item

            # alternatively, you can paginate page-by-page
            async for page in response.iter_pages():
                yield page


        asyncio.run(main())
        """
        return await self._raw_client.list(
            filter=filter,
            enabled=enabled,
            limit=limit,
            page_key=page_key,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            request_options=request_options,
        )

    async def create(
        self,
        *,
        name: AgentName,
        tool_configurations: typing.Dict[str, AgentToolConfiguration],
        model: AgentModel,
        first_step: ComponentsSchemasConversationalAgentStep,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        key: typing.Optional[AgentKey] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Agent:
        """
        Create a new agent. An agent is compromised as 3 main things of functionality:
          1. The instructions an agent follows. Known as a system in prompt in other platforms.
          2. The steps an agent follows when receiving an input.
          3. The tools an agent can use to resolve those steps and instructions.
        Instructions are tied to each step, and should be well crafted so that the agent can perform the desired actions when given an input.

        To use an agent, create a new session (called thread or chat in other platforms), and send new inputs to the agent to get responses.

        Note: Only a single step is supported with no follow up steps. So the `first_step` will be only the only step. We will add multiple steps and step types to execute complex workflows, but many agents can work well with a single step.

        Parameters
        ----------
        name : AgentName

        tool_configurations : typing.Dict[str, AgentToolConfiguration]
            A map of tool configurations available to the agent. The key is the name of the tool configuration and the value is the AgentToolConfiguration.

        model : AgentModel

        first_step : ComponentsSchemasConversationalAgentStep

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        key : typing.Optional[AgentKey]
            A user provided key that uniquely identifies this agent. If not provided, one will be auto-generated based on the agent name.

        description : typing.Optional[str]
            A detailed description of the agent's purpose and capabilities.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the agent for customization and configuration.

        enabled : typing.Optional[bool]
            Whether the agent should be enabled upon creation.

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

        Returns
        -------
        Agent
            The agent has been created successfully.

        Examples
        --------
        import asyncio

        from vectara import (
            AgentModel,
            AsyncVectara,
            ConversationalAgentStep,
            CorporaSearchQueryConfiguration,
            CorporaSearchToolParameters,
            DefaultOutputParser,
            InlineCorporaSearchToolConfiguration,
            ReferenceInstruction,
            SearchCorporaParameters,
        )

        client = AsyncVectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.agents.create(
                name="Customer Support Agent",
                tool_configurations={
                    "customer_search": InlineCorporaSearchToolConfiguration(
                        argument_override=CorporaSearchToolParameters(
                            query="customer support documentation",
                        ),
                        query_configuration=CorporaSearchQueryConfiguration(
                            search=SearchCorporaParameters(),
                        ),
                    )
                },
                model=AgentModel(
                    name="gpt-4",
                ),
                first_step=ConversationalAgentStep(
                    instructions=[
                        ReferenceInstruction(
                            id="ins_customer_support_init",
                        )
                    ],
                    output_parser=DefaultOutputParser(),
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create(
            name=name,
            tool_configurations=tool_configurations,
            model=model,
            first_step=first_step,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            key=key,
            description=description,
            metadata=metadata,
            enabled=enabled,
            request_options=request_options,
        )
        return _response.data

    async def get(
        self,
        agent_key: AgentKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Agent:
        """
        Retrieve the details of a specific agent by its ID, including its configuration, capabilities, and associated resources.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to retrieve.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        Agent
            The requested agent details.

        Examples
        --------
        import asyncio

        from vectara import AsyncVectara

        client = AsyncVectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.agents.get(
                agent_key="customer_support",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get(
            agent_key,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            request_options=request_options,
        )
        return _response.data

    async def replace(
        self,
        agent_key: AgentKey,
        *,
        name: AgentName,
        tool_configurations: typing.Dict[str, AgentToolConfiguration],
        model: AgentModel,
        first_step: ComponentsSchemasConversationalAgentStep,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Agent:
        """
        Completely replace an existing agent's configuration, including its corpora, tools, and generation presets.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to replace.

        name : AgentName

        tool_configurations : typing.Dict[str, AgentToolConfiguration]
            A map of tool configurations available to the agent. The key is the name of the tool configuration and the value is an agent tool configuration.

        model : AgentModel

        first_step : ComponentsSchemasConversationalAgentStep

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        description : typing.Optional[str]
            A detailed description of the agent's purpose and capabilities.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the agent for customization and configuration.

        enabled : typing.Optional[bool]
            Whether the agent is enabled.

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

        Returns
        -------
        Agent
            The agent has been replaced successfully.

        Examples
        --------
        import asyncio

        from vectara import (
            AgentModel,
            AsyncVectara,
            ConversationalAgentStep,
            CorporaSearchQueryConfiguration,
            CorporaSearchToolParameters,
            DefaultOutputParser,
            InlineCorporaSearchToolConfiguration,
            ReferenceInstruction,
            SearchCorporaParameters,
        )

        client = AsyncVectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.agents.replace(
                agent_key="customer_support",
                name="Customer Support Agent",
                tool_configurations={
                    "customer_search": InlineCorporaSearchToolConfiguration(
                        argument_override=CorporaSearchToolParameters(
                            query="customer support documentation",
                        ),
                        query_configuration=CorporaSearchQueryConfiguration(
                            search=SearchCorporaParameters(),
                        ),
                    )
                },
                model=AgentModel(
                    name="gpt-4",
                ),
                first_step=ConversationalAgentStep(
                    instructions=[
                        ReferenceInstruction(
                            id="ins_customer_support_init",
                        )
                    ],
                    output_parser=DefaultOutputParser(),
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.replace(
            agent_key,
            name=name,
            tool_configurations=tool_configurations,
            model=model,
            first_step=first_step,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            description=description,
            metadata=metadata,
            enabled=enabled,
            request_options=request_options,
        )
        return _response.data

    async def delete(
        self,
        agent_key: AgentKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Permanently delete an agent and all its associated configuration. This action cannot be undone.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to delete.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from vectara import AsyncVectara

        client = AsyncVectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.agents.delete(
                agent_key="customer_support",
            )


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

    async def update(
        self,
        agent_key: AgentKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        name: typing.Optional[AgentName] = OMIT,
        description: typing.Optional[str] = OMIT,
        tool_configurations: typing.Optional[typing.Dict[str, AgentToolConfiguration]] = OMIT,
        model: typing.Optional[AgentModel] = OMIT,
        first_step: typing.Optional[ComponentsSchemasConversationalAgentStep] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Agent:
        """
        Update an existing agent's configuration, including its corpora, tools, and generation presets.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to update.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        name : typing.Optional[AgentName]

        description : typing.Optional[str]
            A detailed description of the agent's purpose and capabilities.

        tool_configurations : typing.Optional[typing.Dict[str, AgentToolConfiguration]]
            A map of tool configurations available to the agent. The key is the name of the tool configuration and the value is an agent tool configuration.

        model : typing.Optional[AgentModel]

        first_step : typing.Optional[ComponentsSchemasConversationalAgentStep]

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the agent for customization and configuration.

        enabled : typing.Optional[bool]
            Whether the agent is enabled.

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

        Returns
        -------
        Agent
            The agent has been updated successfully.

        Examples
        --------
        import asyncio

        from vectara import AsyncVectara

        client = AsyncVectara(
            api_key="YOUR_API_KEY",
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.agents.update(
                agent_key="customer_support",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update(
            agent_key,
            request_timeout=request_timeout,
            request_timeout_millis=request_timeout_millis,
            name=name,
            description=description,
            tool_configurations=tool_configurations,
            model=model,
            first_step=first_step,
            metadata=metadata,
            enabled=enabled,
            request_options=request_options,
        )
        return _response.data
