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

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..types.agent_configuration import AgentConfiguration
from ..types.agent_detailed_response import AgentDetailedResponse
from ..types.agent_list_response import AgentListResponse
from ..types.agent_response import AgentResponse
from ..types.success_response import SuccessResponse
from ..types.tool_list_response import ToolListResponse

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


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

    def list_agents(
        self,
        *,
        page: typing.Optional[int] = None,
        limit: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentListResponse]:
        """
        Retrieve all agents for the organization

        Parameters
        ----------
        page : typing.Optional[int]
            Page number for pagination

        limit : typing.Optional[int]
            Number of items per page

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

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

        Returns
        -------
        HttpResponse[AgentListResponse]
            Agents retrieved successfully
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/developer/agents",
            method="GET",
            params={
                "page": page,
                "limit": limit,
                "search": search,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentListResponse,
                    parse_obj_as(
                        type_=AgentListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create_agent(
        self,
        *,
        agent_name: str,
        agent_json: AgentConfiguration,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentResponse]:
        """
        Create a new AI voice agent with specified configuration

        Parameters
        ----------
        agent_name : str
            Human-readable name for the agent

        agent_json : AgentConfiguration

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

        Returns
        -------
        HttpResponse[AgentResponse]
            Agent created successfully
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/developer/agents",
            method="POST",
            json={
                "agent_name": agent_name,
                "agent_json": convert_and_respect_annotation_metadata(
                    object_=agent_json, annotation=AgentConfiguration, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentResponse,
                    parse_obj_as(
                        type_=AgentResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_agent(
        self, agent_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[AgentDetailedResponse]:
        """
        Retrieve a specific agent by ID with full configuration

        Parameters
        ----------
        agent_id : str
            Agent identifier

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

        Returns
        -------
        HttpResponse[AgentDetailedResponse]
            Agent retrieved successfully
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentDetailedResponse,
                    parse_obj_as(
                        type_=AgentDetailedResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update_agent(
        self,
        agent_id: str,
        *,
        agent_name: typing.Optional[str] = OMIT,
        agent_json: typing.Optional[AgentConfiguration] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentResponse]:
        """
        Update agent configuration. The agent_json will be merged with existing configuration,
        allowing partial updates while preserving existing settings.

        Parameters
        ----------
        agent_id : str

        agent_name : typing.Optional[str]

        agent_json : typing.Optional[AgentConfiguration]

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

        Returns
        -------
        HttpResponse[AgentResponse]
            Agent updated successfully
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}",
            method="PUT",
            json={
                "agent_name": agent_name,
                "agent_json": convert_and_respect_annotation_metadata(
                    object_=agent_json, annotation=AgentConfiguration, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentResponse,
                    parse_obj_as(
                        type_=AgentResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

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

        Parameters
        ----------
        agent_id : str

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

        Returns
        -------
        HttpResponse[SuccessResponse]
            Agent deleted successfully
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SuccessResponse,
                    parse_obj_as(
                        type_=SuccessResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_agent_tools(
        self, agent_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[ToolListResponse]:
        """
        Retrieve all tools assigned to a specific agent

        Parameters
        ----------
        agent_id : str

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

        Returns
        -------
        HttpResponse[ToolListResponse]
            Agent tools retrieved successfully
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}/tools",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ToolListResponse,
                    parse_obj_as(
                        type_=ToolListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def assign_tool_to_agent(
        self, agent_id: str, *, tool_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[SuccessResponse]:
        """
        Assign an existing tool to an agent

        Parameters
        ----------
        agent_id : str

        tool_id : str
            Tool identifier to assign

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

        Returns
        -------
        HttpResponse[SuccessResponse]
            Tool assigned to agent successfully
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}/tools",
            method="POST",
            json={
                "toolId": tool_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SuccessResponse,
                    parse_obj_as(
                        type_=SuccessResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def unassign_tool_from_agent(
        self, agent_id: str, *, tool_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[SuccessResponse]:
        """
        Remove a tool assignment from an agent

        Parameters
        ----------
        agent_id : str

        tool_id : str

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

        Returns
        -------
        HttpResponse[SuccessResponse]
            Tool unassigned from agent successfully
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}/tools",
            method="DELETE",
            json={
                "toolId": tool_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SuccessResponse,
                    parse_obj_as(
                        type_=SuccessResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawAgentsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list_agents(
        self,
        *,
        page: typing.Optional[int] = None,
        limit: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentListResponse]:
        """
        Retrieve all agents for the organization

        Parameters
        ----------
        page : typing.Optional[int]
            Page number for pagination

        limit : typing.Optional[int]
            Number of items per page

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

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

        Returns
        -------
        AsyncHttpResponse[AgentListResponse]
            Agents retrieved successfully
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/developer/agents",
            method="GET",
            params={
                "page": page,
                "limit": limit,
                "search": search,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentListResponse,
                    parse_obj_as(
                        type_=AgentListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create_agent(
        self,
        *,
        agent_name: str,
        agent_json: AgentConfiguration,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentResponse]:
        """
        Create a new AI voice agent with specified configuration

        Parameters
        ----------
        agent_name : str
            Human-readable name for the agent

        agent_json : AgentConfiguration

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

        Returns
        -------
        AsyncHttpResponse[AgentResponse]
            Agent created successfully
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/developer/agents",
            method="POST",
            json={
                "agent_name": agent_name,
                "agent_json": convert_and_respect_annotation_metadata(
                    object_=agent_json, annotation=AgentConfiguration, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentResponse,
                    parse_obj_as(
                        type_=AgentResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_agent(
        self, agent_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[AgentDetailedResponse]:
        """
        Retrieve a specific agent by ID with full configuration

        Parameters
        ----------
        agent_id : str
            Agent identifier

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

        Returns
        -------
        AsyncHttpResponse[AgentDetailedResponse]
            Agent retrieved successfully
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentDetailedResponse,
                    parse_obj_as(
                        type_=AgentDetailedResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update_agent(
        self,
        agent_id: str,
        *,
        agent_name: typing.Optional[str] = OMIT,
        agent_json: typing.Optional[AgentConfiguration] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentResponse]:
        """
        Update agent configuration. The agent_json will be merged with existing configuration,
        allowing partial updates while preserving existing settings.

        Parameters
        ----------
        agent_id : str

        agent_name : typing.Optional[str]

        agent_json : typing.Optional[AgentConfiguration]

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

        Returns
        -------
        AsyncHttpResponse[AgentResponse]
            Agent updated successfully
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}",
            method="PUT",
            json={
                "agent_name": agent_name,
                "agent_json": convert_and_respect_annotation_metadata(
                    object_=agent_json, annotation=AgentConfiguration, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentResponse,
                    parse_obj_as(
                        type_=AgentResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

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

        Parameters
        ----------
        agent_id : str

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

        Returns
        -------
        AsyncHttpResponse[SuccessResponse]
            Agent deleted successfully
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SuccessResponse,
                    parse_obj_as(
                        type_=SuccessResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_agent_tools(
        self, agent_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[ToolListResponse]:
        """
        Retrieve all tools assigned to a specific agent

        Parameters
        ----------
        agent_id : str

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

        Returns
        -------
        AsyncHttpResponse[ToolListResponse]
            Agent tools retrieved successfully
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}/tools",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ToolListResponse,
                    parse_obj_as(
                        type_=ToolListResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def assign_tool_to_agent(
        self, agent_id: str, *, tool_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[SuccessResponse]:
        """
        Assign an existing tool to an agent

        Parameters
        ----------
        agent_id : str

        tool_id : str
            Tool identifier to assign

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

        Returns
        -------
        AsyncHttpResponse[SuccessResponse]
            Tool assigned to agent successfully
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}/tools",
            method="POST",
            json={
                "toolId": tool_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SuccessResponse,
                    parse_obj_as(
                        type_=SuccessResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def unassign_tool_from_agent(
        self, agent_id: str, *, tool_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[SuccessResponse]:
        """
        Remove a tool assignment from an agent

        Parameters
        ----------
        agent_id : str

        tool_id : str

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

        Returns
        -------
        AsyncHttpResponse[SuccessResponse]
            Tool unassigned from agent successfully
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/developer/agents/{jsonable_encoder(agent_id)}/tools",
            method="DELETE",
            json={
                "toolId": tool_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SuccessResponse,
                    parse_obj_as(
                        type_=SuccessResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
