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

import datetime as dt
import typing
from json.decoder import JSONDecodeError

from ...core.api_error import ApiError
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.datetime_utils import serialize_datetime
from ...core.http_response import AsyncHttpResponse, HttpResponse
from ...core.jsonable_encoder import jsonable_encoder
from ...core.request_options import RequestOptions
from ...core.unchecked_base_model import construct_type
from ...errors.unprocessable_entity_error import UnprocessableEntityError
from ...types.archival_memory_search_response import ArchivalMemorySearchResponse
from ...types.http_validation_error import HttpValidationError
from ...types.passage import Passage
from .types.passages_search_request_tag_match_mode import PassagesSearchRequestTagMatchMode

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


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

    def list(
        self,
        agent_id: str,
        *,
        after: typing.Optional[str] = None,
        before: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        ascending: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.List[Passage]]:
        """
        Retrieve the memories in an agent's archival memory store (paginated query).

        Parameters
        ----------
        agent_id : str

        after : typing.Optional[str]
            Unique ID of the memory to start the query range at.

        before : typing.Optional[str]
            Unique ID of the memory to end the query range at.

        limit : typing.Optional[int]
            How many results to include in the response.

        search : typing.Optional[str]
            Search passages by text

        ascending : typing.Optional[bool]
            Whether to sort passages oldest to newest (True, default) or newest to oldest (False)

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

        Returns
        -------
        HttpResponse[typing.List[Passage]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory",
            method="GET",
            params={
                "after": after,
                "before": before,
                "limit": limit,
                "search": search,
                "ascending": ascending,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[Passage],
                    construct_type(
                        type_=typing.List[Passage],  # 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,
                        construct_type(
                            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,
        agent_id: str,
        *,
        text: str,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        created_at: typing.Optional[dt.datetime] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.List[Passage]]:
        """
        Insert a memory into an agent's archival memory store.

        Parameters
        ----------
        agent_id : str

        text : str
            Text to write to archival memory.

        tags : typing.Optional[typing.Sequence[str]]
            Optional list of tags to attach to the memory.

        created_at : typing.Optional[dt.datetime]
            Optional timestamp for the memory (defaults to current UTC time).

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

        Returns
        -------
        HttpResponse[typing.List[Passage]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory",
            method="POST",
            json={
                "text": text,
                "tags": tags,
                "created_at": created_at,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[Passage],
                    construct_type(
                        type_=typing.List[Passage],  # 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,
                        construct_type(
                            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,
        agent_id: str,
        *,
        query: str,
        tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_match_mode: typing.Optional[PassagesSearchRequestTagMatchMode] = None,
        top_k: typing.Optional[int] = None,
        start_datetime: typing.Optional[dt.datetime] = None,
        end_datetime: typing.Optional[dt.datetime] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ArchivalMemorySearchResponse]:
        """
        Search archival memory using semantic (embedding-based) search with optional temporal filtering.

        This endpoint allows manual triggering of archival memory searches, enabling users to query
        an agent's archival memory store directly via the API. The search uses the same functionality
        as the agent's archival_memory_search tool but is accessible for external API usage.

        Parameters
        ----------
        agent_id : str

        query : str
            String to search for using semantic similarity

        tags : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Optional list of tags to filter search results

        tag_match_mode : typing.Optional[PassagesSearchRequestTagMatchMode]
            How to match tags - 'any' to match passages with any of the tags, 'all' to match only passages with all tags

        top_k : typing.Optional[int]
            Maximum number of results to return. Uses system default if not specified

        start_datetime : typing.Optional[dt.datetime]
            Filter results to passages created after this datetime

        end_datetime : typing.Optional[dt.datetime]
            Filter results to passages created before this datetime

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

        Returns
        -------
        HttpResponse[ArchivalMemorySearchResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory/search",
            method="GET",
            params={
                "query": query,
                "tags": tags,
                "tag_match_mode": tag_match_mode,
                "top_k": top_k,
                "start_datetime": serialize_datetime(start_datetime) if start_datetime is not None else None,
                "end_datetime": serialize_datetime(end_datetime) if end_datetime is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ArchivalMemorySearchResponse,
                    construct_type(
                        type_=ArchivalMemorySearchResponse,  # 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,
                        construct_type(
                            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, agent_id: str, memory_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Optional[typing.Any]]:
        """
        Delete a memory from an agent's archival memory store.

        Parameters
        ----------
        agent_id : str

        memory_id : str

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

        Returns
        -------
        HttpResponse[typing.Optional[typing.Any]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory/{jsonable_encoder(memory_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Optional[typing.Any],
                    construct_type(
                        type_=typing.Optional[typing.Any],  # 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,
                        construct_type(
                            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 modify(
        self, agent_id: str, memory_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Parameters
        ----------
        agent_id : str

        memory_id : str

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory/{jsonable_encoder(memory_id)}",
            method="PATCH",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            _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 AsyncRawPassagesClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        agent_id: str,
        *,
        after: typing.Optional[str] = None,
        before: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        search: typing.Optional[str] = None,
        ascending: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.List[Passage]]:
        """
        Retrieve the memories in an agent's archival memory store (paginated query).

        Parameters
        ----------
        agent_id : str

        after : typing.Optional[str]
            Unique ID of the memory to start the query range at.

        before : typing.Optional[str]
            Unique ID of the memory to end the query range at.

        limit : typing.Optional[int]
            How many results to include in the response.

        search : typing.Optional[str]
            Search passages by text

        ascending : typing.Optional[bool]
            Whether to sort passages oldest to newest (True, default) or newest to oldest (False)

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

        Returns
        -------
        AsyncHttpResponse[typing.List[Passage]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory",
            method="GET",
            params={
                "after": after,
                "before": before,
                "limit": limit,
                "search": search,
                "ascending": ascending,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[Passage],
                    construct_type(
                        type_=typing.List[Passage],  # 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,
                        construct_type(
                            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,
        agent_id: str,
        *,
        text: str,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        created_at: typing.Optional[dt.datetime] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.List[Passage]]:
        """
        Insert a memory into an agent's archival memory store.

        Parameters
        ----------
        agent_id : str

        text : str
            Text to write to archival memory.

        tags : typing.Optional[typing.Sequence[str]]
            Optional list of tags to attach to the memory.

        created_at : typing.Optional[dt.datetime]
            Optional timestamp for the memory (defaults to current UTC time).

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

        Returns
        -------
        AsyncHttpResponse[typing.List[Passage]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory",
            method="POST",
            json={
                "text": text,
                "tags": tags,
                "created_at": created_at,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[Passage],
                    construct_type(
                        type_=typing.List[Passage],  # 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,
                        construct_type(
                            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,
        agent_id: str,
        *,
        query: str,
        tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        tag_match_mode: typing.Optional[PassagesSearchRequestTagMatchMode] = None,
        top_k: typing.Optional[int] = None,
        start_datetime: typing.Optional[dt.datetime] = None,
        end_datetime: typing.Optional[dt.datetime] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ArchivalMemorySearchResponse]:
        """
        Search archival memory using semantic (embedding-based) search with optional temporal filtering.

        This endpoint allows manual triggering of archival memory searches, enabling users to query
        an agent's archival memory store directly via the API. The search uses the same functionality
        as the agent's archival_memory_search tool but is accessible for external API usage.

        Parameters
        ----------
        agent_id : str

        query : str
            String to search for using semantic similarity

        tags : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Optional list of tags to filter search results

        tag_match_mode : typing.Optional[PassagesSearchRequestTagMatchMode]
            How to match tags - 'any' to match passages with any of the tags, 'all' to match only passages with all tags

        top_k : typing.Optional[int]
            Maximum number of results to return. Uses system default if not specified

        start_datetime : typing.Optional[dt.datetime]
            Filter results to passages created after this datetime

        end_datetime : typing.Optional[dt.datetime]
            Filter results to passages created before this datetime

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

        Returns
        -------
        AsyncHttpResponse[ArchivalMemorySearchResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory/search",
            method="GET",
            params={
                "query": query,
                "tags": tags,
                "tag_match_mode": tag_match_mode,
                "top_k": top_k,
                "start_datetime": serialize_datetime(start_datetime) if start_datetime is not None else None,
                "end_datetime": serialize_datetime(end_datetime) if end_datetime is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ArchivalMemorySearchResponse,
                    construct_type(
                        type_=ArchivalMemorySearchResponse,  # 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,
                        construct_type(
                            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, agent_id: str, memory_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Optional[typing.Any]]:
        """
        Delete a memory from an agent's archival memory store.

        Parameters
        ----------
        agent_id : str

        memory_id : str

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

        Returns
        -------
        AsyncHttpResponse[typing.Optional[typing.Any]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory/{jsonable_encoder(memory_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Optional[typing.Any],
                    construct_type(
                        type_=typing.Optional[typing.Any],  # 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,
                        construct_type(
                            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 modify(
        self, agent_id: str, memory_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Parameters
        ----------
        agent_id : str

        memory_id : str

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/archival-memory/{jsonable_encoder(memory_id)}",
            method="PATCH",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            _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)
