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

import typing
from json.decoder import JSONDecodeError

from ..commons.errors.bad_request_error import BadRequestError
from ..commons.errors.not_found_error import NotFoundError
from ..commons.errors.server_error import ServerError
from ..commons.types.action_parameter import ActionParameter
from ..commons.types.action_response import ActionResponse
from ..commons.types.entity_id import EntityId
from ..commons.types.entity_id_base import EntityIdBase
from ..commons.types.error_message import ErrorMessage
from ..commons.types.llm_inclusion_status import LlmInclusionStatus
from ..commons.types.precondition import Precondition
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.action_field import ActionField
from .types.action_filter import ActionFilter
from .types.actions_response import ActionsResponse

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


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

    def search(
        self,
        *,
        sort: typing.Optional[ActionField] = OMIT,
        filter: typing.Optional[ActionFilter] = OMIT,
        page: typing.Optional[int] = OMIT,
        size: typing.Optional[int] = OMIT,
        sort_desc: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ActionsResponse]:
        """
        Parameters
        ----------
        sort : typing.Optional[ActionField]

        filter : typing.Optional[ActionFilter]

        page : typing.Optional[int]
            Page number to return, defaults to 0

        size : typing.Optional[int]
            The size of the page to return, defaults to 20

        sort_desc : typing.Optional[bool]
            Whether to sort descending, defaults to true

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

        Returns
        -------
        HttpResponse[ActionsResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/actions/search",
            method="POST",
            json={
                "sort": sort,
                "filter": convert_and_respect_annotation_metadata(
                    object_=filter, annotation=ActionFilter, direction="write"
                ),
                "page": page,
                "size": size,
                "sortDesc": sort_desc,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ActionsResponse,
                    parse_obj_as(
                        type_=ActionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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_or_update(
        self,
        *,
        action_id: EntityIdBase,
        name: str,
        description: str,
        user_interaction_required: bool,
        user_form_parameters: typing.Sequence[ActionParameter],
        button_name: typing.Optional[str] = OMIT,
        precondition: typing.Optional[Precondition] = OMIT,
        language: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ActionResponse]:
        """
        Update an action or create it if it doesn't exist

        Parameters
        ----------
        action_id : EntityIdBase
            ID that uniquely identifies this action

        name : str
            The name of the action. This is displayed to the end user as part of forms when user interaction is required. It is also used to help Maven decide if the action is relevant to a conversation.

        description : str
            The description of the action. Must be less than 1024 characters. This helps Maven decide if the action is relevant to a conversation and is not displayed directly to the end user. Descriptions are used by the LLM.

        user_interaction_required : bool
            Whether the action requires user interaction to execute. If false, and all of the required action parameters are known, the LLM may call the action automatically. If true, an conversations ask call will return a BotActionFormResponse which must be submitted by an API caller. API callers must display a button with the buttonName label to confirm the user's intent.

        user_form_parameters : typing.Sequence[ActionParameter]
            The parameters that the action uses as input. An action will only be executed when all of the required parameters are provided. During execution, actions all have access to the full Conversation and User objects. Parameter values may be inferred from the user's conversation by the LLM.

        button_name : typing.Optional[str]
            When user interaction is required, the name of the button that is shown to the end user to confirm execution of the action. Defaults to "Submit" if not supplied.

        precondition : typing.Optional[Precondition]
            The preconditions that must be met for an action to be relevant to a conversation. Can be used to restrict actions to certain types of users.

        language : typing.Optional[str]
            The ISO 639-1 code for the language used in all fields of this action. Will be derived using the description's text if not specified.

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

        Returns
        -------
        HttpResponse[ActionResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/actions",
            method="PUT",
            json={
                "actionId": convert_and_respect_annotation_metadata(
                    object_=action_id, annotation=EntityIdBase, direction="write"
                ),
                "name": name,
                "description": description,
                "userInteractionRequired": user_interaction_required,
                "buttonName": button_name,
                "precondition": convert_and_respect_annotation_metadata(
                    object_=precondition, annotation=Precondition, direction="write"
                ),
                "userFormParameters": convert_and_respect_annotation_metadata(
                    object_=user_form_parameters, annotation=typing.Sequence[ActionParameter], direction="write"
                ),
                "language": language,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ActionResponse,
                    parse_obj_as(
                        type_=ActionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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(
        self,
        action_reference_id: str,
        *,
        app_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ActionResponse]:
        """
        Get an action by its supplied ID

        Parameters
        ----------
        action_reference_id : str
            The reference ID of the action to get. All other entity ID fields are inferred from the request.

        app_id : typing.Optional[str]
            The App ID of the action to get. If not provided the ID of the calling app will be used.

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

        Returns
        -------
        HttpResponse[ActionResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/actions/{jsonable_encoder(action_reference_id)}",
            method="GET",
            params={
                "appId": app_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ActionResponse,
                    parse_obj_as(
                        type_=ActionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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 patch(
        self,
        action_reference_id: str,
        *,
        app_id: typing.Optional[str] = OMIT,
        instructions: typing.Optional[str] = OMIT,
        llm_inclusion_status: typing.Optional[LlmInclusionStatus] = OMIT,
        segment_id: typing.Optional[EntityId] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ActionResponse]:
        """
        Update mutable action fields

        The `appId` field can be provided to update an action owned by a different app.
        All other fields will overwrite the existing value on the action only if provided.

        Parameters
        ----------
        action_reference_id : str
            The reference ID of the action to patch.

        app_id : typing.Optional[str]
            The App ID of the action to patch. If not provided the ID of the calling app will be used.

        instructions : typing.Optional[str]
            The instructions given to the LLM when determining whether to execute the action.

        llm_inclusion_status : typing.Optional[LlmInclusionStatus]
            Determines whether the action is sent to the LLM as part of a conversation.

        segment_id : typing.Optional[EntityId]
            The ID of the segment that must be matched for the action to be relevant to a conversation.
            A null value will remove the segment from the action, it will be available on all conversations.

            Segments are replacing inline preconditions - an action may not have both an inline precondition and a segment.
            Inline precondition support will be removed in a future release.

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

        Returns
        -------
        HttpResponse[ActionResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/actions/{jsonable_encoder(action_reference_id)}",
            method="PATCH",
            json={
                "appId": app_id,
                "instructions": instructions,
                "llmInclusionStatus": llm_inclusion_status,
                "segmentId": convert_and_respect_annotation_metadata(
                    object_=segment_id, annotation=typing.Optional[EntityId], direction="write"
                ),
            },
            headers={
                "content-type": "application/merge-patch+json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ActionResponse,
                    parse_obj_as(
                        type_=ActionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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(
        self, action_reference_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Delete an action

        Parameters
        ----------
        action_reference_id : str
            The reference ID of the action to unregister. All other entity ID fields are inferred from the request.

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/actions/{jsonable_encoder(action_reference_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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 AsyncRawActionsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def search(
        self,
        *,
        sort: typing.Optional[ActionField] = OMIT,
        filter: typing.Optional[ActionFilter] = OMIT,
        page: typing.Optional[int] = OMIT,
        size: typing.Optional[int] = OMIT,
        sort_desc: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ActionsResponse]:
        """
        Parameters
        ----------
        sort : typing.Optional[ActionField]

        filter : typing.Optional[ActionFilter]

        page : typing.Optional[int]
            Page number to return, defaults to 0

        size : typing.Optional[int]
            The size of the page to return, defaults to 20

        sort_desc : typing.Optional[bool]
            Whether to sort descending, defaults to true

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

        Returns
        -------
        AsyncHttpResponse[ActionsResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/actions/search",
            method="POST",
            json={
                "sort": sort,
                "filter": convert_and_respect_annotation_metadata(
                    object_=filter, annotation=ActionFilter, direction="write"
                ),
                "page": page,
                "size": size,
                "sortDesc": sort_desc,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ActionsResponse,
                    parse_obj_as(
                        type_=ActionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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_or_update(
        self,
        *,
        action_id: EntityIdBase,
        name: str,
        description: str,
        user_interaction_required: bool,
        user_form_parameters: typing.Sequence[ActionParameter],
        button_name: typing.Optional[str] = OMIT,
        precondition: typing.Optional[Precondition] = OMIT,
        language: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ActionResponse]:
        """
        Update an action or create it if it doesn't exist

        Parameters
        ----------
        action_id : EntityIdBase
            ID that uniquely identifies this action

        name : str
            The name of the action. This is displayed to the end user as part of forms when user interaction is required. It is also used to help Maven decide if the action is relevant to a conversation.

        description : str
            The description of the action. Must be less than 1024 characters. This helps Maven decide if the action is relevant to a conversation and is not displayed directly to the end user. Descriptions are used by the LLM.

        user_interaction_required : bool
            Whether the action requires user interaction to execute. If false, and all of the required action parameters are known, the LLM may call the action automatically. If true, an conversations ask call will return a BotActionFormResponse which must be submitted by an API caller. API callers must display a button with the buttonName label to confirm the user's intent.

        user_form_parameters : typing.Sequence[ActionParameter]
            The parameters that the action uses as input. An action will only be executed when all of the required parameters are provided. During execution, actions all have access to the full Conversation and User objects. Parameter values may be inferred from the user's conversation by the LLM.

        button_name : typing.Optional[str]
            When user interaction is required, the name of the button that is shown to the end user to confirm execution of the action. Defaults to "Submit" if not supplied.

        precondition : typing.Optional[Precondition]
            The preconditions that must be met for an action to be relevant to a conversation. Can be used to restrict actions to certain types of users.

        language : typing.Optional[str]
            The ISO 639-1 code for the language used in all fields of this action. Will be derived using the description's text if not specified.

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

        Returns
        -------
        AsyncHttpResponse[ActionResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/actions",
            method="PUT",
            json={
                "actionId": convert_and_respect_annotation_metadata(
                    object_=action_id, annotation=EntityIdBase, direction="write"
                ),
                "name": name,
                "description": description,
                "userInteractionRequired": user_interaction_required,
                "buttonName": button_name,
                "precondition": convert_and_respect_annotation_metadata(
                    object_=precondition, annotation=Precondition, direction="write"
                ),
                "userFormParameters": convert_and_respect_annotation_metadata(
                    object_=user_form_parameters, annotation=typing.Sequence[ActionParameter], direction="write"
                ),
                "language": language,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ActionResponse,
                    parse_obj_as(
                        type_=ActionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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(
        self,
        action_reference_id: str,
        *,
        app_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ActionResponse]:
        """
        Get an action by its supplied ID

        Parameters
        ----------
        action_reference_id : str
            The reference ID of the action to get. All other entity ID fields are inferred from the request.

        app_id : typing.Optional[str]
            The App ID of the action to get. If not provided the ID of the calling app will be used.

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

        Returns
        -------
        AsyncHttpResponse[ActionResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/actions/{jsonable_encoder(action_reference_id)}",
            method="GET",
            params={
                "appId": app_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ActionResponse,
                    parse_obj_as(
                        type_=ActionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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 patch(
        self,
        action_reference_id: str,
        *,
        app_id: typing.Optional[str] = OMIT,
        instructions: typing.Optional[str] = OMIT,
        llm_inclusion_status: typing.Optional[LlmInclusionStatus] = OMIT,
        segment_id: typing.Optional[EntityId] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ActionResponse]:
        """
        Update mutable action fields

        The `appId` field can be provided to update an action owned by a different app.
        All other fields will overwrite the existing value on the action only if provided.

        Parameters
        ----------
        action_reference_id : str
            The reference ID of the action to patch.

        app_id : typing.Optional[str]
            The App ID of the action to patch. If not provided the ID of the calling app will be used.

        instructions : typing.Optional[str]
            The instructions given to the LLM when determining whether to execute the action.

        llm_inclusion_status : typing.Optional[LlmInclusionStatus]
            Determines whether the action is sent to the LLM as part of a conversation.

        segment_id : typing.Optional[EntityId]
            The ID of the segment that must be matched for the action to be relevant to a conversation.
            A null value will remove the segment from the action, it will be available on all conversations.

            Segments are replacing inline preconditions - an action may not have both an inline precondition and a segment.
            Inline precondition support will be removed in a future release.

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

        Returns
        -------
        AsyncHttpResponse[ActionResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/actions/{jsonable_encoder(action_reference_id)}",
            method="PATCH",
            json={
                "appId": app_id,
                "instructions": instructions,
                "llmInclusionStatus": llm_inclusion_status,
                "segmentId": convert_and_respect_annotation_metadata(
                    object_=segment_id, annotation=typing.Optional[EntityId], direction="write"
                ),
            },
            headers={
                "content-type": "application/merge-patch+json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ActionResponse,
                    parse_obj_as(
                        type_=ActionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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(
        self, action_reference_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Delete an action

        Parameters
        ----------
        action_reference_id : str
            The reference ID of the action to unregister. All other entity ID fields are inferred from the request.

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/actions/{jsonable_encoder(action_reference_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise ServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        ErrorMessage,
                        parse_obj_as(
                            type_=ErrorMessage,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _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)
