# 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.pagination import AsyncPager, BaseHttpResponse, SyncPager
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..errors.bad_request_error import BadRequestError
from ..errors.forbidden_error import ForbiddenError
from ..errors.not_found_error import NotFoundError
from ..types.agent_key import AgentKey
from ..types.agent_session import AgentSession
from ..types.agent_session_key import AgentSessionKey
from ..types.bad_request_error_body import BadRequestErrorBody
from ..types.error import Error
from ..types.list_agent_sessions_response import ListAgentSessionsResponse
from ..types.not_found_error_body import NotFoundErrorBody

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


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

    def list(
        self,
        agent_key: AgentKey,
        *,
        filter: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        page_key: typing.Optional[str] = None,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[AgentSession]:
        """
        List all agent sessions for a specific agent, with optional filtering and pagination.

        Parameters
        ----------
        agent_key : AgentKey
            The unique identifier of the agent to list sessions for.

        filter : typing.Optional[str]
            A regular expression against session names and descriptions to filter the results.

        limit : typing.Optional[int]
            The maximum number of sessions to return in the list.

        page_key : typing.Optional[str]
            Used to retrieve the next page of sessions after the limit has been reached.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        SyncPager[AgentSession]
            List of available agent sessions.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions",
            base_url=self._client_wrapper.get_environment().default,
            method="GET",
            params={
                "filter": filter,
                "limit": limit,
                "page_key": page_key,
            },
            headers={
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListAgentSessionsResponse,
                    parse_obj_as(
                        type_=ListAgentSessionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.sessions
                _has_next = False
                _get_next = None
                if _parsed_response.metadata is not None:
                    _parsed_next = _parsed_response.metadata.page_key
                    _has_next = _parsed_next is not None and _parsed_next != ""
                    _get_next = lambda: self.list(
                        agent_key,
                        filter=filter,
                        limit=limit,
                        page_key=_parsed_next,
                        request_timeout=request_timeout,
                        request_timeout_millis=request_timeout_millis,
                        request_options=request_options,
                    )
                return SyncPager(
                    has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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_key: AgentKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        key: typing.Optional[AgentSessionKey] = OMIT,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        tti_minutes: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentSession]:
        """
        Create a new session for interacting with an agent. Sessions maintain conversation context.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to create a session for.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        key : typing.Optional[AgentSessionKey]
            A user provided key that uniquely identifies this session. If not provided, one will be auto-generated based on the session name.

        name : typing.Optional[str]
            Human-readable name for the session.

        description : typing.Optional[str]
            Optional description of the session purpose or context.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the session.

        enabled : typing.Optional[bool]
            Whether the session should be enabled upon creation.

        tti_minutes : typing.Optional[int]
            Time-to-idle in minutes for the session. If no events occur in the session for this duration, the session will be automatically deleted. If set to 0, the session will not expire.

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

        Returns
        -------
        HttpResponse[AgentSession]
            The agent session has been created successfully.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions",
            base_url=self._client_wrapper.get_environment().default,
            method="POST",
            json={
                "key": key,
                "name": name,
                "description": description,
                "metadata": metadata,
                "enabled": enabled,
                "tti_minutes": tti_minutes,
            },
            headers={
                "content-type": "application/json",
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentSession,
                    parse_obj_as(
                        type_=AgentSession,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        BadRequestErrorBody,
                        parse_obj_as(
                            type_=BadRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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,
        agent_key: AgentKey,
        session_key: AgentSessionKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentSession]:
        """
        Retrieve the details of a specific agent session by its ID, including session configuration.

        Parameters
        ----------
        agent_key : AgentKey
            The unique identifier of the agent.

        session_key : AgentSessionKey
            The unique key of the session to retrieve.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        HttpResponse[AgentSession]
            The requested agent session details.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions/{jsonable_encoder(session_key)}",
            base_url=self._client_wrapper.get_environment().default,
            method="GET",
            headers={
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentSession,
                    parse_obj_as(
                        type_=AgentSession,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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_key: AgentKey,
        session_key: AgentSessionKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[None]:
        """
        Permanently delete an agent session. This action cannot be undone.

        Parameters
        ----------
        agent_key : AgentKey
            The unique identifier of the agent.

        session_key : AgentSessionKey
            The unique key of the session to delete.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions/{jsonable_encoder(session_key)}",
            base_url=self._client_wrapper.get_environment().default,
            method="DELETE",
            headers={
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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 update(
        self,
        agent_key: AgentKey,
        session_key: AgentSessionKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        tti_minutes: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentSession]:
        """
        Update an existing agent session's configuration and metadata.

        Parameters
        ----------
        agent_key : AgentKey
            The unique identifier of the agent.

        session_key : AgentSessionKey
            The unique key of the session to update.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        name : typing.Optional[str]
            Human-readable name for the session.

        description : typing.Optional[str]
            Optional description of the session purpose or context.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the session.

        enabled : typing.Optional[bool]
            Whether the session is enabled.

        tti_minutes : typing.Optional[int]
            Time-to-idle in minutes for the session. If no events occur in the session for this duration, the session will be automatically deleted. If set to 0, the session will not expire.

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

        Returns
        -------
        HttpResponse[AgentSession]
            The agent session has been updated successfully.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions/{jsonable_encoder(session_key)}",
            base_url=self._client_wrapper.get_environment().default,
            method="PATCH",
            json={
                "name": name,
                "description": description,
                "metadata": metadata,
                "enabled": enabled,
                "tti_minutes": tti_minutes,
            },
            headers={
                "content-type": "application/json",
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentSession,
                    parse_obj_as(
                        type_=AgentSession,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        BadRequestErrorBody,
                        parse_obj_as(
                            type_=BadRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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 AsyncRawAgentSessionsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        agent_key: AgentKey,
        *,
        filter: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        page_key: typing.Optional[str] = None,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[AgentSession]:
        """
        List all agent sessions for a specific agent, with optional filtering and pagination.

        Parameters
        ----------
        agent_key : AgentKey
            The unique identifier of the agent to list sessions for.

        filter : typing.Optional[str]
            A regular expression against session names and descriptions to filter the results.

        limit : typing.Optional[int]
            The maximum number of sessions to return in the list.

        page_key : typing.Optional[str]
            Used to retrieve the next page of sessions after the limit has been reached.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        AsyncPager[AgentSession]
            List of available agent sessions.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions",
            base_url=self._client_wrapper.get_environment().default,
            method="GET",
            params={
                "filter": filter,
                "limit": limit,
                "page_key": page_key,
            },
            headers={
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    ListAgentSessionsResponse,
                    parse_obj_as(
                        type_=ListAgentSessionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.sessions
                _has_next = False
                _get_next = None
                if _parsed_response.metadata is not None:
                    _parsed_next = _parsed_response.metadata.page_key
                    _has_next = _parsed_next is not None and _parsed_next != ""

                    async def _get_next():
                        return await self.list(
                            agent_key,
                            filter=filter,
                            limit=limit,
                            page_key=_parsed_next,
                            request_timeout=request_timeout,
                            request_timeout_millis=request_timeout_millis,
                            request_options=request_options,
                        )

                return AsyncPager(
                    has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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_key: AgentKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        key: typing.Optional[AgentSessionKey] = OMIT,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        tti_minutes: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentSession]:
        """
        Create a new session for interacting with an agent. Sessions maintain conversation context.

        Parameters
        ----------
        agent_key : AgentKey
            The unique key of the agent to create a session for.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        key : typing.Optional[AgentSessionKey]
            A user provided key that uniquely identifies this session. If not provided, one will be auto-generated based on the session name.

        name : typing.Optional[str]
            Human-readable name for the session.

        description : typing.Optional[str]
            Optional description of the session purpose or context.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the session.

        enabled : typing.Optional[bool]
            Whether the session should be enabled upon creation.

        tti_minutes : typing.Optional[int]
            Time-to-idle in minutes for the session. If no events occur in the session for this duration, the session will be automatically deleted. If set to 0, the session will not expire.

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

        Returns
        -------
        AsyncHttpResponse[AgentSession]
            The agent session has been created successfully.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions",
            base_url=self._client_wrapper.get_environment().default,
            method="POST",
            json={
                "key": key,
                "name": name,
                "description": description,
                "metadata": metadata,
                "enabled": enabled,
                "tti_minutes": tti_minutes,
            },
            headers={
                "content-type": "application/json",
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentSession,
                    parse_obj_as(
                        type_=AgentSession,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        BadRequestErrorBody,
                        parse_obj_as(
                            type_=BadRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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,
        agent_key: AgentKey,
        session_key: AgentSessionKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentSession]:
        """
        Retrieve the details of a specific agent session by its ID, including session configuration.

        Parameters
        ----------
        agent_key : AgentKey
            The unique identifier of the agent.

        session_key : AgentSessionKey
            The unique key of the session to retrieve.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        AsyncHttpResponse[AgentSession]
            The requested agent session details.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions/{jsonable_encoder(session_key)}",
            base_url=self._client_wrapper.get_environment().default,
            method="GET",
            headers={
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentSession,
                    parse_obj_as(
                        type_=AgentSession,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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_key: AgentKey,
        session_key: AgentSessionKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[None]:
        """
        Permanently delete an agent session. This action cannot be undone.

        Parameters
        ----------
        agent_key : AgentKey
            The unique identifier of the agent.

        session_key : AgentSessionKey
            The unique key of the session to delete.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions/{jsonable_encoder(session_key)}",
            base_url=self._client_wrapper.get_environment().default,
            method="DELETE",
            headers={
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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 update(
        self,
        agent_key: AgentKey,
        session_key: AgentSessionKey,
        *,
        request_timeout: typing.Optional[int] = None,
        request_timeout_millis: typing.Optional[int] = None,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        enabled: typing.Optional[bool] = OMIT,
        tti_minutes: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentSession]:
        """
        Update an existing agent session's configuration and metadata.

        Parameters
        ----------
        agent_key : AgentKey
            The unique identifier of the agent.

        session_key : AgentSessionKey
            The unique key of the session to update.

        request_timeout : typing.Optional[int]
            The API will make a best effort to complete the request in the specified seconds or time out.

        request_timeout_millis : typing.Optional[int]
            The API will make a best effort to complete the request in the specified milliseconds or time out.

        name : typing.Optional[str]
            Human-readable name for the session.

        description : typing.Optional[str]
            Optional description of the session purpose or context.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            Arbitrary metadata associated with the session.

        enabled : typing.Optional[bool]
            Whether the session is enabled.

        tti_minutes : typing.Optional[int]
            Time-to-idle in minutes for the session. If no events occur in the session for this duration, the session will be automatically deleted. If set to 0, the session will not expire.

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

        Returns
        -------
        AsyncHttpResponse[AgentSession]
            The agent session has been updated successfully.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v2/agents/{jsonable_encoder(agent_key)}/sessions/{jsonable_encoder(session_key)}",
            base_url=self._client_wrapper.get_environment().default,
            method="PATCH",
            json={
                "name": name,
                "description": description,
                "metadata": metadata,
                "enabled": enabled,
                "tti_minutes": tti_minutes,
            },
            headers={
                "content-type": "application/json",
                "Request-Timeout": str(request_timeout) if request_timeout is not None else None,
                "Request-Timeout-Millis": str(request_timeout_millis) if request_timeout_millis is not None else None,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentSession,
                    parse_obj_as(
                        type_=AgentSession,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        BadRequestErrorBody,
                        parse_obj_as(
                            type_=BadRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        NotFoundErrorBody,
                        parse_obj_as(
                            type_=NotFoundErrorBody,  # 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)
