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

import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.request_options import RequestOptions
from ..types.add_thread_messages_response import AddThreadMessagesResponse
from ..types.message import Message
from ..types.message_list_response import MessageListResponse
from ..types.role_type import RoleType
from ..types.success_response import SuccessResponse
from ..types.thread import Thread
from ..types.thread_context_response import ThreadContextResponse
from ..types.thread_list_response import ThreadListResponse
from .raw_client import AsyncRawThreadClient, RawThreadClient

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


class ThreadClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawThreadClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawThreadClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawThreadClient
        """
        return self._raw_client

    def list_all(
        self,
        *,
        page_number: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        order_by: typing.Optional[str] = None,
        asc: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ThreadListResponse:
        """
        Returns all threads.

        Parameters
        ----------
        page_number : typing.Optional[int]
            Page number for pagination, starting from 1

        page_size : typing.Optional[int]
            Number of threads to retrieve per page.

        order_by : typing.Optional[str]
            Field to order the results by: created_at, updated_at, user_id, thread_id.

        asc : typing.Optional[bool]
            Order direction: true for ascending, false for descending.

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

        Returns
        -------
        ThreadListResponse
            List of threads

        Examples
        --------
        from zep_cloud import Zep

        client = Zep(
            api_key="YOUR_API_KEY",
        )
        client.thread.list_all()
        """
        _response = self._raw_client.list_all(
            page_number=page_number, page_size=page_size, order_by=order_by, asc=asc, request_options=request_options
        )
        return _response.data

    def create(
        self, *, thread_id: str, user_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> Thread:
        """
        Start a new thread.

        Parameters
        ----------
        thread_id : str
            The unique identifier of the thread.

        user_id : str
            The unique identifier of the user associated with the thread

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

        Returns
        -------
        Thread
            The thread object.

        Examples
        --------
        from zep_cloud import Zep

        client = Zep(
            api_key="YOUR_API_KEY",
        )
        client.thread.create(
            thread_id="thread_id",
            user_id="user_id",
        )
        """
        _response = self._raw_client.create(thread_id=thread_id, user_id=user_id, request_options=request_options)
        return _response.data

    def delete(self, thread_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> SuccessResponse:
        """
        Deletes a thread.

        Parameters
        ----------
        thread_id : str
            The ID of the thread for which memory should be deleted.

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

        Returns
        -------
        SuccessResponse
            OK

        Examples
        --------
        from zep_cloud import Zep

        client = Zep(
            api_key="YOUR_API_KEY",
        )
        client.thread.delete(
            thread_id="threadId",
        )
        """
        _response = self._raw_client.delete(thread_id, request_options=request_options)
        return _response.data

    def get_user_context(
        self,
        thread_id: str,
        *,
        lastn: typing.Optional[int] = None,
        min_rating: typing.Optional[float] = None,
        fast: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ThreadContextResponse:
        """
        Returns most relevant context for a given thread.

        Parameters
        ----------
        thread_id : str
            The ID of the thread for which to retrieve context.

        lastn : typing.Optional[int]
            The number of most recent memory entries to retrieve.

        min_rating : typing.Optional[float]
            The minimum rating by which to filter relevant facts.

        fast : typing.Optional[bool]
            If true, bypasses context summarization and returns raw search results.

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

        Returns
        -------
        ThreadContextResponse
            OK

        Examples
        --------
        from zep_cloud import Zep

        client = Zep(
            api_key="YOUR_API_KEY",
        )
        client.thread.get_user_context(
            thread_id="threadId",
        )
        """
        _response = self._raw_client.get_user_context(
            thread_id, lastn=lastn, min_rating=min_rating, fast=fast, request_options=request_options
        )
        return _response.data

    def get(
        self,
        thread_id: str,
        *,
        limit: typing.Optional[int] = None,
        cursor: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> MessageListResponse:
        """
        Returns messages for a thread.

        Parameters
        ----------
        thread_id : str
            Thread ID

        limit : typing.Optional[int]
            Limit the number of results returned

        cursor : typing.Optional[int]
            Cursor for pagination

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

        Returns
        -------
        MessageListResponse
            OK

        Examples
        --------
        from zep_cloud import Zep

        client = Zep(
            api_key="YOUR_API_KEY",
        )
        client.thread.get(
            thread_id="threadId",
        )
        """
        _response = self._raw_client.get(thread_id, limit=limit, cursor=cursor, request_options=request_options)
        return _response.data

    def add_messages(
        self,
        thread_id: str,
        *,
        messages: typing.Sequence[Message],
        ignore_roles: typing.Optional[typing.Sequence[RoleType]] = OMIT,
        return_context: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddThreadMessagesResponse:
        """
        Add messages to a thread.

        Parameters
        ----------
        thread_id : str
            The ID of the thread to which messages should be added.

        messages : typing.Sequence[Message]
            A list of message objects, where each message contains a role and content.

        ignore_roles : typing.Optional[typing.Sequence[RoleType]]
            Optional list of role types to ignore when adding messages to graph memory.
            The message itself will still be added, retained and used as context for messages
            that are added to a user's graph.

        return_context : typing.Optional[bool]
            Optionally return memory context relevant to the most recent messages.

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

        Returns
        -------
        AddThreadMessagesResponse
            An object, optionally containing user context retrieved for the last thread message

        Examples
        --------
        from zep_cloud import Message, Zep

        client = Zep(
            api_key="YOUR_API_KEY",
        )
        client.thread.add_messages(
            thread_id="threadId",
            messages=[
                Message(
                    content="content",
                    role="norole",
                )
            ],
        )
        """
        _response = self._raw_client.add_messages(
            thread_id,
            messages=messages,
            ignore_roles=ignore_roles,
            return_context=return_context,
            request_options=request_options,
        )
        return _response.data


class AsyncThreadClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawThreadClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawThreadClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawThreadClient
        """
        return self._raw_client

    async def list_all(
        self,
        *,
        page_number: typing.Optional[int] = None,
        page_size: typing.Optional[int] = None,
        order_by: typing.Optional[str] = None,
        asc: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ThreadListResponse:
        """
        Returns all threads.

        Parameters
        ----------
        page_number : typing.Optional[int]
            Page number for pagination, starting from 1

        page_size : typing.Optional[int]
            Number of threads to retrieve per page.

        order_by : typing.Optional[str]
            Field to order the results by: created_at, updated_at, user_id, thread_id.

        asc : typing.Optional[bool]
            Order direction: true for ascending, false for descending.

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

        Returns
        -------
        ThreadListResponse
            List of threads

        Examples
        --------
        import asyncio

        from zep_cloud import AsyncZep

        client = AsyncZep(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.thread.list_all()


        asyncio.run(main())
        """
        _response = await self._raw_client.list_all(
            page_number=page_number, page_size=page_size, order_by=order_by, asc=asc, request_options=request_options
        )
        return _response.data

    async def create(
        self, *, thread_id: str, user_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> Thread:
        """
        Start a new thread.

        Parameters
        ----------
        thread_id : str
            The unique identifier of the thread.

        user_id : str
            The unique identifier of the user associated with the thread

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

        Returns
        -------
        Thread
            The thread object.

        Examples
        --------
        import asyncio

        from zep_cloud import AsyncZep

        client = AsyncZep(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.thread.create(
                thread_id="thread_id",
                user_id="user_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create(thread_id=thread_id, user_id=user_id, request_options=request_options)
        return _response.data

    async def delete(
        self, thread_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> SuccessResponse:
        """
        Deletes a thread.

        Parameters
        ----------
        thread_id : str
            The ID of the thread for which memory should be deleted.

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

        Returns
        -------
        SuccessResponse
            OK

        Examples
        --------
        import asyncio

        from zep_cloud import AsyncZep

        client = AsyncZep(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.thread.delete(
                thread_id="threadId",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.delete(thread_id, request_options=request_options)
        return _response.data

    async def get_user_context(
        self,
        thread_id: str,
        *,
        lastn: typing.Optional[int] = None,
        min_rating: typing.Optional[float] = None,
        fast: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ThreadContextResponse:
        """
        Returns most relevant context for a given thread.

        Parameters
        ----------
        thread_id : str
            The ID of the thread for which to retrieve context.

        lastn : typing.Optional[int]
            The number of most recent memory entries to retrieve.

        min_rating : typing.Optional[float]
            The minimum rating by which to filter relevant facts.

        fast : typing.Optional[bool]
            If true, bypasses context summarization and returns raw search results.

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

        Returns
        -------
        ThreadContextResponse
            OK

        Examples
        --------
        import asyncio

        from zep_cloud import AsyncZep

        client = AsyncZep(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.thread.get_user_context(
                thread_id="threadId",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_user_context(
            thread_id, lastn=lastn, min_rating=min_rating, fast=fast, request_options=request_options
        )
        return _response.data

    async def get(
        self,
        thread_id: str,
        *,
        limit: typing.Optional[int] = None,
        cursor: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> MessageListResponse:
        """
        Returns messages for a thread.

        Parameters
        ----------
        thread_id : str
            Thread ID

        limit : typing.Optional[int]
            Limit the number of results returned

        cursor : typing.Optional[int]
            Cursor for pagination

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

        Returns
        -------
        MessageListResponse
            OK

        Examples
        --------
        import asyncio

        from zep_cloud import AsyncZep

        client = AsyncZep(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.thread.get(
                thread_id="threadId",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get(thread_id, limit=limit, cursor=cursor, request_options=request_options)
        return _response.data

    async def add_messages(
        self,
        thread_id: str,
        *,
        messages: typing.Sequence[Message],
        ignore_roles: typing.Optional[typing.Sequence[RoleType]] = OMIT,
        return_context: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AddThreadMessagesResponse:
        """
        Add messages to a thread.

        Parameters
        ----------
        thread_id : str
            The ID of the thread to which messages should be added.

        messages : typing.Sequence[Message]
            A list of message objects, where each message contains a role and content.

        ignore_roles : typing.Optional[typing.Sequence[RoleType]]
            Optional list of role types to ignore when adding messages to graph memory.
            The message itself will still be added, retained and used as context for messages
            that are added to a user's graph.

        return_context : typing.Optional[bool]
            Optionally return memory context relevant to the most recent messages.

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

        Returns
        -------
        AddThreadMessagesResponse
            An object, optionally containing user context retrieved for the last thread message

        Examples
        --------
        import asyncio

        from zep_cloud import AsyncZep, Message

        client = AsyncZep(
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.thread.add_messages(
                thread_id="threadId",
                messages=[
                    Message(
                        content="content",
                        role="norole",
                    )
                ],
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.add_messages(
            thread_id,
            messages=messages,
            ignore_roles=ignore_roles,
            return_context=return_context,
            request_options=request_options,
        )
        return _response.data
