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

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.collection import Collection
from ..types.http_validation_error import HttpValidationError
from ..types.legacy_search_response import LegacySearchResponse
from ..types.response_type import ResponseType
from ..types.source_connection_job import SourceConnectionJob
from .types.search_collections_readable_id_search_post_request_body import (
    SearchCollectionsReadableIdSearchPostRequestBody,
)
from .types.search_collections_readable_id_search_post_response import SearchCollectionsReadableIdSearchPostResponse

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


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

    def list(
        self,
        *,
        skip: typing.Optional[int] = None,
        limit: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.List[Collection]]:
        """
        List all collections that belong to your organization with optional search filtering.

        Collections are always sorted by creation date (newest first).

        Parameters
        ----------
        skip : typing.Optional[int]
            Number of collections to skip for pagination

        limit : typing.Optional[int]
            Maximum number of collections to return (1-1000)

        search : typing.Optional[str]
            Search term to filter by name or readable_id

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

        Returns
        -------
        HttpResponse[typing.List[Collection]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "collections",
            method="GET",
            params={
                "skip": skip,
                "limit": limit,
                "search": search,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[Collection],
                    parse_obj_as(
                        type_=typing.List[Collection],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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(
        self,
        *,
        name: str,
        description: typing.Optional[str] = OMIT,
        color: typing.Optional[str] = OMIT,
        icon: typing.Optional[str] = OMIT,
        readable_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[Collection]:
        """
        Create a new collection.

        Only organization owners and admins can create collections.
        The creator is automatically assigned as collection_owner.

        The newly created collection is initially empty and does not contain any data
        until you explicitly add source connections to it.

        Parameters
        ----------
        name : str
            Human-readable display name for the collection. This appears in the UI and should clearly describe the data contained within (e.g., 'Finance Data').

        description : typing.Optional[str]
            Optional description of the collection to provide additional context.

        color : typing.Optional[str]
            Optional color for the collection (hex code, CSS color name, or RGB).

        icon : typing.Optional[str]
            Optional icon name or identifier for the collection.

        readable_id : typing.Optional[str]
            URL-safe unique identifier used in API endpoints. Must contain only lowercase letters, numbers, and hyphens. If not provided, it will be automatically generated from the collection name with a random suffix for uniqueness (e.g., 'finance-data-ab123').

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

        Returns
        -------
        HttpResponse[Collection]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "collections",
            method="POST",
            json={
                "name": name,
                "description": description,
                "color": color,
                "icon": icon,
                "readable_id": readable_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    Collection,
                    parse_obj_as(
                        type_=Collection,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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, readable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[Collection]:
        """
        Retrieve a specific collection by its readable ID.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection (e.g., 'finance-data-ab123')

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

        Returns
        -------
        HttpResponse[Collection]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    Collection,
                    parse_obj_as(
                        type_=Collection,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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, readable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[Collection]:
        """
        Delete a collection and all associated data.

        Only organization owners/admins and collection owners can delete collections.

        Permanently removes a collection from your organization including all synced data
        from the destination systems. All source connections within this collection
        will also be deleted as part of the cleanup process. This action cannot be undone.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection to delete

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

        Returns
        -------
        HttpResponse[Collection]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    Collection,
                    parse_obj_as(
                        type_=Collection,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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 refresh_all_source_connections(
        self, readable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[SourceConnectionJob]]:
        """
        Trigger data synchronization for all source connections in the collection.

        Only organization owners/admins, collection owners and collection editors can refresh collections.

        The sync jobs run asynchronously in the background, so this endpoint
        returns immediately with job details that you can use to track progress. You can
        monitor the status of individual data synchronization using the source connection
        endpoints.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection to refresh

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

        Returns
        -------
        HttpResponse[typing.List[SourceConnectionJob]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}/refresh_all",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[SourceConnectionJob],
                    parse_obj_as(
                        type_=typing.List[SourceConnectionJob],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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_get_legacy(
        self,
        readable_id: str,
        *,
        query: str,
        response_type: typing.Optional[ResponseType] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        recency_bias: typing.Optional[float] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[LegacySearchResponse]:
        """
        Legacy GET search endpoint for backwards compatibility.

        DEPRECATED: This endpoint uses the old schema. Please migrate to POST with the new
        SearchRequest format for access to all features.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection to search

        query : str
            The search query text to find relevant documents and data

        response_type : typing.Optional[ResponseType]
            Format of the response: 'raw' returns search results, 'completion' returns AI-generated answers

        limit : typing.Optional[int]
            Maximum number of results to return

        offset : typing.Optional[int]
            Number of results to skip for pagination

        recency_bias : typing.Optional[float]
            How much to weigh recency vs similarity (0..1)

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

        Returns
        -------
        HttpResponse[LegacySearchResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}/search",
            method="GET",
            params={
                "query": query,
                "response_type": response_type,
                "limit": limit,
                "offset": offset,
                "recency_bias": recency_bias,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    LegacySearchResponse,
                    parse_obj_as(
                        type_=LegacySearchResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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(
        self,
        readable_id: str,
        *,
        request: SearchCollectionsReadableIdSearchPostRequestBody,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[SearchCollectionsReadableIdSearchPostResponse]:
        """
        Search your collection.

        Accepts both new SearchRequest and legacy LegacySearchRequest formats
        for backwards compatibility.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection

        request : SearchCollectionsReadableIdSearchPostRequestBody

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

        Returns
        -------
        HttpResponse[SearchCollectionsReadableIdSearchPostResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}/search",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request, annotation=SearchCollectionsReadableIdSearchPostRequestBody, direction="write"
            ),
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchCollectionsReadableIdSearchPostResponse,
                    parse_obj_as(
                        type_=SearchCollectionsReadableIdSearchPostResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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 AsyncRawCollectionsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        *,
        skip: typing.Optional[int] = None,
        limit: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.List[Collection]]:
        """
        List all collections that belong to your organization with optional search filtering.

        Collections are always sorted by creation date (newest first).

        Parameters
        ----------
        skip : typing.Optional[int]
            Number of collections to skip for pagination

        limit : typing.Optional[int]
            Maximum number of collections to return (1-1000)

        search : typing.Optional[str]
            Search term to filter by name or readable_id

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

        Returns
        -------
        AsyncHttpResponse[typing.List[Collection]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "collections",
            method="GET",
            params={
                "skip": skip,
                "limit": limit,
                "search": search,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[Collection],
                    parse_obj_as(
                        type_=typing.List[Collection],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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(
        self,
        *,
        name: str,
        description: typing.Optional[str] = OMIT,
        color: typing.Optional[str] = OMIT,
        icon: typing.Optional[str] = OMIT,
        readable_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[Collection]:
        """
        Create a new collection.

        Only organization owners and admins can create collections.
        The creator is automatically assigned as collection_owner.

        The newly created collection is initially empty and does not contain any data
        until you explicitly add source connections to it.

        Parameters
        ----------
        name : str
            Human-readable display name for the collection. This appears in the UI and should clearly describe the data contained within (e.g., 'Finance Data').

        description : typing.Optional[str]
            Optional description of the collection to provide additional context.

        color : typing.Optional[str]
            Optional color for the collection (hex code, CSS color name, or RGB).

        icon : typing.Optional[str]
            Optional icon name or identifier for the collection.

        readable_id : typing.Optional[str]
            URL-safe unique identifier used in API endpoints. Must contain only lowercase letters, numbers, and hyphens. If not provided, it will be automatically generated from the collection name with a random suffix for uniqueness (e.g., 'finance-data-ab123').

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

        Returns
        -------
        AsyncHttpResponse[Collection]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "collections",
            method="POST",
            json={
                "name": name,
                "description": description,
                "color": color,
                "icon": icon,
                "readable_id": readable_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    Collection,
                    parse_obj_as(
                        type_=Collection,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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, readable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[Collection]:
        """
        Retrieve a specific collection by its readable ID.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection (e.g., 'finance-data-ab123')

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

        Returns
        -------
        AsyncHttpResponse[Collection]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    Collection,
                    parse_obj_as(
                        type_=Collection,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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, readable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[Collection]:
        """
        Delete a collection and all associated data.

        Only organization owners/admins and collection owners can delete collections.

        Permanently removes a collection from your organization including all synced data
        from the destination systems. All source connections within this collection
        will also be deleted as part of the cleanup process. This action cannot be undone.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection to delete

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

        Returns
        -------
        AsyncHttpResponse[Collection]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    Collection,
                    parse_obj_as(
                        type_=Collection,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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 refresh_all_source_connections(
        self, readable_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[SourceConnectionJob]]:
        """
        Trigger data synchronization for all source connections in the collection.

        Only organization owners/admins, collection owners and collection editors can refresh collections.

        The sync jobs run asynchronously in the background, so this endpoint
        returns immediately with job details that you can use to track progress. You can
        monitor the status of individual data synchronization using the source connection
        endpoints.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection to refresh

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

        Returns
        -------
        AsyncHttpResponse[typing.List[SourceConnectionJob]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}/refresh_all",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[SourceConnectionJob],
                    parse_obj_as(
                        type_=typing.List[SourceConnectionJob],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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_get_legacy(
        self,
        readable_id: str,
        *,
        query: str,
        response_type: typing.Optional[ResponseType] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        recency_bias: typing.Optional[float] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[LegacySearchResponse]:
        """
        Legacy GET search endpoint for backwards compatibility.

        DEPRECATED: This endpoint uses the old schema. Please migrate to POST with the new
        SearchRequest format for access to all features.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection to search

        query : str
            The search query text to find relevant documents and data

        response_type : typing.Optional[ResponseType]
            Format of the response: 'raw' returns search results, 'completion' returns AI-generated answers

        limit : typing.Optional[int]
            Maximum number of results to return

        offset : typing.Optional[int]
            Number of results to skip for pagination

        recency_bias : typing.Optional[float]
            How much to weigh recency vs similarity (0..1)

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

        Returns
        -------
        AsyncHttpResponse[LegacySearchResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}/search",
            method="GET",
            params={
                "query": query,
                "response_type": response_type,
                "limit": limit,
                "offset": offset,
                "recency_bias": recency_bias,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    LegacySearchResponse,
                    parse_obj_as(
                        type_=LegacySearchResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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(
        self,
        readable_id: str,
        *,
        request: SearchCollectionsReadableIdSearchPostRequestBody,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[SearchCollectionsReadableIdSearchPostResponse]:
        """
        Search your collection.

        Accepts both new SearchRequest and legacy LegacySearchRequest formats
        for backwards compatibility.

        Parameters
        ----------
        readable_id : str
            The unique readable identifier of the collection

        request : SearchCollectionsReadableIdSearchPostRequestBody

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

        Returns
        -------
        AsyncHttpResponse[SearchCollectionsReadableIdSearchPostResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"collections/{jsonable_encoder(readable_id)}/search",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request, annotation=SearchCollectionsReadableIdSearchPostRequestBody, direction="write"
            ),
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchCollectionsReadableIdSearchPostResponse,
                    parse_obj_as(
                        type_=SearchCollectionsReadableIdSearchPostResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # 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)
