# 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 ..requests.tool_parameter import ToolParameterParams
from .raw_client import AsyncRawToolsClient, RawToolsClient
from .types.create_tool_request_endpoint_method import CreateToolRequestEndpointMethod
from .types.create_tool_request_execution_mode import CreateToolRequestExecutionMode
from .types.create_tool_request_type import CreateToolRequestType
from .types.tools_create_response import ToolsCreateResponse
from .types.tools_delete_response import ToolsDeleteResponse
from .types.tools_get_response import ToolsGetResponse
from .types.tools_list_response import ToolsListResponse
from .types.tools_update_response import ToolsUpdateResponse
from .types.update_tool_request_endpoint_method import UpdateToolRequestEndpointMethod
from .types.update_tool_request_execution_mode import UpdateToolRequestExecutionMode
from .types.update_tool_request_type import UpdateToolRequestType

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


class ToolsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawToolsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawToolsClient
        """
        return self._raw_client

    def list(
        self, *, project: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> ToolsListResponse:
        """
        Returns all custom tools for the organization.

        Parameters
        ----------
        project : typing.Optional[str]
            The name of the project to list tools for.

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

        Returns
        -------
        ToolsListResponse
            Success response

        Examples
        --------
        from phonic import Phonic

        client = Phonic(
            api_key="YOUR_API_KEY",
        )
        client.tools.list(
            project="main",
        )
        """
        _response = self._raw_client.list(project=project, request_options=request_options)
        return _response.data

    def create(
        self,
        *,
        name: str,
        description: str,
        type: CreateToolRequestType,
        execution_mode: CreateToolRequestExecutionMode,
        project: typing.Optional[str] = None,
        parameters: typing.Optional[typing.Sequence[ToolParameterParams]] = OMIT,
        endpoint_method: typing.Optional[CreateToolRequestEndpointMethod] = OMIT,
        endpoint_url: typing.Optional[str] = OMIT,
        endpoint_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
        endpoint_timeout_ms: typing.Optional[int] = OMIT,
        tool_call_output_timeout_ms: typing.Optional[int] = OMIT,
        phone_number: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ToolsCreateResponse:
        """
        Creates a new tool in a project.

        Parameters
        ----------
        name : str
            The name of the tool. Must be snake_case and unique within the organization.

        description : str
            A description of what the tool does.

        type : CreateToolRequestType
            The type of tool.

        execution_mode : CreateToolRequestExecutionMode
            Mode of operation.

        project : typing.Optional[str]
            The name of the project to create the tool in.

        parameters : typing.Optional[typing.Sequence[ToolParameterParams]]
            Array of parameter definitions.
            For `custom_webhook` tools with POST method, each parameter must include a `location` field.
            For `custom_webhook` tools with GET method, `location` defaults to `"query_string"` if not specified.
            For `custom_websocket` and `built_in_transfer_to_phone_number` tools, `location` must not be specified.

        endpoint_method : typing.Optional[CreateToolRequestEndpointMethod]
            Required for webhook tools. HTTP method for the webhook endpoint.

        endpoint_url : typing.Optional[str]
            Required for webhook tools.

        endpoint_headers : typing.Optional[typing.Dict[str, str]]
            Optional headers for webhook tools.

        endpoint_timeout_ms : typing.Optional[int]
            Timeout for webhook tools.

        tool_call_output_timeout_ms : typing.Optional[int]
            Timeout for WebSocket tool responses.

        phone_number : typing.Optional[str]
            The E.164 formatted phone number to transfer calls to. Required for built_in_transfer_to_phone_number tools.

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

        Returns
        -------
        ToolsCreateResponse
            Success response

        Examples
        --------
        from phonic import Phonic

        client = Phonic(
            api_key="YOUR_API_KEY",
        )
        client.tools.create(
            project="main",
            name="book_appointment",
            description="Books an appointment in the calendar system",
            type="custom_webhook",
            execution_mode="sync",
            parameters=[
                {
                    "type": "string",
                    "name": "date",
                    "description": "The date for the appointment in YYYY-MM-DD format",
                    "is_required": True,
                    "location": "request_body",
                },
                {
                    "type": "string",
                    "name": "time",
                    "description": "The time for the appointment in HH:MM format",
                    "is_required": True,
                    "location": "request_body",
                },
            ],
            endpoint_method="POST",
            endpoint_url="https://api.example.com/book-appointment",
            endpoint_headers={
                "Authorization": "Bearer token123",
                "Content-Type": "application/json",
            },
            endpoint_timeout_ms=5000,
        )
        """
        _response = self._raw_client.create(
            name=name,
            description=description,
            type=type,
            execution_mode=execution_mode,
            project=project,
            parameters=parameters,
            endpoint_method=endpoint_method,
            endpoint_url=endpoint_url,
            endpoint_headers=endpoint_headers,
            endpoint_timeout_ms=endpoint_timeout_ms,
            tool_call_output_timeout_ms=tool_call_output_timeout_ms,
            phone_number=phone_number,
            request_options=request_options,
        )
        return _response.data

    def get(
        self,
        name_or_id: str,
        *,
        project: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ToolsGetResponse:
        """
        Returns a tool by name or ID.

        Parameters
        ----------
        name_or_id : str
            The name or the ID of the tool to get.

        project : typing.Optional[str]
            The name of the project containing the tool. Only used when `nameOrId` is a name.

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

        Returns
        -------
        ToolsGetResponse
            Success response

        Examples
        --------
        from phonic import Phonic

        client = Phonic(
            api_key="YOUR_API_KEY",
        )
        client.tools.get(
            name_or_id="nameOrId",
            project="main",
        )
        """
        _response = self._raw_client.get(name_or_id, project=project, request_options=request_options)
        return _response.data

    def delete(
        self,
        name_or_id: str,
        *,
        project: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ToolsDeleteResponse:
        """
        Deletes a tool by name or ID.

        Parameters
        ----------
        name_or_id : str
            The name or the ID of the tool to delete.

        project : typing.Optional[str]
            The name of the project containing the tool. Only used when `nameOrId` is a name.

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

        Returns
        -------
        ToolsDeleteResponse
            Success response

        Examples
        --------
        from phonic import Phonic

        client = Phonic(
            api_key="YOUR_API_KEY",
        )
        client.tools.delete(
            name_or_id="nameOrId",
            project="main",
        )
        """
        _response = self._raw_client.delete(name_or_id, project=project, request_options=request_options)
        return _response.data

    def update(
        self,
        name_or_id: str,
        *,
        project: typing.Optional[str] = None,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        type: typing.Optional[UpdateToolRequestType] = OMIT,
        execution_mode: typing.Optional[UpdateToolRequestExecutionMode] = OMIT,
        parameters: typing.Optional[typing.Sequence[ToolParameterParams]] = OMIT,
        endpoint_method: typing.Optional[UpdateToolRequestEndpointMethod] = OMIT,
        endpoint_url: typing.Optional[str] = OMIT,
        endpoint_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
        endpoint_timeout_ms: typing.Optional[int] = OMIT,
        tool_call_output_timeout_ms: typing.Optional[int] = OMIT,
        phone_number: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ToolsUpdateResponse:
        """
        Updates a tool by name or ID.

        Parameters
        ----------
        name_or_id : str
            The name or the ID of the tool to update.

        project : typing.Optional[str]
            The name of the project containing the tool. Only used when `nameOrId` is a name.

        name : typing.Optional[str]
            The name of the tool. Must be snake_case and unique within the organization.

        description : typing.Optional[str]
            A description of what the tool does.

        type : typing.Optional[UpdateToolRequestType]
            The type of tool.

        execution_mode : typing.Optional[UpdateToolRequestExecutionMode]
            Mode of operation.

        parameters : typing.Optional[typing.Sequence[ToolParameterParams]]
            Array of parameter definitions.
            When updating `type` or `endpoint_method`, all parameters must include explicit `location` values.
            For `custom_webhook` tools: `location` is required for POST, defaults to `"query_string"` for GET.
            For `custom_websocket` and `built_in_transfer_to_phone_number` tools: `location` must not be specified.

        endpoint_method : typing.Optional[UpdateToolRequestEndpointMethod]
            HTTP method for webhook tools. When changing this value, all parameters must include explicit `location` values.

        endpoint_url : typing.Optional[str]

        endpoint_headers : typing.Optional[typing.Dict[str, str]]

        endpoint_timeout_ms : typing.Optional[int]

        tool_call_output_timeout_ms : typing.Optional[int]

        phone_number : typing.Optional[str]
            The E.164 formatted phone number to transfer calls to. Required for built_in_transfer_to_phone_number tools.

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

        Returns
        -------
        ToolsUpdateResponse
            Success response

        Examples
        --------
        from phonic import Phonic

        client = Phonic(
            api_key="YOUR_API_KEY",
        )
        client.tools.update(
            name_or_id="nameOrId",
            project="main",
            description="Updated description for booking appointments with enhanced features",
            endpoint_headers={"Authorization": "Bearer updated_token456"},
            endpoint_timeout_ms=7000,
        )
        """
        _response = self._raw_client.update(
            name_or_id,
            project=project,
            name=name,
            description=description,
            type=type,
            execution_mode=execution_mode,
            parameters=parameters,
            endpoint_method=endpoint_method,
            endpoint_url=endpoint_url,
            endpoint_headers=endpoint_headers,
            endpoint_timeout_ms=endpoint_timeout_ms,
            tool_call_output_timeout_ms=tool_call_output_timeout_ms,
            phone_number=phone_number,
            request_options=request_options,
        )
        return _response.data


class AsyncToolsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawToolsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawToolsClient
        """
        return self._raw_client

    async def list(
        self, *, project: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
    ) -> ToolsListResponse:
        """
        Returns all custom tools for the organization.

        Parameters
        ----------
        project : typing.Optional[str]
            The name of the project to list tools for.

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

        Returns
        -------
        ToolsListResponse
            Success response

        Examples
        --------
        import asyncio

        from phonic import AsyncPhonic

        client = AsyncPhonic(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tools.list(
                project="main",
            )


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

    async def create(
        self,
        *,
        name: str,
        description: str,
        type: CreateToolRequestType,
        execution_mode: CreateToolRequestExecutionMode,
        project: typing.Optional[str] = None,
        parameters: typing.Optional[typing.Sequence[ToolParameterParams]] = OMIT,
        endpoint_method: typing.Optional[CreateToolRequestEndpointMethod] = OMIT,
        endpoint_url: typing.Optional[str] = OMIT,
        endpoint_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
        endpoint_timeout_ms: typing.Optional[int] = OMIT,
        tool_call_output_timeout_ms: typing.Optional[int] = OMIT,
        phone_number: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ToolsCreateResponse:
        """
        Creates a new tool in a project.

        Parameters
        ----------
        name : str
            The name of the tool. Must be snake_case and unique within the organization.

        description : str
            A description of what the tool does.

        type : CreateToolRequestType
            The type of tool.

        execution_mode : CreateToolRequestExecutionMode
            Mode of operation.

        project : typing.Optional[str]
            The name of the project to create the tool in.

        parameters : typing.Optional[typing.Sequence[ToolParameterParams]]
            Array of parameter definitions.
            For `custom_webhook` tools with POST method, each parameter must include a `location` field.
            For `custom_webhook` tools with GET method, `location` defaults to `"query_string"` if not specified.
            For `custom_websocket` and `built_in_transfer_to_phone_number` tools, `location` must not be specified.

        endpoint_method : typing.Optional[CreateToolRequestEndpointMethod]
            Required for webhook tools. HTTP method for the webhook endpoint.

        endpoint_url : typing.Optional[str]
            Required for webhook tools.

        endpoint_headers : typing.Optional[typing.Dict[str, str]]
            Optional headers for webhook tools.

        endpoint_timeout_ms : typing.Optional[int]
            Timeout for webhook tools.

        tool_call_output_timeout_ms : typing.Optional[int]
            Timeout for WebSocket tool responses.

        phone_number : typing.Optional[str]
            The E.164 formatted phone number to transfer calls to. Required for built_in_transfer_to_phone_number tools.

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

        Returns
        -------
        ToolsCreateResponse
            Success response

        Examples
        --------
        import asyncio

        from phonic import AsyncPhonic

        client = AsyncPhonic(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tools.create(
                project="main",
                name="book_appointment",
                description="Books an appointment in the calendar system",
                type="custom_webhook",
                execution_mode="sync",
                parameters=[
                    {
                        "type": "string",
                        "name": "date",
                        "description": "The date for the appointment in YYYY-MM-DD format",
                        "is_required": True,
                        "location": "request_body",
                    },
                    {
                        "type": "string",
                        "name": "time",
                        "description": "The time for the appointment in HH:MM format",
                        "is_required": True,
                        "location": "request_body",
                    },
                ],
                endpoint_method="POST",
                endpoint_url="https://api.example.com/book-appointment",
                endpoint_headers={
                    "Authorization": "Bearer token123",
                    "Content-Type": "application/json",
                },
                endpoint_timeout_ms=5000,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create(
            name=name,
            description=description,
            type=type,
            execution_mode=execution_mode,
            project=project,
            parameters=parameters,
            endpoint_method=endpoint_method,
            endpoint_url=endpoint_url,
            endpoint_headers=endpoint_headers,
            endpoint_timeout_ms=endpoint_timeout_ms,
            tool_call_output_timeout_ms=tool_call_output_timeout_ms,
            phone_number=phone_number,
            request_options=request_options,
        )
        return _response.data

    async def get(
        self,
        name_or_id: str,
        *,
        project: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ToolsGetResponse:
        """
        Returns a tool by name or ID.

        Parameters
        ----------
        name_or_id : str
            The name or the ID of the tool to get.

        project : typing.Optional[str]
            The name of the project containing the tool. Only used when `nameOrId` is a name.

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

        Returns
        -------
        ToolsGetResponse
            Success response

        Examples
        --------
        import asyncio

        from phonic import AsyncPhonic

        client = AsyncPhonic(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tools.get(
                name_or_id="nameOrId",
                project="main",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get(name_or_id, project=project, request_options=request_options)
        return _response.data

    async def delete(
        self,
        name_or_id: str,
        *,
        project: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ToolsDeleteResponse:
        """
        Deletes a tool by name or ID.

        Parameters
        ----------
        name_or_id : str
            The name or the ID of the tool to delete.

        project : typing.Optional[str]
            The name of the project containing the tool. Only used when `nameOrId` is a name.

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

        Returns
        -------
        ToolsDeleteResponse
            Success response

        Examples
        --------
        import asyncio

        from phonic import AsyncPhonic

        client = AsyncPhonic(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tools.delete(
                name_or_id="nameOrId",
                project="main",
            )


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

    async def update(
        self,
        name_or_id: str,
        *,
        project: typing.Optional[str] = None,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        type: typing.Optional[UpdateToolRequestType] = OMIT,
        execution_mode: typing.Optional[UpdateToolRequestExecutionMode] = OMIT,
        parameters: typing.Optional[typing.Sequence[ToolParameterParams]] = OMIT,
        endpoint_method: typing.Optional[UpdateToolRequestEndpointMethod] = OMIT,
        endpoint_url: typing.Optional[str] = OMIT,
        endpoint_headers: typing.Optional[typing.Dict[str, str]] = OMIT,
        endpoint_timeout_ms: typing.Optional[int] = OMIT,
        tool_call_output_timeout_ms: typing.Optional[int] = OMIT,
        phone_number: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ToolsUpdateResponse:
        """
        Updates a tool by name or ID.

        Parameters
        ----------
        name_or_id : str
            The name or the ID of the tool to update.

        project : typing.Optional[str]
            The name of the project containing the tool. Only used when `nameOrId` is a name.

        name : typing.Optional[str]
            The name of the tool. Must be snake_case and unique within the organization.

        description : typing.Optional[str]
            A description of what the tool does.

        type : typing.Optional[UpdateToolRequestType]
            The type of tool.

        execution_mode : typing.Optional[UpdateToolRequestExecutionMode]
            Mode of operation.

        parameters : typing.Optional[typing.Sequence[ToolParameterParams]]
            Array of parameter definitions.
            When updating `type` or `endpoint_method`, all parameters must include explicit `location` values.
            For `custom_webhook` tools: `location` is required for POST, defaults to `"query_string"` for GET.
            For `custom_websocket` and `built_in_transfer_to_phone_number` tools: `location` must not be specified.

        endpoint_method : typing.Optional[UpdateToolRequestEndpointMethod]
            HTTP method for webhook tools. When changing this value, all parameters must include explicit `location` values.

        endpoint_url : typing.Optional[str]

        endpoint_headers : typing.Optional[typing.Dict[str, str]]

        endpoint_timeout_ms : typing.Optional[int]

        tool_call_output_timeout_ms : typing.Optional[int]

        phone_number : typing.Optional[str]
            The E.164 formatted phone number to transfer calls to. Required for built_in_transfer_to_phone_number tools.

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

        Returns
        -------
        ToolsUpdateResponse
            Success response

        Examples
        --------
        import asyncio

        from phonic import AsyncPhonic

        client = AsyncPhonic(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.tools.update(
                name_or_id="nameOrId",
                project="main",
                description="Updated description for booking appointments with enhanced features",
                endpoint_headers={"Authorization": "Bearer updated_token456"},
                endpoint_timeout_ms=7000,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update(
            name_or_id,
            project=project,
            name=name,
            description=description,
            type=type,
            execution_mode=execution_mode,
            parameters=parameters,
            endpoint_method=endpoint_method,
            endpoint_url=endpoint_url,
            endpoint_headers=endpoint_headers,
            endpoint_timeout_ms=endpoint_timeout_ms,
            tool_call_output_timeout_ms=tool_call_output_timeout_ms,
            phone_number=phone_number,
            request_options=request_options,
        )
        return _response.data
