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

import typing
from ...core.client_wrapper import SyncClientWrapper
from ...core.request_options import RequestOptions
from ...core.pagination import SyncPager
from ..types.return_user_defined_tool import ReturnUserDefinedTool
from ..types.return_paged_user_defined_tools import ReturnPagedUserDefinedTools
from ...core.pydantic_utilities import parse_obj_as
from ..errors.bad_request_error import BadRequestError
from ..types.error_response import ErrorResponse
from json.decoder import JSONDecodeError
from ...core.api_error import ApiError
from ...core.jsonable_encoder import jsonable_encoder
from ...core.client_wrapper import AsyncClientWrapper
from ...core.pagination import AsyncPager

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


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

    def list_tools(
        self,
        *,
        page_number: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        restrict_to_most_recent: typing.Optional[bool] = None,
        name: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[typing.Optional[ReturnUserDefinedTool]]:
        """
        Fetches a paginated list of **Tools**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        page_number : typing.Optional[int]
            Specifies the page number to retrieve, enabling pagination.

            This parameter uses zero-based indexing. For example, setting `page_number` to 0 retrieves the first page of results (items 0-9 if `page_size` is 10), setting `page_number` to 1 retrieves the second page (items 10-19), and so on. Defaults to 0, which retrieves the first page.

        page_size : typing.Optional[int]
            Specifies the maximum number of results to include per page, enabling pagination. The value must be between 1 and 100, inclusive.

            For example, if `page_size` is set to 10, each page will include up to 10 items. Defaults to 10.

        restrict_to_most_recent : typing.Optional[bool]
            By default, `restrict_to_most_recent` is set to true, returning only the latest version of each tool. To include all versions of each tool in the list, set `restrict_to_most_recent` to false.

        name : typing.Optional[str]
            Filter to only include tools with name.

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

        Returns
        -------
        SyncPager[typing.Optional[ReturnUserDefinedTool]]
            Success

        Examples
        --------
        from hume import HumeClient

        client = HumeClient(
            api_key="YOUR_API_KEY",
        )
        response = client.empathic_voice.tools.list_tools(
            page_number=0,
            page_size=2,
        )
        for item in response:
            yield item
        # alternatively, you can paginate page-by-page
        for page in response.iter_pages():
            yield page
        """
        page_number = page_number if page_number is not None else 1
        _response = self._client_wrapper.httpx_client.request(
            "v0/evi/tools",
            method="GET",
            params={
                "page_number": page_number,
                "page_size": page_size,
                "restrict_to_most_recent": restrict_to_most_recent,
                "name": name,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ReturnPagedUserDefinedTools,
                    parse_obj_as(
                        type_=ReturnPagedUserDefinedTools,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _has_next = True
                _get_next = lambda: self.list_tools(
                    page_number=page_number + 1,
                    page_size=page_size,
                    restrict_to_most_recent=restrict_to_most_recent,
                    name=name,
                    request_options=request_options,
                )
                _items = _parsed_response.tools_page
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create_tool(
        self,
        *,
        name: str,
        parameters: str,
        version_description: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        fallback_content: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[ReturnUserDefinedTool]:
        """
        Creates a **Tool** that can be added to an [EVI configuration](/reference/empathic-voice-interface-evi/configs/create-config).

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        name : str
            Name applied to all versions of a particular Tool.

        parameters : str
            Stringified JSON defining the parameters used by this version of the Tool.

            These parameters define the inputs needed for the Tool’s execution, including the expected data type and description for each input field. Structured as a stringified JSON schema, this format ensures the Tool receives data in the expected format.

        version_description : typing.Optional[str]
            An optional description of the Tool version.

        description : typing.Optional[str]
            An optional description of what the Tool does, used by the supplemental LLM to choose when and how to call the function.

        fallback_content : typing.Optional[str]
            Optional text passed to the supplemental LLM in place of the tool call result. The LLM then uses this text to generate a response back to the user, ensuring continuity in the conversation if the Tool errors.

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

        Returns
        -------
        typing.Optional[ReturnUserDefinedTool]
            Created

        Examples
        --------
        from hume import HumeClient

        client = HumeClient(
            api_key="YOUR_API_KEY",
        )
        client.empathic_voice.tools.create_tool(
            name="get_current_weather",
            parameters='{ "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA" }, "format": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "The temperature unit to use. Infer this from the users location." } }, "required": ["location", "format"] }',
            version_description="Fetches current weather and uses celsius or fahrenheit based on location of user.",
            description="This tool is for getting the current weather.",
            fallback_content="Unable to fetch current weather.",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/evi/tools",
            method="POST",
            json={
                "name": name,
                "version_description": version_description,
                "description": description,
                "parameters": parameters,
                "fallback_content": fallback_content,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[ReturnUserDefinedTool],
                    parse_obj_as(
                        type_=typing.Optional[ReturnUserDefinedTool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def list_tool_versions(
        self,
        id: str,
        *,
        page_number: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        restrict_to_most_recent: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReturnPagedUserDefinedTools:
        """
        Fetches a list of a **Tool's** versions.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        page_number : typing.Optional[int]
            Specifies the page number to retrieve, enabling pagination.

            This parameter uses zero-based indexing. For example, setting `page_number` to 0 retrieves the first page of results (items 0-9 if `page_size` is 10), setting `page_number` to 1 retrieves the second page (items 10-19), and so on. Defaults to 0, which retrieves the first page.

        page_size : typing.Optional[int]
            Specifies the maximum number of results to include per page, enabling pagination. The value must be between 1 and 100, inclusive.

            For example, if `page_size` is set to 10, each page will include up to 10 items. Defaults to 10.

        restrict_to_most_recent : typing.Optional[bool]
            By default, `restrict_to_most_recent` is set to true, returning only the latest version of each tool. To include all versions of each tool in the list, set `restrict_to_most_recent` to false.

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

        Returns
        -------
        ReturnPagedUserDefinedTools
            Success

        Examples
        --------
        from hume import HumeClient

        client = HumeClient(
            api_key="YOUR_API_KEY",
        )
        client.empathic_voice.tools.list_tool_versions(
            id="00183a3f-79ba-413d-9f3b-609864268bea",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}",
            method="GET",
            params={
                "page_number": page_number,
                "page_size": page_size,
                "restrict_to_most_recent": restrict_to_most_recent,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReturnPagedUserDefinedTools,
                    parse_obj_as(
                        type_=ReturnPagedUserDefinedTools,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create_tool_version(
        self,
        id: str,
        *,
        parameters: str,
        version_description: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        fallback_content: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[ReturnUserDefinedTool]:
        """
        Updates a **Tool** by creating a new version of the **Tool**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        parameters : str
            Stringified JSON defining the parameters used by this version of the Tool.

            These parameters define the inputs needed for the Tool’s execution, including the expected data type and description for each input field. Structured as a stringified JSON schema, this format ensures the Tool receives data in the expected format.

        version_description : typing.Optional[str]
            An optional description of the Tool version.

        description : typing.Optional[str]
            An optional description of what the Tool does, used by the supplemental LLM to choose when and how to call the function.

        fallback_content : typing.Optional[str]
            Optional text passed to the supplemental LLM in place of the tool call result. The LLM then uses this text to generate a response back to the user, ensuring continuity in the conversation if the Tool errors.

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

        Returns
        -------
        typing.Optional[ReturnUserDefinedTool]
            Created

        Examples
        --------
        from hume import HumeClient

        client = HumeClient(
            api_key="YOUR_API_KEY",
        )
        client.empathic_voice.tools.create_tool_version(
            id="00183a3f-79ba-413d-9f3b-609864268bea",
            parameters='{ "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA" }, "format": { "type": "string", "enum": ["celsius", "fahrenheit", "kelvin"], "description": "The temperature unit to use. Infer this from the users location." } }, "required": ["location", "format"] }',
            version_description="Fetches current weather and uses celsius, fahrenheit, or kelvin based on location of user.",
            fallback_content="Unable to fetch current weather.",
            description="This tool is for getting the current weather.",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}",
            method="POST",
            json={
                "version_description": version_description,
                "description": description,
                "parameters": parameters,
                "fallback_content": fallback_content,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[ReturnUserDefinedTool],
                    parse_obj_as(
                        type_=typing.Optional[ReturnUserDefinedTool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete_tool(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Deletes a **Tool** and its versions.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

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

        Returns
        -------
        None

        Examples
        --------
        from hume import HumeClient

        client = HumeClient(
            api_key="YOUR_API_KEY",
        )
        client.empathic_voice.tools.delete_tool(
            id="00183a3f-79ba-413d-9f3b-609864268bea",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_tool_name(self, id: str, *, name: str, request_options: typing.Optional[RequestOptions] = None) -> str:
        """
        Updates the name of a **Tool**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        name : str
            Name applied to all versions of a particular Tool.

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

        Returns
        -------
        str
            Success

        Examples
        --------
        from hume import HumeClient

        client = HumeClient(
            api_key="YOUR_API_KEY",
        )
        client.empathic_voice.tools.update_tool_name(
            id="00183a3f-79ba-413d-9f3b-609864268bea",
            name="get_current_temperature",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}",
            method="PATCH",
            json={
                "name": name,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return _response.text  # type: ignore
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_tool_version(
        self, id: str, version: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[ReturnUserDefinedTool]:
        """
        Fetches a specified version of a **Tool**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        version : int
            Version number for a Tool.

            Tools, Configs, Custom Voices, and Prompts are versioned. This versioning system supports iterative development, allowing you to progressively refine tools and revert to previous versions if needed.

            Version numbers are integer values representing different iterations of the Tool. Each update to the Tool increments its version number.

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

        Returns
        -------
        typing.Optional[ReturnUserDefinedTool]
            Success

        Examples
        --------
        from hume import HumeClient

        client = HumeClient(
            api_key="YOUR_API_KEY",
        )
        client.empathic_voice.tools.get_tool_version(
            id="00183a3f-79ba-413d-9f3b-609864268bea",
            version=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}/version/{jsonable_encoder(version)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[ReturnUserDefinedTool],
                    parse_obj_as(
                        type_=typing.Optional[ReturnUserDefinedTool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete_tool_version(
        self, id: str, version: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Deletes a specified version of a **Tool**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        version : int
            Version number for a Tool.

            Tools, Configs, Custom Voices, and Prompts are versioned. This versioning system supports iterative development, allowing you to progressively refine tools and revert to previous versions if needed.

            Version numbers are integer values representing different iterations of the Tool. Each update to the Tool increments its version number.

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

        Returns
        -------
        None

        Examples
        --------
        from hume import HumeClient

        client = HumeClient(
            api_key="YOUR_API_KEY",
        )
        client.empathic_voice.tools.delete_tool_version(
            id="00183a3f-79ba-413d-9f3b-609864268bea",
            version=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}/version/{jsonable_encoder(version)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_tool_description(
        self,
        id: str,
        version: int,
        *,
        version_description: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[ReturnUserDefinedTool]:
        """
        Updates the description of a specified **Tool** version.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        version : int
            Version number for a Tool.

            Tools, Configs, Custom Voices, and Prompts are versioned. This versioning system supports iterative development, allowing you to progressively refine tools and revert to previous versions if needed.

            Version numbers are integer values representing different iterations of the Tool. Each update to the Tool increments its version number.

        version_description : typing.Optional[str]
            An optional description of the Tool version.

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

        Returns
        -------
        typing.Optional[ReturnUserDefinedTool]
            Success

        Examples
        --------
        from hume import HumeClient

        client = HumeClient(
            api_key="YOUR_API_KEY",
        )
        client.empathic_voice.tools.update_tool_description(
            id="00183a3f-79ba-413d-9f3b-609864268bea",
            version=1,
            version_description="Fetches current temperature, precipitation, wind speed, AQI, and other weather conditions. Uses Celsius, Fahrenheit, or kelvin depending on user's region.",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}/version/{jsonable_encoder(version)}",
            method="PATCH",
            json={
                "version_description": version_description,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[ReturnUserDefinedTool],
                    parse_obj_as(
                        type_=typing.Optional[ReturnUserDefinedTool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


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

    async def list_tools(
        self,
        *,
        page_number: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        restrict_to_most_recent: typing.Optional[bool] = None,
        name: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[typing.Optional[ReturnUserDefinedTool]]:
        """
        Fetches a paginated list of **Tools**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        page_number : typing.Optional[int]
            Specifies the page number to retrieve, enabling pagination.

            This parameter uses zero-based indexing. For example, setting `page_number` to 0 retrieves the first page of results (items 0-9 if `page_size` is 10), setting `page_number` to 1 retrieves the second page (items 10-19), and so on. Defaults to 0, which retrieves the first page.

        page_size : typing.Optional[int]
            Specifies the maximum number of results to include per page, enabling pagination. The value must be between 1 and 100, inclusive.

            For example, if `page_size` is set to 10, each page will include up to 10 items. Defaults to 10.

        restrict_to_most_recent : typing.Optional[bool]
            By default, `restrict_to_most_recent` is set to true, returning only the latest version of each tool. To include all versions of each tool in the list, set `restrict_to_most_recent` to false.

        name : typing.Optional[str]
            Filter to only include tools with name.

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

        Returns
        -------
        AsyncPager[typing.Optional[ReturnUserDefinedTool]]
            Success

        Examples
        --------
        import asyncio

        from hume import AsyncHumeClient

        client = AsyncHumeClient(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            response = await client.empathic_voice.tools.list_tools(
                page_number=0,
                page_size=2,
            )
            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())
        """
        page_number = page_number if page_number is not None else 1
        _response = await self._client_wrapper.httpx_client.request(
            "v0/evi/tools",
            method="GET",
            params={
                "page_number": page_number,
                "page_size": page_size,
                "restrict_to_most_recent": restrict_to_most_recent,
                "name": name,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ReturnPagedUserDefinedTools,
                    parse_obj_as(
                        type_=ReturnPagedUserDefinedTools,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _has_next = True
                _get_next = lambda: self.list_tools(
                    page_number=page_number + 1,
                    page_size=page_size,
                    restrict_to_most_recent=restrict_to_most_recent,
                    name=name,
                    request_options=request_options,
                )
                _items = _parsed_response.tools_page
                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create_tool(
        self,
        *,
        name: str,
        parameters: str,
        version_description: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        fallback_content: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[ReturnUserDefinedTool]:
        """
        Creates a **Tool** that can be added to an [EVI configuration](/reference/empathic-voice-interface-evi/configs/create-config).

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        name : str
            Name applied to all versions of a particular Tool.

        parameters : str
            Stringified JSON defining the parameters used by this version of the Tool.

            These parameters define the inputs needed for the Tool’s execution, including the expected data type and description for each input field. Structured as a stringified JSON schema, this format ensures the Tool receives data in the expected format.

        version_description : typing.Optional[str]
            An optional description of the Tool version.

        description : typing.Optional[str]
            An optional description of what the Tool does, used by the supplemental LLM to choose when and how to call the function.

        fallback_content : typing.Optional[str]
            Optional text passed to the supplemental LLM in place of the tool call result. The LLM then uses this text to generate a response back to the user, ensuring continuity in the conversation if the Tool errors.

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

        Returns
        -------
        typing.Optional[ReturnUserDefinedTool]
            Created

        Examples
        --------
        import asyncio

        from hume import AsyncHumeClient

        client = AsyncHumeClient(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.empathic_voice.tools.create_tool(
                name="get_current_weather",
                parameters='{ "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA" }, "format": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "The temperature unit to use. Infer this from the users location." } }, "required": ["location", "format"] }',
                version_description="Fetches current weather and uses celsius or fahrenheit based on location of user.",
                description="This tool is for getting the current weather.",
                fallback_content="Unable to fetch current weather.",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/evi/tools",
            method="POST",
            json={
                "name": name,
                "version_description": version_description,
                "description": description,
                "parameters": parameters,
                "fallback_content": fallback_content,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[ReturnUserDefinedTool],
                    parse_obj_as(
                        type_=typing.Optional[ReturnUserDefinedTool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def list_tool_versions(
        self,
        id: str,
        *,
        page_number: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        restrict_to_most_recent: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReturnPagedUserDefinedTools:
        """
        Fetches a list of a **Tool's** versions.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        page_number : typing.Optional[int]
            Specifies the page number to retrieve, enabling pagination.

            This parameter uses zero-based indexing. For example, setting `page_number` to 0 retrieves the first page of results (items 0-9 if `page_size` is 10), setting `page_number` to 1 retrieves the second page (items 10-19), and so on. Defaults to 0, which retrieves the first page.

        page_size : typing.Optional[int]
            Specifies the maximum number of results to include per page, enabling pagination. The value must be between 1 and 100, inclusive.

            For example, if `page_size` is set to 10, each page will include up to 10 items. Defaults to 10.

        restrict_to_most_recent : typing.Optional[bool]
            By default, `restrict_to_most_recent` is set to true, returning only the latest version of each tool. To include all versions of each tool in the list, set `restrict_to_most_recent` to false.

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

        Returns
        -------
        ReturnPagedUserDefinedTools
            Success

        Examples
        --------
        import asyncio

        from hume import AsyncHumeClient

        client = AsyncHumeClient(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.empathic_voice.tools.list_tool_versions(
                id="00183a3f-79ba-413d-9f3b-609864268bea",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}",
            method="GET",
            params={
                "page_number": page_number,
                "page_size": page_size,
                "restrict_to_most_recent": restrict_to_most_recent,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReturnPagedUserDefinedTools,
                    parse_obj_as(
                        type_=ReturnPagedUserDefinedTools,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create_tool_version(
        self,
        id: str,
        *,
        parameters: str,
        version_description: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        fallback_content: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[ReturnUserDefinedTool]:
        """
        Updates a **Tool** by creating a new version of the **Tool**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        parameters : str
            Stringified JSON defining the parameters used by this version of the Tool.

            These parameters define the inputs needed for the Tool’s execution, including the expected data type and description for each input field. Structured as a stringified JSON schema, this format ensures the Tool receives data in the expected format.

        version_description : typing.Optional[str]
            An optional description of the Tool version.

        description : typing.Optional[str]
            An optional description of what the Tool does, used by the supplemental LLM to choose when and how to call the function.

        fallback_content : typing.Optional[str]
            Optional text passed to the supplemental LLM in place of the tool call result. The LLM then uses this text to generate a response back to the user, ensuring continuity in the conversation if the Tool errors.

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

        Returns
        -------
        typing.Optional[ReturnUserDefinedTool]
            Created

        Examples
        --------
        import asyncio

        from hume import AsyncHumeClient

        client = AsyncHumeClient(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.empathic_voice.tools.create_tool_version(
                id="00183a3f-79ba-413d-9f3b-609864268bea",
                parameters='{ "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA" }, "format": { "type": "string", "enum": ["celsius", "fahrenheit", "kelvin"], "description": "The temperature unit to use. Infer this from the users location." } }, "required": ["location", "format"] }',
                version_description="Fetches current weather and uses celsius, fahrenheit, or kelvin based on location of user.",
                fallback_content="Unable to fetch current weather.",
                description="This tool is for getting the current weather.",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}",
            method="POST",
            json={
                "version_description": version_description,
                "description": description,
                "parameters": parameters,
                "fallback_content": fallback_content,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[ReturnUserDefinedTool],
                    parse_obj_as(
                        type_=typing.Optional[ReturnUserDefinedTool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete_tool(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Deletes a **Tool** and its versions.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from hume import AsyncHumeClient

        client = AsyncHumeClient(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.empathic_voice.tools.delete_tool(
                id="00183a3f-79ba-413d-9f3b-609864268bea",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_tool_name(
        self, id: str, *, name: str, request_options: typing.Optional[RequestOptions] = None
    ) -> str:
        """
        Updates the name of a **Tool**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        name : str
            Name applied to all versions of a particular Tool.

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

        Returns
        -------
        str
            Success

        Examples
        --------
        import asyncio

        from hume import AsyncHumeClient

        client = AsyncHumeClient(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.empathic_voice.tools.update_tool_name(
                id="00183a3f-79ba-413d-9f3b-609864268bea",
                name="get_current_temperature",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}",
            method="PATCH",
            json={
                "name": name,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return _response.text  # type: ignore
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_tool_version(
        self, id: str, version: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[ReturnUserDefinedTool]:
        """
        Fetches a specified version of a **Tool**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        version : int
            Version number for a Tool.

            Tools, Configs, Custom Voices, and Prompts are versioned. This versioning system supports iterative development, allowing you to progressively refine tools and revert to previous versions if needed.

            Version numbers are integer values representing different iterations of the Tool. Each update to the Tool increments its version number.

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

        Returns
        -------
        typing.Optional[ReturnUserDefinedTool]
            Success

        Examples
        --------
        import asyncio

        from hume import AsyncHumeClient

        client = AsyncHumeClient(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.empathic_voice.tools.get_tool_version(
                id="00183a3f-79ba-413d-9f3b-609864268bea",
                version=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}/version/{jsonable_encoder(version)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[ReturnUserDefinedTool],
                    parse_obj_as(
                        type_=typing.Optional[ReturnUserDefinedTool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete_tool_version(
        self, id: str, version: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Deletes a specified version of a **Tool**.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        version : int
            Version number for a Tool.

            Tools, Configs, Custom Voices, and Prompts are versioned. This versioning system supports iterative development, allowing you to progressively refine tools and revert to previous versions if needed.

            Version numbers are integer values representing different iterations of the Tool. Each update to the Tool increments its version number.

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from hume import AsyncHumeClient

        client = AsyncHumeClient(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.empathic_voice.tools.delete_tool_version(
                id="00183a3f-79ba-413d-9f3b-609864268bea",
                version=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}/version/{jsonable_encoder(version)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_tool_description(
        self,
        id: str,
        version: int,
        *,
        version_description: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[ReturnUserDefinedTool]:
        """
        Updates the description of a specified **Tool** version.

        Refer to our [tool use](/docs/empathic-voice-interface-evi/tool-use#function-calling) guide for comprehensive instructions on defining and integrating tools into EVI.

        Parameters
        ----------
        id : str
            Identifier for a Tool. Formatted as a UUID.

        version : int
            Version number for a Tool.

            Tools, Configs, Custom Voices, and Prompts are versioned. This versioning system supports iterative development, allowing you to progressively refine tools and revert to previous versions if needed.

            Version numbers are integer values representing different iterations of the Tool. Each update to the Tool increments its version number.

        version_description : typing.Optional[str]
            An optional description of the Tool version.

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

        Returns
        -------
        typing.Optional[ReturnUserDefinedTool]
            Success

        Examples
        --------
        import asyncio

        from hume import AsyncHumeClient

        client = AsyncHumeClient(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.empathic_voice.tools.update_tool_description(
                id="00183a3f-79ba-413d-9f3b-609864268bea",
                version=1,
                version_description="Fetches current temperature, precipitation, wind speed, AQI, and other weather conditions. Uses Celsius, Fahrenheit, or kelvin depending on user's region.",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v0/evi/tools/{jsonable_encoder(id)}/version/{jsonable_encoder(version)}",
            method="PATCH",
            json={
                "version_description": version_description,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[ReturnUserDefinedTool],
                    parse_obj_as(
                        type_=typing.Optional[ReturnUserDefinedTool],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        ErrorResponse,
                        parse_obj_as(
                            type_=ErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
