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

import datetime as dt
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.entity_id import EntityId
from ..commons.types.entity_id_base import EntityIdBase
from ..commons.types.entity_id_without_agent import EntityIdWithoutAgent
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.knowledge_base_field import KnowledgeBaseField
from .types.knowledge_base_filter import KnowledgeBaseFilter
from .types.knowledge_base_refresh_frequency import KnowledgeBaseRefreshFrequency
from .types.knowledge_base_response import KnowledgeBaseResponse
from .types.knowledge_base_version import KnowledgeBaseVersion
from .types.knowledge_base_version_finalize_status import KnowledgeBaseVersionFinalizeStatus
from .types.knowledge_base_version_type import KnowledgeBaseVersionType
from .types.knowledge_base_versions_list_response import KnowledgeBaseVersionsListResponse
from .types.knowledge_bases_response import KnowledgeBasesResponse
from .types.knowledge_document_content_type import KnowledgeDocumentContentType
from .types.knowledge_document_field import KnowledgeDocumentField
from .types.knowledge_document_filter import KnowledgeDocumentFilter
from .types.knowledge_document_response import KnowledgeDocumentResponse
from .types.knowledge_documents_response import KnowledgeDocumentsResponse

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


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

    def search_knowledge_bases(
        self,
        *,
        sort: typing.Optional[KnowledgeBaseField] = OMIT,
        filter: typing.Optional[KnowledgeBaseFilter] = OMIT,
        page: typing.Optional[int] = OMIT,
        size: typing.Optional[int] = OMIT,
        sort_desc: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeBasesResponse]:
        """
        Search knowledge bases

        Parameters
        ----------
        sort : typing.Optional[KnowledgeBaseField]

        filter : typing.Optional[KnowledgeBaseFilter]

        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[KnowledgeBasesResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/knowledge/search",
            method="POST",
            json={
                "sort": sort,
                "filter": convert_and_respect_annotation_metadata(
                    object_=filter, annotation=KnowledgeBaseFilter, 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(
                    KnowledgeBasesResponse,
                    parse_obj_as(
                        type_=KnowledgeBasesResponse,  # 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_knowledge_base(
        self,
        *,
        knowledge_base_id: EntityIdBase,
        name: str,
        metadata: typing.Optional[typing.Dict[str, str]] = OMIT,
        precondition: typing.Optional[Precondition] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeBaseResponse]:
        """
        Update a knowledge base or create it if it doesn't exist.

        Parameters
        ----------
        knowledge_base_id : EntityIdBase
            ID that uniquely identifies this knowledge base

        name : str
            The name of the knowledge base

        metadata : typing.Optional[typing.Dict[str, str]]
            Metadata for the knowledge base.

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

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

        Returns
        -------
        HttpResponse[KnowledgeBaseResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/knowledge",
            method="PUT",
            json={
                "knowledgeBaseId": convert_and_respect_annotation_metadata(
                    object_=knowledge_base_id, annotation=EntityIdBase, direction="write"
                ),
                "metadata": metadata,
                "name": name,
                "precondition": convert_and_respect_annotation_metadata(
                    object_=precondition, annotation=Precondition, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseResponse,
                    parse_obj_as(
                        type_=KnowledgeBaseResponse,  # 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_knowledge_base(
        self,
        knowledge_base_reference_id: str,
        *,
        app_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeBaseResponse]:
        """
        Get an existing knowledge base by its supplied ID

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

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

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

        Returns
        -------
        HttpResponse[KnowledgeBaseResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}",
            method="GET",
            params={
                "appId": app_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseResponse,
                    parse_obj_as(
                        type_=KnowledgeBaseResponse,  # 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_knowledge_base(
        self,
        knowledge_base_reference_id: str,
        *,
        app_id: typing.Optional[str] = OMIT,
        name: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Set[str]] = OMIT,
        llm_inclusion_status: typing.Optional[LlmInclusionStatus] = OMIT,
        precondition: typing.Optional[Precondition] = OMIT,
        segment_id: typing.Optional[EntityId] = OMIT,
        refresh_frequency: typing.Optional[KnowledgeBaseRefreshFrequency] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeBaseResponse]:
        """
        Update mutable knowledge base fields

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

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to patch.

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

        name : typing.Optional[str]
            The name of the knowledge base.

        tags : typing.Optional[typing.Set[str]]
            The tags of the knowledge base.

        llm_inclusion_status : typing.Optional[LlmInclusionStatus]
            Determines whether documents in the knowledge base are sent to the LLM as part of a conversation. Note that at this time knowledge bases can not be set to `ALWAYS`.

        precondition : typing.Optional[Precondition]
            The preconditions that must be met for a knowledge base to be relevant to a conversation. Can be used to restrict knowledge bases to certain types of users. A null value will remove the precondition from the knowledge base, it will be available on all conversations.

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

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

        refresh_frequency : typing.Optional[KnowledgeBaseRefreshFrequency]
            How often the knowledge base should be refreshed.

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

        Returns
        -------
        HttpResponse[KnowledgeBaseResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}",
            method="PATCH",
            json={
                "appId": app_id,
                "name": name,
                "tags": tags,
                "llmInclusionStatus": llm_inclusion_status,
                "precondition": convert_and_respect_annotation_metadata(
                    object_=precondition, annotation=typing.Optional[Precondition], direction="write"
                ),
                "segmentId": convert_and_respect_annotation_metadata(
                    object_=segment_id, annotation=typing.Optional[EntityId], direction="write"
                ),
                "refreshFrequency": refresh_frequency,
            },
            headers={
                "content-type": "application/merge-patch+json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseResponse,
                    parse_obj_as(
                        type_=KnowledgeBaseResponse,  # 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_knowledge_base_version(
        self,
        knowledge_base_reference_id: str,
        *,
        type: KnowledgeBaseVersionType,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeBaseVersion]:
        """
        Create a new knowledge base version.

        If an existing version is in progress, then that version will be finalized in an error state.

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to create a version for. All other entity ID fields are inferred from the request.

        type : KnowledgeBaseVersionType
            Indicates whether the completed version constitutes a full or partial refresh of the knowledge base. Deleting and updating documents is only supported for partial refreshes.

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

        Returns
        -------
        HttpResponse[KnowledgeBaseVersion]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/version",
            method="POST",
            json={
                "type": type,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseVersion,
                    parse_obj_as(
                        type_=KnowledgeBaseVersion,  # 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 finalize_knowledge_base_version(
        self,
        knowledge_base_reference_id: str,
        *,
        version_id: typing.Optional[EntityIdWithoutAgent] = OMIT,
        status: typing.Optional[KnowledgeBaseVersionFinalizeStatus] = OMIT,
        error_message: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeBaseVersion]:
        """
        Finalize the latest knowledge base version. Required to indicate the version is complete. Will throw an exception if the latest version is not in progress.

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to finalize a version for. All other entity ID fields are inferred from the request.

        version_id : typing.Optional[EntityIdWithoutAgent]
            ID that uniquely identifies which knowledge base version to finalize. If not provided will use the most recent version of the knowledge base.

        status : typing.Optional[KnowledgeBaseVersionFinalizeStatus]
            Whether the knowledge base version processing was successful or not.

        error_message : typing.Optional[str]
            A user-facing error message that provides more details about a version failure.

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

        Returns
        -------
        HttpResponse[KnowledgeBaseVersion]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/version/finalize",
            method="POST",
            json={
                "versionId": convert_and_respect_annotation_metadata(
                    object_=version_id, annotation=EntityIdWithoutAgent, direction="write"
                ),
                "status": status,
                "errorMessage": error_message,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseVersion,
                    parse_obj_as(
                        type_=KnowledgeBaseVersion,  # 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 list_knowledge_base_versions(
        self,
        knowledge_base_reference_id: str,
        *,
        app_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeBaseVersionsListResponse]:
        """
        List all active versions for a knowledge base. Returns the most recent versions first.

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to list versions for. All other entity ID fields are inferred from the request.

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

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

        Returns
        -------
        HttpResponse[KnowledgeBaseVersionsListResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/versions",
            method="GET",
            params={
                "appId": app_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseVersionsListResponse,
                    parse_obj_as(
                        type_=KnowledgeBaseVersionsListResponse,  # 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 search_knowledge_documents(
        self,
        *,
        sort: typing.Optional[KnowledgeDocumentField] = OMIT,
        filter: typing.Optional[KnowledgeDocumentFilter] = OMIT,
        page: typing.Optional[int] = OMIT,
        size: typing.Optional[int] = OMIT,
        sort_desc: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeDocumentsResponse]:
        """
        Search knowledge documents

        Parameters
        ----------
        sort : typing.Optional[KnowledgeDocumentField]

        filter : typing.Optional[KnowledgeDocumentFilter]

        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[KnowledgeDocumentsResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/knowledge/documents/search",
            method="POST",
            json={
                "sort": sort,
                "filter": convert_and_respect_annotation_metadata(
                    object_=filter, annotation=KnowledgeDocumentFilter, 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(
                    KnowledgeDocumentsResponse,
                    parse_obj_as(
                        type_=KnowledgeDocumentsResponse,  # 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_knowledge_document(
        self,
        knowledge_base_reference_id: str,
        *,
        knowledge_document_id: EntityIdBase,
        content_type: KnowledgeDocumentContentType,
        content: str,
        title: str,
        version_id: typing.Optional[EntityIdWithoutAgent] = OMIT,
        metadata: typing.Optional[typing.Dict[str, str]] = OMIT,
        url: typing.Optional[str] = OMIT,
        language: typing.Optional[str] = OMIT,
        created_at: typing.Optional[dt.datetime] = OMIT,
        updated_at: typing.Optional[dt.datetime] = OMIT,
        author: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeDocumentResponse]:
        """
        Create or update a knowledge document. Requires an existing knowledge base with an in progress version.
        Will throw an exception if the latest version is not in progress.

        <Tip>
        This API maintains document version history. If for the same reference ID none of the `title`, `text`, `sourceUrl`, `metadata` fields
        have changed, a new document version will not be created. The existing version will be reused.
        </Tip>

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to create a document for. All other entity ID fields are inferred from the request.

        knowledge_document_id : EntityIdBase
            ID that uniquely identifies this knowledge document within its knowledge base

        content_type : KnowledgeDocumentContentType

        content : str
            The content of the document. Not shown directly to users. May be provided in HTML or markdown. HTML will be converted to markdown automatically. Images are not currently supported and will be ignored.

        title : str
            The title of the document. Will be shown as part of answers.

        version_id : typing.Optional[EntityIdWithoutAgent]
            ID that uniquely identifies which knowledge base version to create the document in. If not provided will use the most recent version of the knowledge base.

        metadata : typing.Optional[typing.Dict[str, str]]
            Metadata for the knowledge document.

        url : typing.Optional[str]
            The URL of the document. Should be visible to end users. Will be shown as part of answers. Not used for crawling.

        language : typing.Optional[str]
            The document language. Must be a valid ISO 639-1 language code.

        created_at : typing.Optional[dt.datetime]
            The time at which this document was created.

        updated_at : typing.Optional[dt.datetime]
            The time at which this document was last modified.

        author : typing.Optional[str]
            The name of the author who created this document.

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

        Returns
        -------
        HttpResponse[KnowledgeDocumentResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/document",
            method="POST",
            json={
                "knowledgeDocumentId": convert_and_respect_annotation_metadata(
                    object_=knowledge_document_id, annotation=EntityIdBase, direction="write"
                ),
                "versionId": convert_and_respect_annotation_metadata(
                    object_=version_id, annotation=EntityIdWithoutAgent, direction="write"
                ),
                "contentType": content_type,
                "content": content,
                "metadata": metadata,
                "title": title,
                "url": url,
                "language": language,
                "createdAt": created_at,
                "updatedAt": updated_at,
                "author": author,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeDocumentResponse,
                    parse_obj_as(
                        type_=KnowledgeDocumentResponse,  # 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_knowledge_document(
        self,
        knowledge_base_reference_id: str,
        knowledge_document_reference_id: str,
        *,
        version_id: EntityIdWithoutAgent,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[None]:
        """
        Delete knowledge document from a specific version.
        Requires an existing knowledge base with an in progress version of type PARTIAL. Will throw an exception if the version is not in progress.

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base that contains the document to delete. All other entity ID fields are inferred from the request

        knowledge_document_reference_id : str
            The reference ID of the knowledge document to delete. All other entity ID fields are inferred from the request.

        version_id : EntityIdWithoutAgent
            ID that uniquely identifies which knowledge base version to delete the document from.

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/{jsonable_encoder(knowledge_document_reference_id)}/document",
            method="DELETE",
            json={
                "versionId": convert_and_respect_annotation_metadata(
                    object_=version_id, annotation=EntityIdWithoutAgent, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        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)

    def get_knowledge_document(
        self,
        knowledge_base_version_reference_id: str,
        knowledge_document_reference_id: str,
        *,
        knowledge_base_version_app_id: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[KnowledgeDocumentResponse]:
        """
        Get a knowledge document by its supplied version and document IDs. Response includes document content in markdown format.

        Parameters
        ----------
        knowledge_base_version_reference_id : str
            The reference ID of the knowledge base version that contains the document. All other entity ID fields are inferred from the request.

        knowledge_document_reference_id : str
            The reference ID of the knowledge document to get. All other entity ID fields are inferred from the request.

        knowledge_base_version_app_id : str
            The App ID of the knowledge base version.

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

        Returns
        -------
        HttpResponse[KnowledgeDocumentResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/knowledge/versions/{jsonable_encoder(knowledge_base_version_reference_id)}/documents/{jsonable_encoder(knowledge_document_reference_id)}",
            method="GET",
            params={
                "knowledgeBaseVersionAppId": knowledge_base_version_app_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeDocumentResponse,
                    parse_obj_as(
                        type_=KnowledgeDocumentResponse,  # 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)


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

    async def search_knowledge_bases(
        self,
        *,
        sort: typing.Optional[KnowledgeBaseField] = OMIT,
        filter: typing.Optional[KnowledgeBaseFilter] = OMIT,
        page: typing.Optional[int] = OMIT,
        size: typing.Optional[int] = OMIT,
        sort_desc: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeBasesResponse]:
        """
        Search knowledge bases

        Parameters
        ----------
        sort : typing.Optional[KnowledgeBaseField]

        filter : typing.Optional[KnowledgeBaseFilter]

        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[KnowledgeBasesResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/knowledge/search",
            method="POST",
            json={
                "sort": sort,
                "filter": convert_and_respect_annotation_metadata(
                    object_=filter, annotation=KnowledgeBaseFilter, 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(
                    KnowledgeBasesResponse,
                    parse_obj_as(
                        type_=KnowledgeBasesResponse,  # 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_knowledge_base(
        self,
        *,
        knowledge_base_id: EntityIdBase,
        name: str,
        metadata: typing.Optional[typing.Dict[str, str]] = OMIT,
        precondition: typing.Optional[Precondition] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeBaseResponse]:
        """
        Update a knowledge base or create it if it doesn't exist.

        Parameters
        ----------
        knowledge_base_id : EntityIdBase
            ID that uniquely identifies this knowledge base

        name : str
            The name of the knowledge base

        metadata : typing.Optional[typing.Dict[str, str]]
            Metadata for the knowledge base.

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

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

        Returns
        -------
        AsyncHttpResponse[KnowledgeBaseResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/knowledge",
            method="PUT",
            json={
                "knowledgeBaseId": convert_and_respect_annotation_metadata(
                    object_=knowledge_base_id, annotation=EntityIdBase, direction="write"
                ),
                "metadata": metadata,
                "name": name,
                "precondition": convert_and_respect_annotation_metadata(
                    object_=precondition, annotation=Precondition, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseResponse,
                    parse_obj_as(
                        type_=KnowledgeBaseResponse,  # 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_knowledge_base(
        self,
        knowledge_base_reference_id: str,
        *,
        app_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeBaseResponse]:
        """
        Get an existing knowledge base by its supplied ID

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

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

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

        Returns
        -------
        AsyncHttpResponse[KnowledgeBaseResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}",
            method="GET",
            params={
                "appId": app_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseResponse,
                    parse_obj_as(
                        type_=KnowledgeBaseResponse,  # 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_knowledge_base(
        self,
        knowledge_base_reference_id: str,
        *,
        app_id: typing.Optional[str] = OMIT,
        name: typing.Optional[str] = OMIT,
        tags: typing.Optional[typing.Set[str]] = OMIT,
        llm_inclusion_status: typing.Optional[LlmInclusionStatus] = OMIT,
        precondition: typing.Optional[Precondition] = OMIT,
        segment_id: typing.Optional[EntityId] = OMIT,
        refresh_frequency: typing.Optional[KnowledgeBaseRefreshFrequency] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeBaseResponse]:
        """
        Update mutable knowledge base fields

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

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to patch.

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

        name : typing.Optional[str]
            The name of the knowledge base.

        tags : typing.Optional[typing.Set[str]]
            The tags of the knowledge base.

        llm_inclusion_status : typing.Optional[LlmInclusionStatus]
            Determines whether documents in the knowledge base are sent to the LLM as part of a conversation. Note that at this time knowledge bases can not be set to `ALWAYS`.

        precondition : typing.Optional[Precondition]
            The preconditions that must be met for a knowledge base to be relevant to a conversation. Can be used to restrict knowledge bases to certain types of users. A null value will remove the precondition from the knowledge base, it will be available on all conversations.

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

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

        refresh_frequency : typing.Optional[KnowledgeBaseRefreshFrequency]
            How often the knowledge base should be refreshed.

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

        Returns
        -------
        AsyncHttpResponse[KnowledgeBaseResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}",
            method="PATCH",
            json={
                "appId": app_id,
                "name": name,
                "tags": tags,
                "llmInclusionStatus": llm_inclusion_status,
                "precondition": convert_and_respect_annotation_metadata(
                    object_=precondition, annotation=typing.Optional[Precondition], direction="write"
                ),
                "segmentId": convert_and_respect_annotation_metadata(
                    object_=segment_id, annotation=typing.Optional[EntityId], direction="write"
                ),
                "refreshFrequency": refresh_frequency,
            },
            headers={
                "content-type": "application/merge-patch+json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseResponse,
                    parse_obj_as(
                        type_=KnowledgeBaseResponse,  # 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_knowledge_base_version(
        self,
        knowledge_base_reference_id: str,
        *,
        type: KnowledgeBaseVersionType,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeBaseVersion]:
        """
        Create a new knowledge base version.

        If an existing version is in progress, then that version will be finalized in an error state.

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to create a version for. All other entity ID fields are inferred from the request.

        type : KnowledgeBaseVersionType
            Indicates whether the completed version constitutes a full or partial refresh of the knowledge base. Deleting and updating documents is only supported for partial refreshes.

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

        Returns
        -------
        AsyncHttpResponse[KnowledgeBaseVersion]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/version",
            method="POST",
            json={
                "type": type,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseVersion,
                    parse_obj_as(
                        type_=KnowledgeBaseVersion,  # 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 finalize_knowledge_base_version(
        self,
        knowledge_base_reference_id: str,
        *,
        version_id: typing.Optional[EntityIdWithoutAgent] = OMIT,
        status: typing.Optional[KnowledgeBaseVersionFinalizeStatus] = OMIT,
        error_message: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeBaseVersion]:
        """
        Finalize the latest knowledge base version. Required to indicate the version is complete. Will throw an exception if the latest version is not in progress.

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to finalize a version for. All other entity ID fields are inferred from the request.

        version_id : typing.Optional[EntityIdWithoutAgent]
            ID that uniquely identifies which knowledge base version to finalize. If not provided will use the most recent version of the knowledge base.

        status : typing.Optional[KnowledgeBaseVersionFinalizeStatus]
            Whether the knowledge base version processing was successful or not.

        error_message : typing.Optional[str]
            A user-facing error message that provides more details about a version failure.

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

        Returns
        -------
        AsyncHttpResponse[KnowledgeBaseVersion]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/version/finalize",
            method="POST",
            json={
                "versionId": convert_and_respect_annotation_metadata(
                    object_=version_id, annotation=EntityIdWithoutAgent, direction="write"
                ),
                "status": status,
                "errorMessage": error_message,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseVersion,
                    parse_obj_as(
                        type_=KnowledgeBaseVersion,  # 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 list_knowledge_base_versions(
        self,
        knowledge_base_reference_id: str,
        *,
        app_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeBaseVersionsListResponse]:
        """
        List all active versions for a knowledge base. Returns the most recent versions first.

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to list versions for. All other entity ID fields are inferred from the request.

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

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

        Returns
        -------
        AsyncHttpResponse[KnowledgeBaseVersionsListResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/versions",
            method="GET",
            params={
                "appId": app_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeBaseVersionsListResponse,
                    parse_obj_as(
                        type_=KnowledgeBaseVersionsListResponse,  # 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 search_knowledge_documents(
        self,
        *,
        sort: typing.Optional[KnowledgeDocumentField] = OMIT,
        filter: typing.Optional[KnowledgeDocumentFilter] = OMIT,
        page: typing.Optional[int] = OMIT,
        size: typing.Optional[int] = OMIT,
        sort_desc: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeDocumentsResponse]:
        """
        Search knowledge documents

        Parameters
        ----------
        sort : typing.Optional[KnowledgeDocumentField]

        filter : typing.Optional[KnowledgeDocumentFilter]

        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[KnowledgeDocumentsResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/knowledge/documents/search",
            method="POST",
            json={
                "sort": sort,
                "filter": convert_and_respect_annotation_metadata(
                    object_=filter, annotation=KnowledgeDocumentFilter, 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(
                    KnowledgeDocumentsResponse,
                    parse_obj_as(
                        type_=KnowledgeDocumentsResponse,  # 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_knowledge_document(
        self,
        knowledge_base_reference_id: str,
        *,
        knowledge_document_id: EntityIdBase,
        content_type: KnowledgeDocumentContentType,
        content: str,
        title: str,
        version_id: typing.Optional[EntityIdWithoutAgent] = OMIT,
        metadata: typing.Optional[typing.Dict[str, str]] = OMIT,
        url: typing.Optional[str] = OMIT,
        language: typing.Optional[str] = OMIT,
        created_at: typing.Optional[dt.datetime] = OMIT,
        updated_at: typing.Optional[dt.datetime] = OMIT,
        author: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeDocumentResponse]:
        """
        Create or update a knowledge document. Requires an existing knowledge base with an in progress version.
        Will throw an exception if the latest version is not in progress.

        <Tip>
        This API maintains document version history. If for the same reference ID none of the `title`, `text`, `sourceUrl`, `metadata` fields
        have changed, a new document version will not be created. The existing version will be reused.
        </Tip>

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base to create a document for. All other entity ID fields are inferred from the request.

        knowledge_document_id : EntityIdBase
            ID that uniquely identifies this knowledge document within its knowledge base

        content_type : KnowledgeDocumentContentType

        content : str
            The content of the document. Not shown directly to users. May be provided in HTML or markdown. HTML will be converted to markdown automatically. Images are not currently supported and will be ignored.

        title : str
            The title of the document. Will be shown as part of answers.

        version_id : typing.Optional[EntityIdWithoutAgent]
            ID that uniquely identifies which knowledge base version to create the document in. If not provided will use the most recent version of the knowledge base.

        metadata : typing.Optional[typing.Dict[str, str]]
            Metadata for the knowledge document.

        url : typing.Optional[str]
            The URL of the document. Should be visible to end users. Will be shown as part of answers. Not used for crawling.

        language : typing.Optional[str]
            The document language. Must be a valid ISO 639-1 language code.

        created_at : typing.Optional[dt.datetime]
            The time at which this document was created.

        updated_at : typing.Optional[dt.datetime]
            The time at which this document was last modified.

        author : typing.Optional[str]
            The name of the author who created this document.

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

        Returns
        -------
        AsyncHttpResponse[KnowledgeDocumentResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/document",
            method="POST",
            json={
                "knowledgeDocumentId": convert_and_respect_annotation_metadata(
                    object_=knowledge_document_id, annotation=EntityIdBase, direction="write"
                ),
                "versionId": convert_and_respect_annotation_metadata(
                    object_=version_id, annotation=EntityIdWithoutAgent, direction="write"
                ),
                "contentType": content_type,
                "content": content,
                "metadata": metadata,
                "title": title,
                "url": url,
                "language": language,
                "createdAt": created_at,
                "updatedAt": updated_at,
                "author": author,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeDocumentResponse,
                    parse_obj_as(
                        type_=KnowledgeDocumentResponse,  # 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_knowledge_document(
        self,
        knowledge_base_reference_id: str,
        knowledge_document_reference_id: str,
        *,
        version_id: EntityIdWithoutAgent,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[None]:
        """
        Delete knowledge document from a specific version.
        Requires an existing knowledge base with an in progress version of type PARTIAL. Will throw an exception if the version is not in progress.

        Parameters
        ----------
        knowledge_base_reference_id : str
            The reference ID of the knowledge base that contains the document to delete. All other entity ID fields are inferred from the request

        knowledge_document_reference_id : str
            The reference ID of the knowledge document to delete. All other entity ID fields are inferred from the request.

        version_id : EntityIdWithoutAgent
            ID that uniquely identifies which knowledge base version to delete the document from.

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/knowledge/{jsonable_encoder(knowledge_base_reference_id)}/{jsonable_encoder(knowledge_document_reference_id)}/document",
            method="DELETE",
            json={
                "versionId": convert_and_respect_annotation_metadata(
                    object_=version_id, annotation=EntityIdWithoutAgent, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        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)

    async def get_knowledge_document(
        self,
        knowledge_base_version_reference_id: str,
        knowledge_document_reference_id: str,
        *,
        knowledge_base_version_app_id: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[KnowledgeDocumentResponse]:
        """
        Get a knowledge document by its supplied version and document IDs. Response includes document content in markdown format.

        Parameters
        ----------
        knowledge_base_version_reference_id : str
            The reference ID of the knowledge base version that contains the document. All other entity ID fields are inferred from the request.

        knowledge_document_reference_id : str
            The reference ID of the knowledge document to get. All other entity ID fields are inferred from the request.

        knowledge_base_version_app_id : str
            The App ID of the knowledge base version.

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

        Returns
        -------
        AsyncHttpResponse[KnowledgeDocumentResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/knowledge/versions/{jsonable_encoder(knowledge_base_version_reference_id)}/documents/{jsonable_encoder(knowledge_document_reference_id)}",
            method="GET",
            params={
                "knowledgeBaseVersionAppId": knowledge_base_version_app_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    KnowledgeDocumentResponse,
                    parse_obj_as(
                        type_=KnowledgeDocumentResponse,  # 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)
