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

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

from .. import core
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.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..core.unchecked_base_model import construct_type
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.agent_state import AgentState
from ..types.agent_type import AgentType
from ..types.create_block import CreateBlock
from ..types.embedding_config import EmbeddingConfig
from ..types.http_validation_error import HttpValidationError
from ..types.imported_agents_response import ImportedAgentsResponse
from ..types.llm_config import LlmConfig
from ..types.message_create import MessageCreate
from .types.agents_list_request_order import AgentsListRequestOrder
from .types.agents_list_request_order_by import AgentsListRequestOrderBy
from .types.agents_search_request_search_item import AgentsSearchRequestSearchItem
from .types.agents_search_request_sort_by import AgentsSearchRequestSortBy
from .types.agents_search_response import AgentsSearchResponse
from .types.create_agent_request_response_format import CreateAgentRequestResponseFormat
from .types.create_agent_request_tool_rules_item import CreateAgentRequestToolRulesItem
from .types.update_agent_response_format import UpdateAgentResponseFormat
from .types.update_agent_tool_rules_item import UpdateAgentToolRulesItem

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


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

    def list(
        self,
        *,
        name: typing.Optional[str] = None,
        tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        match_all_tags: typing.Optional[bool] = None,
        before: typing.Optional[str] = None,
        after: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        query_text: typing.Optional[str] = None,
        project_id: typing.Optional[str] = None,
        template_id: typing.Optional[str] = None,
        base_template_id: typing.Optional[str] = None,
        identity_id: typing.Optional[str] = None,
        identifier_keys: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        include_relationships: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        order: typing.Optional[AgentsListRequestOrder] = None,
        order_by: typing.Optional[AgentsListRequestOrderBy] = None,
        ascending: typing.Optional[bool] = None,
        sort_by: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.List[AgentState]]:
        """
        Get a list of all agents.

        Parameters
        ----------
        name : typing.Optional[str]
            Name of the agent

        tags : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            List of tags to filter agents by

        match_all_tags : typing.Optional[bool]
            If True, only returns agents that match ALL given tags. Otherwise, return agents that have ANY of the passed-in tags.

        before : typing.Optional[str]
            Cursor for pagination

        after : typing.Optional[str]
            Cursor for pagination

        limit : typing.Optional[int]
            Limit for pagination

        query_text : typing.Optional[str]
            Search agents by name

        project_id : typing.Optional[str]
            Search agents by project ID - this will default to your default project on cloud

        template_id : typing.Optional[str]
            Search agents by template ID

        base_template_id : typing.Optional[str]
            Search agents by base template ID

        identity_id : typing.Optional[str]
            Search agents by identity ID

        identifier_keys : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Search agents by identifier keys

        include_relationships : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Specify which relational fields (e.g., 'tools', 'sources', 'memory') to include in the response. If not provided, all relationships are loaded by default. Using this can optimize performance by reducing unnecessary joins.

        order : typing.Optional[AgentsListRequestOrder]
            Sort order for agents by creation time. 'asc' for oldest first, 'desc' for newest first

        order_by : typing.Optional[AgentsListRequestOrderBy]
            Field to sort by

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

        sort_by : typing.Optional[str]
            Field to sort by. Options: 'created_at' (default), 'last_run_completion'

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

        Returns
        -------
        HttpResponse[typing.List[AgentState]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/agents/",
            method="GET",
            params={
                "name": name,
                "tags": tags,
                "match_all_tags": match_all_tags,
                "before": before,
                "after": after,
                "limit": limit,
                "query_text": query_text,
                "project_id": project_id,
                "template_id": template_id,
                "base_template_id": base_template_id,
                "identity_id": identity_id,
                "identifier_keys": identifier_keys,
                "include_relationships": include_relationships,
                "order": order,
                "order_by": order_by,
                "ascending": ascending,
                "sort_by": sort_by,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[AgentState],
                    construct_type(
                        type_=typing.List[AgentState],  # 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,
        *,
        name: typing.Optional[str] = OMIT,
        memory_blocks: typing.Optional[typing.Sequence[CreateBlock]] = OMIT,
        tools: typing.Optional[typing.Sequence[str]] = OMIT,
        tool_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        source_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        block_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        tool_rules: typing.Optional[typing.Sequence[CreateAgentRequestToolRulesItem]] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        system: typing.Optional[str] = OMIT,
        agent_type: typing.Optional[AgentType] = OMIT,
        llm_config: typing.Optional[LlmConfig] = OMIT,
        embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
        initial_message_sequence: typing.Optional[typing.Sequence[MessageCreate]] = OMIT,
        include_base_tools: typing.Optional[bool] = OMIT,
        include_multi_agent_tools: typing.Optional[bool] = OMIT,
        include_base_tool_rules: typing.Optional[bool] = OMIT,
        include_default_source: typing.Optional[bool] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        model: typing.Optional[str] = OMIT,
        embedding: typing.Optional[str] = OMIT,
        context_window_limit: typing.Optional[int] = OMIT,
        embedding_chunk_size: typing.Optional[int] = OMIT,
        max_tokens: typing.Optional[int] = OMIT,
        max_reasoning_tokens: typing.Optional[int] = OMIT,
        enable_reasoner: typing.Optional[bool] = OMIT,
        reasoning: typing.Optional[bool] = OMIT,
        from_template: typing.Optional[str] = OMIT,
        template: typing.Optional[bool] = OMIT,
        project: typing.Optional[str] = OMIT,
        tool_exec_environment_variables: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        secrets: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        memory_variables: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        template_id: typing.Optional[str] = OMIT,
        base_template_id: typing.Optional[str] = OMIT,
        identity_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        message_buffer_autoclear: typing.Optional[bool] = OMIT,
        enable_sleeptime: typing.Optional[bool] = OMIT,
        response_format: typing.Optional[CreateAgentRequestResponseFormat] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        max_files_open: typing.Optional[int] = OMIT,
        per_file_view_window_char_limit: typing.Optional[int] = OMIT,
        hidden: typing.Optional[bool] = OMIT,
        parallel_tool_calls: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentState]:
        """
        Create an agent.

        Parameters
        ----------
        name : typing.Optional[str]
            The name of the agent.

        memory_blocks : typing.Optional[typing.Sequence[CreateBlock]]
            The blocks to create in the agent's in-context memory.

        tools : typing.Optional[typing.Sequence[str]]
            The tools used by the agent.

        tool_ids : typing.Optional[typing.Sequence[str]]
            The ids of the tools used by the agent.

        source_ids : typing.Optional[typing.Sequence[str]]
            The ids of the sources used by the agent.

        block_ids : typing.Optional[typing.Sequence[str]]
            The ids of the blocks used by the agent.

        tool_rules : typing.Optional[typing.Sequence[CreateAgentRequestToolRulesItem]]
            The tool rules governing the agent.

        tags : typing.Optional[typing.Sequence[str]]
            The tags associated with the agent.

        system : typing.Optional[str]
            The system prompt used by the agent.

        agent_type : typing.Optional[AgentType]
            The type of agent.

        llm_config : typing.Optional[LlmConfig]
            The LLM configuration used by the agent.

        embedding_config : typing.Optional[EmbeddingConfig]
            The embedding configuration used by the agent.

        initial_message_sequence : typing.Optional[typing.Sequence[MessageCreate]]
            The initial set of messages to put in the agent's in-context memory.

        include_base_tools : typing.Optional[bool]
            If true, attaches the Letta core tools (e.g. core_memory related functions).

        include_multi_agent_tools : typing.Optional[bool]
            If true, attaches the Letta multi-agent tools (e.g. sending a message to another agent).

        include_base_tool_rules : typing.Optional[bool]
            If true, attaches the Letta base tool rules (e.g. deny all tools not explicitly allowed).

        include_default_source : typing.Optional[bool]
            If true, automatically creates and attaches a default data source for this agent.

        description : typing.Optional[str]
            The description of the agent.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            The metadata of the agent.

        model : typing.Optional[str]
            The LLM configuration handle used by the agent, specified in the format provider/model-name, as an alternative to specifying llm_config.

        embedding : typing.Optional[str]
            The embedding configuration handle used by the agent, specified in the format provider/model-name.

        context_window_limit : typing.Optional[int]
            The context window limit used by the agent.

        embedding_chunk_size : typing.Optional[int]
            The embedding chunk size used by the agent.

        max_tokens : typing.Optional[int]
            The maximum number of tokens to generate, including reasoning step. If not set, the model will use its default value.

        max_reasoning_tokens : typing.Optional[int]
            The maximum number of tokens to generate for reasoning step. If not set, the model will use its default value.

        enable_reasoner : typing.Optional[bool]
            Whether to enable internal extended thinking step for a reasoner model.

        reasoning : typing.Optional[bool]
            Whether to enable reasoning for this agent.

        from_template : typing.Optional[str]
            Deprecated: please use the 'create agents from a template' endpoint instead.

        template : typing.Optional[bool]
            Deprecated: No longer used

        project : typing.Optional[str]
            Deprecated: Project should now be passed via the X-Project header instead of in the request body. If using the sdk, this can be done via the new x_project field below.

        tool_exec_environment_variables : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            Deprecated: use `secrets` field instead.

        secrets : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            The environment variables for tool execution specific to this agent.

        memory_variables : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            The variables that should be set for the agent.

        project_id : typing.Optional[str]
            The id of the project the agent belongs to.

        template_id : typing.Optional[str]
            The id of the template the agent belongs to.

        base_template_id : typing.Optional[str]
            The base template id of the agent.

        identity_ids : typing.Optional[typing.Sequence[str]]
            The ids of the identities associated with this agent.

        message_buffer_autoclear : typing.Optional[bool]
            If set to True, the agent will not remember previous messages (though the agent will still retain state via core memory blocks and archival/recall memory). Not recommended unless you have an advanced use case.

        enable_sleeptime : typing.Optional[bool]
            If set to True, memory management will move to a background agent thread.

        response_format : typing.Optional[CreateAgentRequestResponseFormat]
            The response format for the agent.

        timezone : typing.Optional[str]
            The timezone of the agent (IANA format).

        max_files_open : typing.Optional[int]
            Maximum number of files that can be open at once for this agent. Setting this too high may exceed the context window, which will break the agent.

        per_file_view_window_char_limit : typing.Optional[int]
            The per-file view window character limit for this agent. Setting this too high may exceed the context window, which will break the agent.

        hidden : typing.Optional[bool]
            If set to True, the agent will be hidden.

        parallel_tool_calls : typing.Optional[bool]
            If set to True, enables parallel tool calling. Defaults to False.

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

        Returns
        -------
        HttpResponse[AgentState]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/agents/",
            method="POST",
            json={
                "name": name,
                "memory_blocks": convert_and_respect_annotation_metadata(
                    object_=memory_blocks, annotation=typing.Sequence[CreateBlock], direction="write"
                ),
                "tools": tools,
                "tool_ids": tool_ids,
                "source_ids": source_ids,
                "block_ids": block_ids,
                "tool_rules": convert_and_respect_annotation_metadata(
                    object_=tool_rules, annotation=typing.Sequence[CreateAgentRequestToolRulesItem], direction="write"
                ),
                "tags": tags,
                "system": system,
                "agent_type": agent_type,
                "llm_config": convert_and_respect_annotation_metadata(
                    object_=llm_config, annotation=LlmConfig, direction="write"
                ),
                "embedding_config": convert_and_respect_annotation_metadata(
                    object_=embedding_config, annotation=EmbeddingConfig, direction="write"
                ),
                "initial_message_sequence": convert_and_respect_annotation_metadata(
                    object_=initial_message_sequence, annotation=typing.Sequence[MessageCreate], direction="write"
                ),
                "include_base_tools": include_base_tools,
                "include_multi_agent_tools": include_multi_agent_tools,
                "include_base_tool_rules": include_base_tool_rules,
                "include_default_source": include_default_source,
                "description": description,
                "metadata": metadata,
                "model": model,
                "embedding": embedding,
                "context_window_limit": context_window_limit,
                "embedding_chunk_size": embedding_chunk_size,
                "max_tokens": max_tokens,
                "max_reasoning_tokens": max_reasoning_tokens,
                "enable_reasoner": enable_reasoner,
                "reasoning": reasoning,
                "from_template": from_template,
                "template": template,
                "project": project,
                "tool_exec_environment_variables": tool_exec_environment_variables,
                "secrets": secrets,
                "memory_variables": memory_variables,
                "project_id": project_id,
                "template_id": template_id,
                "base_template_id": base_template_id,
                "identity_ids": identity_ids,
                "message_buffer_autoclear": message_buffer_autoclear,
                "enable_sleeptime": enable_sleeptime,
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=CreateAgentRequestResponseFormat, direction="write"
                ),
                "timezone": timezone,
                "max_files_open": max_files_open,
                "per_file_view_window_char_limit": per_file_view_window_char_limit,
                "hidden": hidden,
                "parallel_tool_calls": parallel_tool_calls,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentState,
                    construct_type(
                        type_=AgentState,  # 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 count(self, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[int]:
        """
        Get the total number of agents.

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

        Returns
        -------
        HttpResponse[int]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/agents/count",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    int,
                    construct_type(
                        type_=int,  # 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 export_file(
        self,
        agent_id: str,
        *,
        max_steps: typing.Optional[int] = None,
        use_legacy_format: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[str]:
        """
        Export the serialized JSON representation of an agent, formatted with indentation.

        Supports two export formats:
        - Legacy format (use_legacy_format=true): Single agent with inline tools/blocks
        - New format (default): Multi-entity format with separate agents, tools, blocks, files, etc.

        Parameters
        ----------
        agent_id : str
            The ID of the agent in the format 'agent-<uuid4>'

        max_steps : typing.Optional[int]

        use_legacy_format : typing.Optional[bool]
            If true, exports using the legacy single-agent format (v1). If false, exports using the new multi-entity format (v2).

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

        Returns
        -------
        HttpResponse[str]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/export",
            method="GET",
            params={
                "max_steps": max_steps,
                "use_legacy_format": use_legacy_format,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    str,
                    construct_type(
                        type_=str,  # 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 import_file(
        self,
        *,
        file: core.File,
        override_embedding_model: typing.Optional[str] = None,
        append_copy_suffix: typing.Optional[bool] = OMIT,
        override_existing_tools: typing.Optional[bool] = OMIT,
        override_embedding_handle: typing.Optional[str] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        strip_messages: typing.Optional[bool] = OMIT,
        env_vars_json: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ImportedAgentsResponse]:
        """
        Import a serialized agent file and recreate the agent(s) in the system.
        Returns the IDs of all imported agents.

        Parameters
        ----------
        file : core.File
            See core.File for more documentation

        override_embedding_model : typing.Optional[str]

        append_copy_suffix : typing.Optional[bool]
            If set to True, appends "_copy" to the end of the agent name.

        override_existing_tools : typing.Optional[bool]
            If set to True, existing tools can get their source code overwritten by the uploaded tool definitions. Note that Letta core tools can never be updated externally.

        override_embedding_handle : typing.Optional[str]
            Override import with specific embedding handle.

        project_id : typing.Optional[str]
            The project ID to associate the uploaded agent with.

        strip_messages : typing.Optional[bool]
            If set to True, strips all messages from the agent before importing.

        env_vars_json : typing.Optional[str]
            Environment variables as a JSON string to pass to the agent for tool execution.

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

        Returns
        -------
        HttpResponse[ImportedAgentsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/agents/import",
            method="POST",
            data={
                "append_copy_suffix": append_copy_suffix,
                "override_existing_tools": override_existing_tools,
                "override_embedding_handle": override_embedding_handle,
                "project_id": project_id,
                "strip_messages": strip_messages,
                "env_vars_json": env_vars_json,
            },
            files={
                "file": file,
            },
            headers={
                "x-override-embedding-model": str(override_embedding_model)
                if override_embedding_model is not None
                else None,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ImportedAgentsResponse,
                    construct_type(
                        type_=ImportedAgentsResponse,  # 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 retrieve(
        self,
        agent_id: str,
        *,
        include_relationships: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentState]:
        """
        Get the state of the agent.

        Parameters
        ----------
        agent_id : str
            The ID of the agent in the format 'agent-<uuid4>'

        include_relationships : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Specify which relational fields (e.g., 'tools', 'sources', 'memory') to include in the response. If not provided, all relationships are loaded by default. Using this can optimize performance by reducing unnecessary joins.

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

        Returns
        -------
        HttpResponse[AgentState]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}",
            method="GET",
            params={
                "include_relationships": include_relationships,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentState,
                    construct_type(
                        type_=AgentState,  # 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, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Optional[typing.Any]]:
        """
        Delete an agent.

        Parameters
        ----------
        agent_id : str
            The ID of the agent in the format 'agent-<uuid4>'

        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)}",
            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,
        *,
        name: typing.Optional[str] = OMIT,
        tool_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        source_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        block_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        system: typing.Optional[str] = OMIT,
        tool_rules: typing.Optional[typing.Sequence[UpdateAgentToolRulesItem]] = OMIT,
        llm_config: typing.Optional[LlmConfig] = OMIT,
        embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
        message_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        tool_exec_environment_variables: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        secrets: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        template_id: typing.Optional[str] = OMIT,
        base_template_id: typing.Optional[str] = OMIT,
        identity_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        message_buffer_autoclear: typing.Optional[bool] = OMIT,
        model: typing.Optional[str] = OMIT,
        embedding: typing.Optional[str] = OMIT,
        reasoning: typing.Optional[bool] = OMIT,
        enable_sleeptime: typing.Optional[bool] = OMIT,
        response_format: typing.Optional[UpdateAgentResponseFormat] = OMIT,
        last_run_completion: typing.Optional[dt.datetime] = OMIT,
        last_run_duration_ms: typing.Optional[int] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        max_files_open: typing.Optional[int] = OMIT,
        per_file_view_window_char_limit: typing.Optional[int] = OMIT,
        hidden: typing.Optional[bool] = OMIT,
        parallel_tool_calls: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentState]:
        """
        Update an existing agent.

        Parameters
        ----------
        agent_id : str
            The ID of the agent in the format 'agent-<uuid4>'

        name : typing.Optional[str]
            The name of the agent.

        tool_ids : typing.Optional[typing.Sequence[str]]
            The ids of the tools used by the agent.

        source_ids : typing.Optional[typing.Sequence[str]]
            The ids of the sources used by the agent.

        block_ids : typing.Optional[typing.Sequence[str]]
            The ids of the blocks used by the agent.

        tags : typing.Optional[typing.Sequence[str]]
            The tags associated with the agent.

        system : typing.Optional[str]
            The system prompt used by the agent.

        tool_rules : typing.Optional[typing.Sequence[UpdateAgentToolRulesItem]]
            The tool rules governing the agent.

        llm_config : typing.Optional[LlmConfig]
            The LLM configuration used by the agent.

        embedding_config : typing.Optional[EmbeddingConfig]
            The embedding configuration used by the agent.

        message_ids : typing.Optional[typing.Sequence[str]]
            The ids of the messages in the agent's in-context memory.

        description : typing.Optional[str]
            The description of the agent.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            The metadata of the agent.

        tool_exec_environment_variables : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            Deprecated: use `secrets` field instead

        secrets : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            The environment variables for tool execution specific to this agent.

        project_id : typing.Optional[str]
            The id of the project the agent belongs to.

        template_id : typing.Optional[str]
            The id of the template the agent belongs to.

        base_template_id : typing.Optional[str]
            The base template id of the agent.

        identity_ids : typing.Optional[typing.Sequence[str]]
            The ids of the identities associated with this agent.

        message_buffer_autoclear : typing.Optional[bool]
            If set to True, the agent will not remember previous messages (though the agent will still retain state via core memory blocks and archival/recall memory). Not recommended unless you have an advanced use case.

        model : typing.Optional[str]
            The LLM configuration handle used by the agent, specified in the format provider/model-name, as an alternative to specifying llm_config.

        embedding : typing.Optional[str]
            The embedding configuration handle used by the agent, specified in the format provider/model-name.

        reasoning : typing.Optional[bool]
            Whether to enable reasoning for this agent.

        enable_sleeptime : typing.Optional[bool]
            If set to True, memory management will move to a background agent thread.

        response_format : typing.Optional[UpdateAgentResponseFormat]
            The response format for the agent.

        last_run_completion : typing.Optional[dt.datetime]
            The timestamp when the agent last completed a run.

        last_run_duration_ms : typing.Optional[int]
            The duration in milliseconds of the agent's last run.

        timezone : typing.Optional[str]
            The timezone of the agent (IANA format).

        max_files_open : typing.Optional[int]
            Maximum number of files that can be open at once for this agent. Setting this too high may exceed the context window, which will break the agent.

        per_file_view_window_char_limit : typing.Optional[int]
            The per-file view window character limit for this agent. Setting this too high may exceed the context window, which will break the agent.

        hidden : typing.Optional[bool]
            If set to True, the agent will be hidden.

        parallel_tool_calls : typing.Optional[bool]
            If set to True, enables parallel tool calling. Defaults to False.

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

        Returns
        -------
        HttpResponse[AgentState]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}",
            method="PATCH",
            json={
                "name": name,
                "tool_ids": tool_ids,
                "source_ids": source_ids,
                "block_ids": block_ids,
                "tags": tags,
                "system": system,
                "tool_rules": convert_and_respect_annotation_metadata(
                    object_=tool_rules, annotation=typing.Sequence[UpdateAgentToolRulesItem], direction="write"
                ),
                "llm_config": convert_and_respect_annotation_metadata(
                    object_=llm_config, annotation=LlmConfig, direction="write"
                ),
                "embedding_config": convert_and_respect_annotation_metadata(
                    object_=embedding_config, annotation=EmbeddingConfig, direction="write"
                ),
                "message_ids": message_ids,
                "description": description,
                "metadata": metadata,
                "tool_exec_environment_variables": tool_exec_environment_variables,
                "secrets": secrets,
                "project_id": project_id,
                "template_id": template_id,
                "base_template_id": base_template_id,
                "identity_ids": identity_ids,
                "message_buffer_autoclear": message_buffer_autoclear,
                "model": model,
                "embedding": embedding,
                "reasoning": reasoning,
                "enable_sleeptime": enable_sleeptime,
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=UpdateAgentResponseFormat, direction="write"
                ),
                "last_run_completion": last_run_completion,
                "last_run_duration_ms": last_run_duration_ms,
                "timezone": timezone,
                "max_files_open": max_files_open,
                "per_file_view_window_char_limit": per_file_view_window_char_limit,
                "hidden": hidden,
                "parallel_tool_calls": parallel_tool_calls,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentState,
                    construct_type(
                        type_=AgentState,  # 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,
        *,
        search: typing.Optional[typing.Sequence[AgentsSearchRequestSearchItem]] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        combinator: typing.Optional[typing.Literal["AND"]] = OMIT,
        limit: typing.Optional[float] = OMIT,
        after: typing.Optional[str] = OMIT,
        sort_by: typing.Optional[AgentsSearchRequestSortBy] = OMIT,
        ascending: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AgentsSearchResponse]:
        """
        <Note>This endpoint is only available on Letta Cloud.</Note>

        Search deployed agents.

        Parameters
        ----------
        search : typing.Optional[typing.Sequence[AgentsSearchRequestSearchItem]]

        project_id : typing.Optional[str]

        combinator : typing.Optional[typing.Literal["AND"]]

        limit : typing.Optional[float]

        after : typing.Optional[str]

        sort_by : typing.Optional[AgentsSearchRequestSortBy]

        ascending : typing.Optional[bool]

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

        Returns
        -------
        HttpResponse[AgentsSearchResponse]
            200
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/agents/search",
            method="POST",
            json={
                "search": convert_and_respect_annotation_metadata(
                    object_=search, annotation=typing.Sequence[AgentsSearchRequestSearchItem], direction="write"
                ),
                "project_id": project_id,
                "combinator": combinator,
                "limit": limit,
                "after": after,
                "sortBy": sort_by,
                "ascending": ascending,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentsSearchResponse,
                    construct_type(
                        type_=AgentsSearchResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _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 AsyncRawAgentsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        *,
        name: typing.Optional[str] = None,
        tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        match_all_tags: typing.Optional[bool] = None,
        before: typing.Optional[str] = None,
        after: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        query_text: typing.Optional[str] = None,
        project_id: typing.Optional[str] = None,
        template_id: typing.Optional[str] = None,
        base_template_id: typing.Optional[str] = None,
        identity_id: typing.Optional[str] = None,
        identifier_keys: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        include_relationships: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        order: typing.Optional[AgentsListRequestOrder] = None,
        order_by: typing.Optional[AgentsListRequestOrderBy] = None,
        ascending: typing.Optional[bool] = None,
        sort_by: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.List[AgentState]]:
        """
        Get a list of all agents.

        Parameters
        ----------
        name : typing.Optional[str]
            Name of the agent

        tags : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            List of tags to filter agents by

        match_all_tags : typing.Optional[bool]
            If True, only returns agents that match ALL given tags. Otherwise, return agents that have ANY of the passed-in tags.

        before : typing.Optional[str]
            Cursor for pagination

        after : typing.Optional[str]
            Cursor for pagination

        limit : typing.Optional[int]
            Limit for pagination

        query_text : typing.Optional[str]
            Search agents by name

        project_id : typing.Optional[str]
            Search agents by project ID - this will default to your default project on cloud

        template_id : typing.Optional[str]
            Search agents by template ID

        base_template_id : typing.Optional[str]
            Search agents by base template ID

        identity_id : typing.Optional[str]
            Search agents by identity ID

        identifier_keys : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Search agents by identifier keys

        include_relationships : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Specify which relational fields (e.g., 'tools', 'sources', 'memory') to include in the response. If not provided, all relationships are loaded by default. Using this can optimize performance by reducing unnecessary joins.

        order : typing.Optional[AgentsListRequestOrder]
            Sort order for agents by creation time. 'asc' for oldest first, 'desc' for newest first

        order_by : typing.Optional[AgentsListRequestOrderBy]
            Field to sort by

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

        sort_by : typing.Optional[str]
            Field to sort by. Options: 'created_at' (default), 'last_run_completion'

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

        Returns
        -------
        AsyncHttpResponse[typing.List[AgentState]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/agents/",
            method="GET",
            params={
                "name": name,
                "tags": tags,
                "match_all_tags": match_all_tags,
                "before": before,
                "after": after,
                "limit": limit,
                "query_text": query_text,
                "project_id": project_id,
                "template_id": template_id,
                "base_template_id": base_template_id,
                "identity_id": identity_id,
                "identifier_keys": identifier_keys,
                "include_relationships": include_relationships,
                "order": order,
                "order_by": order_by,
                "ascending": ascending,
                "sort_by": sort_by,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[AgentState],
                    construct_type(
                        type_=typing.List[AgentState],  # 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,
        *,
        name: typing.Optional[str] = OMIT,
        memory_blocks: typing.Optional[typing.Sequence[CreateBlock]] = OMIT,
        tools: typing.Optional[typing.Sequence[str]] = OMIT,
        tool_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        source_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        block_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        tool_rules: typing.Optional[typing.Sequence[CreateAgentRequestToolRulesItem]] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        system: typing.Optional[str] = OMIT,
        agent_type: typing.Optional[AgentType] = OMIT,
        llm_config: typing.Optional[LlmConfig] = OMIT,
        embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
        initial_message_sequence: typing.Optional[typing.Sequence[MessageCreate]] = OMIT,
        include_base_tools: typing.Optional[bool] = OMIT,
        include_multi_agent_tools: typing.Optional[bool] = OMIT,
        include_base_tool_rules: typing.Optional[bool] = OMIT,
        include_default_source: typing.Optional[bool] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        model: typing.Optional[str] = OMIT,
        embedding: typing.Optional[str] = OMIT,
        context_window_limit: typing.Optional[int] = OMIT,
        embedding_chunk_size: typing.Optional[int] = OMIT,
        max_tokens: typing.Optional[int] = OMIT,
        max_reasoning_tokens: typing.Optional[int] = OMIT,
        enable_reasoner: typing.Optional[bool] = OMIT,
        reasoning: typing.Optional[bool] = OMIT,
        from_template: typing.Optional[str] = OMIT,
        template: typing.Optional[bool] = OMIT,
        project: typing.Optional[str] = OMIT,
        tool_exec_environment_variables: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        secrets: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        memory_variables: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        template_id: typing.Optional[str] = OMIT,
        base_template_id: typing.Optional[str] = OMIT,
        identity_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        message_buffer_autoclear: typing.Optional[bool] = OMIT,
        enable_sleeptime: typing.Optional[bool] = OMIT,
        response_format: typing.Optional[CreateAgentRequestResponseFormat] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        max_files_open: typing.Optional[int] = OMIT,
        per_file_view_window_char_limit: typing.Optional[int] = OMIT,
        hidden: typing.Optional[bool] = OMIT,
        parallel_tool_calls: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentState]:
        """
        Create an agent.

        Parameters
        ----------
        name : typing.Optional[str]
            The name of the agent.

        memory_blocks : typing.Optional[typing.Sequence[CreateBlock]]
            The blocks to create in the agent's in-context memory.

        tools : typing.Optional[typing.Sequence[str]]
            The tools used by the agent.

        tool_ids : typing.Optional[typing.Sequence[str]]
            The ids of the tools used by the agent.

        source_ids : typing.Optional[typing.Sequence[str]]
            The ids of the sources used by the agent.

        block_ids : typing.Optional[typing.Sequence[str]]
            The ids of the blocks used by the agent.

        tool_rules : typing.Optional[typing.Sequence[CreateAgentRequestToolRulesItem]]
            The tool rules governing the agent.

        tags : typing.Optional[typing.Sequence[str]]
            The tags associated with the agent.

        system : typing.Optional[str]
            The system prompt used by the agent.

        agent_type : typing.Optional[AgentType]
            The type of agent.

        llm_config : typing.Optional[LlmConfig]
            The LLM configuration used by the agent.

        embedding_config : typing.Optional[EmbeddingConfig]
            The embedding configuration used by the agent.

        initial_message_sequence : typing.Optional[typing.Sequence[MessageCreate]]
            The initial set of messages to put in the agent's in-context memory.

        include_base_tools : typing.Optional[bool]
            If true, attaches the Letta core tools (e.g. core_memory related functions).

        include_multi_agent_tools : typing.Optional[bool]
            If true, attaches the Letta multi-agent tools (e.g. sending a message to another agent).

        include_base_tool_rules : typing.Optional[bool]
            If true, attaches the Letta base tool rules (e.g. deny all tools not explicitly allowed).

        include_default_source : typing.Optional[bool]
            If true, automatically creates and attaches a default data source for this agent.

        description : typing.Optional[str]
            The description of the agent.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            The metadata of the agent.

        model : typing.Optional[str]
            The LLM configuration handle used by the agent, specified in the format provider/model-name, as an alternative to specifying llm_config.

        embedding : typing.Optional[str]
            The embedding configuration handle used by the agent, specified in the format provider/model-name.

        context_window_limit : typing.Optional[int]
            The context window limit used by the agent.

        embedding_chunk_size : typing.Optional[int]
            The embedding chunk size used by the agent.

        max_tokens : typing.Optional[int]
            The maximum number of tokens to generate, including reasoning step. If not set, the model will use its default value.

        max_reasoning_tokens : typing.Optional[int]
            The maximum number of tokens to generate for reasoning step. If not set, the model will use its default value.

        enable_reasoner : typing.Optional[bool]
            Whether to enable internal extended thinking step for a reasoner model.

        reasoning : typing.Optional[bool]
            Whether to enable reasoning for this agent.

        from_template : typing.Optional[str]
            Deprecated: please use the 'create agents from a template' endpoint instead.

        template : typing.Optional[bool]
            Deprecated: No longer used

        project : typing.Optional[str]
            Deprecated: Project should now be passed via the X-Project header instead of in the request body. If using the sdk, this can be done via the new x_project field below.

        tool_exec_environment_variables : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            Deprecated: use `secrets` field instead.

        secrets : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            The environment variables for tool execution specific to this agent.

        memory_variables : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            The variables that should be set for the agent.

        project_id : typing.Optional[str]
            The id of the project the agent belongs to.

        template_id : typing.Optional[str]
            The id of the template the agent belongs to.

        base_template_id : typing.Optional[str]
            The base template id of the agent.

        identity_ids : typing.Optional[typing.Sequence[str]]
            The ids of the identities associated with this agent.

        message_buffer_autoclear : typing.Optional[bool]
            If set to True, the agent will not remember previous messages (though the agent will still retain state via core memory blocks and archival/recall memory). Not recommended unless you have an advanced use case.

        enable_sleeptime : typing.Optional[bool]
            If set to True, memory management will move to a background agent thread.

        response_format : typing.Optional[CreateAgentRequestResponseFormat]
            The response format for the agent.

        timezone : typing.Optional[str]
            The timezone of the agent (IANA format).

        max_files_open : typing.Optional[int]
            Maximum number of files that can be open at once for this agent. Setting this too high may exceed the context window, which will break the agent.

        per_file_view_window_char_limit : typing.Optional[int]
            The per-file view window character limit for this agent. Setting this too high may exceed the context window, which will break the agent.

        hidden : typing.Optional[bool]
            If set to True, the agent will be hidden.

        parallel_tool_calls : typing.Optional[bool]
            If set to True, enables parallel tool calling. Defaults to False.

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

        Returns
        -------
        AsyncHttpResponse[AgentState]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/agents/",
            method="POST",
            json={
                "name": name,
                "memory_blocks": convert_and_respect_annotation_metadata(
                    object_=memory_blocks, annotation=typing.Sequence[CreateBlock], direction="write"
                ),
                "tools": tools,
                "tool_ids": tool_ids,
                "source_ids": source_ids,
                "block_ids": block_ids,
                "tool_rules": convert_and_respect_annotation_metadata(
                    object_=tool_rules, annotation=typing.Sequence[CreateAgentRequestToolRulesItem], direction="write"
                ),
                "tags": tags,
                "system": system,
                "agent_type": agent_type,
                "llm_config": convert_and_respect_annotation_metadata(
                    object_=llm_config, annotation=LlmConfig, direction="write"
                ),
                "embedding_config": convert_and_respect_annotation_metadata(
                    object_=embedding_config, annotation=EmbeddingConfig, direction="write"
                ),
                "initial_message_sequence": convert_and_respect_annotation_metadata(
                    object_=initial_message_sequence, annotation=typing.Sequence[MessageCreate], direction="write"
                ),
                "include_base_tools": include_base_tools,
                "include_multi_agent_tools": include_multi_agent_tools,
                "include_base_tool_rules": include_base_tool_rules,
                "include_default_source": include_default_source,
                "description": description,
                "metadata": metadata,
                "model": model,
                "embedding": embedding,
                "context_window_limit": context_window_limit,
                "embedding_chunk_size": embedding_chunk_size,
                "max_tokens": max_tokens,
                "max_reasoning_tokens": max_reasoning_tokens,
                "enable_reasoner": enable_reasoner,
                "reasoning": reasoning,
                "from_template": from_template,
                "template": template,
                "project": project,
                "tool_exec_environment_variables": tool_exec_environment_variables,
                "secrets": secrets,
                "memory_variables": memory_variables,
                "project_id": project_id,
                "template_id": template_id,
                "base_template_id": base_template_id,
                "identity_ids": identity_ids,
                "message_buffer_autoclear": message_buffer_autoclear,
                "enable_sleeptime": enable_sleeptime,
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=CreateAgentRequestResponseFormat, direction="write"
                ),
                "timezone": timezone,
                "max_files_open": max_files_open,
                "per_file_view_window_char_limit": per_file_view_window_char_limit,
                "hidden": hidden,
                "parallel_tool_calls": parallel_tool_calls,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentState,
                    construct_type(
                        type_=AgentState,  # 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 count(self, *, request_options: typing.Optional[RequestOptions] = None) -> AsyncHttpResponse[int]:
        """
        Get the total number of agents.

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

        Returns
        -------
        AsyncHttpResponse[int]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/agents/count",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    int,
                    construct_type(
                        type_=int,  # 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 export_file(
        self,
        agent_id: str,
        *,
        max_steps: typing.Optional[int] = None,
        use_legacy_format: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[str]:
        """
        Export the serialized JSON representation of an agent, formatted with indentation.

        Supports two export formats:
        - Legacy format (use_legacy_format=true): Single agent with inline tools/blocks
        - New format (default): Multi-entity format with separate agents, tools, blocks, files, etc.

        Parameters
        ----------
        agent_id : str
            The ID of the agent in the format 'agent-<uuid4>'

        max_steps : typing.Optional[int]

        use_legacy_format : typing.Optional[bool]
            If true, exports using the legacy single-agent format (v1). If false, exports using the new multi-entity format (v2).

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

        Returns
        -------
        AsyncHttpResponse[str]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}/export",
            method="GET",
            params={
                "max_steps": max_steps,
                "use_legacy_format": use_legacy_format,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    str,
                    construct_type(
                        type_=str,  # 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 import_file(
        self,
        *,
        file: core.File,
        override_embedding_model: typing.Optional[str] = None,
        append_copy_suffix: typing.Optional[bool] = OMIT,
        override_existing_tools: typing.Optional[bool] = OMIT,
        override_embedding_handle: typing.Optional[str] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        strip_messages: typing.Optional[bool] = OMIT,
        env_vars_json: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ImportedAgentsResponse]:
        """
        Import a serialized agent file and recreate the agent(s) in the system.
        Returns the IDs of all imported agents.

        Parameters
        ----------
        file : core.File
            See core.File for more documentation

        override_embedding_model : typing.Optional[str]

        append_copy_suffix : typing.Optional[bool]
            If set to True, appends "_copy" to the end of the agent name.

        override_existing_tools : typing.Optional[bool]
            If set to True, existing tools can get their source code overwritten by the uploaded tool definitions. Note that Letta core tools can never be updated externally.

        override_embedding_handle : typing.Optional[str]
            Override import with specific embedding handle.

        project_id : typing.Optional[str]
            The project ID to associate the uploaded agent with.

        strip_messages : typing.Optional[bool]
            If set to True, strips all messages from the agent before importing.

        env_vars_json : typing.Optional[str]
            Environment variables as a JSON string to pass to the agent for tool execution.

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

        Returns
        -------
        AsyncHttpResponse[ImportedAgentsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/agents/import",
            method="POST",
            data={
                "append_copy_suffix": append_copy_suffix,
                "override_existing_tools": override_existing_tools,
                "override_embedding_handle": override_embedding_handle,
                "project_id": project_id,
                "strip_messages": strip_messages,
                "env_vars_json": env_vars_json,
            },
            files={
                "file": file,
            },
            headers={
                "x-override-embedding-model": str(override_embedding_model)
                if override_embedding_model is not None
                else None,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ImportedAgentsResponse,
                    construct_type(
                        type_=ImportedAgentsResponse,  # 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 retrieve(
        self,
        agent_id: str,
        *,
        include_relationships: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentState]:
        """
        Get the state of the agent.

        Parameters
        ----------
        agent_id : str
            The ID of the agent in the format 'agent-<uuid4>'

        include_relationships : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Specify which relational fields (e.g., 'tools', 'sources', 'memory') to include in the response. If not provided, all relationships are loaded by default. Using this can optimize performance by reducing unnecessary joins.

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

        Returns
        -------
        AsyncHttpResponse[AgentState]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}",
            method="GET",
            params={
                "include_relationships": include_relationships,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentState,
                    construct_type(
                        type_=AgentState,  # 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, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Optional[typing.Any]]:
        """
        Delete an agent.

        Parameters
        ----------
        agent_id : str
            The ID of the agent in the format 'agent-<uuid4>'

        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)}",
            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,
        *,
        name: typing.Optional[str] = OMIT,
        tool_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        source_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        block_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        system: typing.Optional[str] = OMIT,
        tool_rules: typing.Optional[typing.Sequence[UpdateAgentToolRulesItem]] = OMIT,
        llm_config: typing.Optional[LlmConfig] = OMIT,
        embedding_config: typing.Optional[EmbeddingConfig] = OMIT,
        message_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        description: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        tool_exec_environment_variables: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        secrets: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        template_id: typing.Optional[str] = OMIT,
        base_template_id: typing.Optional[str] = OMIT,
        identity_ids: typing.Optional[typing.Sequence[str]] = OMIT,
        message_buffer_autoclear: typing.Optional[bool] = OMIT,
        model: typing.Optional[str] = OMIT,
        embedding: typing.Optional[str] = OMIT,
        reasoning: typing.Optional[bool] = OMIT,
        enable_sleeptime: typing.Optional[bool] = OMIT,
        response_format: typing.Optional[UpdateAgentResponseFormat] = OMIT,
        last_run_completion: typing.Optional[dt.datetime] = OMIT,
        last_run_duration_ms: typing.Optional[int] = OMIT,
        timezone: typing.Optional[str] = OMIT,
        max_files_open: typing.Optional[int] = OMIT,
        per_file_view_window_char_limit: typing.Optional[int] = OMIT,
        hidden: typing.Optional[bool] = OMIT,
        parallel_tool_calls: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentState]:
        """
        Update an existing agent.

        Parameters
        ----------
        agent_id : str
            The ID of the agent in the format 'agent-<uuid4>'

        name : typing.Optional[str]
            The name of the agent.

        tool_ids : typing.Optional[typing.Sequence[str]]
            The ids of the tools used by the agent.

        source_ids : typing.Optional[typing.Sequence[str]]
            The ids of the sources used by the agent.

        block_ids : typing.Optional[typing.Sequence[str]]
            The ids of the blocks used by the agent.

        tags : typing.Optional[typing.Sequence[str]]
            The tags associated with the agent.

        system : typing.Optional[str]
            The system prompt used by the agent.

        tool_rules : typing.Optional[typing.Sequence[UpdateAgentToolRulesItem]]
            The tool rules governing the agent.

        llm_config : typing.Optional[LlmConfig]
            The LLM configuration used by the agent.

        embedding_config : typing.Optional[EmbeddingConfig]
            The embedding configuration used by the agent.

        message_ids : typing.Optional[typing.Sequence[str]]
            The ids of the messages in the agent's in-context memory.

        description : typing.Optional[str]
            The description of the agent.

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            The metadata of the agent.

        tool_exec_environment_variables : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            Deprecated: use `secrets` field instead

        secrets : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            The environment variables for tool execution specific to this agent.

        project_id : typing.Optional[str]
            The id of the project the agent belongs to.

        template_id : typing.Optional[str]
            The id of the template the agent belongs to.

        base_template_id : typing.Optional[str]
            The base template id of the agent.

        identity_ids : typing.Optional[typing.Sequence[str]]
            The ids of the identities associated with this agent.

        message_buffer_autoclear : typing.Optional[bool]
            If set to True, the agent will not remember previous messages (though the agent will still retain state via core memory blocks and archival/recall memory). Not recommended unless you have an advanced use case.

        model : typing.Optional[str]
            The LLM configuration handle used by the agent, specified in the format provider/model-name, as an alternative to specifying llm_config.

        embedding : typing.Optional[str]
            The embedding configuration handle used by the agent, specified in the format provider/model-name.

        reasoning : typing.Optional[bool]
            Whether to enable reasoning for this agent.

        enable_sleeptime : typing.Optional[bool]
            If set to True, memory management will move to a background agent thread.

        response_format : typing.Optional[UpdateAgentResponseFormat]
            The response format for the agent.

        last_run_completion : typing.Optional[dt.datetime]
            The timestamp when the agent last completed a run.

        last_run_duration_ms : typing.Optional[int]
            The duration in milliseconds of the agent's last run.

        timezone : typing.Optional[str]
            The timezone of the agent (IANA format).

        max_files_open : typing.Optional[int]
            Maximum number of files that can be open at once for this agent. Setting this too high may exceed the context window, which will break the agent.

        per_file_view_window_char_limit : typing.Optional[int]
            The per-file view window character limit for this agent. Setting this too high may exceed the context window, which will break the agent.

        hidden : typing.Optional[bool]
            If set to True, the agent will be hidden.

        parallel_tool_calls : typing.Optional[bool]
            If set to True, enables parallel tool calling. Defaults to False.

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

        Returns
        -------
        AsyncHttpResponse[AgentState]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/agents/{jsonable_encoder(agent_id)}",
            method="PATCH",
            json={
                "name": name,
                "tool_ids": tool_ids,
                "source_ids": source_ids,
                "block_ids": block_ids,
                "tags": tags,
                "system": system,
                "tool_rules": convert_and_respect_annotation_metadata(
                    object_=tool_rules, annotation=typing.Sequence[UpdateAgentToolRulesItem], direction="write"
                ),
                "llm_config": convert_and_respect_annotation_metadata(
                    object_=llm_config, annotation=LlmConfig, direction="write"
                ),
                "embedding_config": convert_and_respect_annotation_metadata(
                    object_=embedding_config, annotation=EmbeddingConfig, direction="write"
                ),
                "message_ids": message_ids,
                "description": description,
                "metadata": metadata,
                "tool_exec_environment_variables": tool_exec_environment_variables,
                "secrets": secrets,
                "project_id": project_id,
                "template_id": template_id,
                "base_template_id": base_template_id,
                "identity_ids": identity_ids,
                "message_buffer_autoclear": message_buffer_autoclear,
                "model": model,
                "embedding": embedding,
                "reasoning": reasoning,
                "enable_sleeptime": enable_sleeptime,
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=UpdateAgentResponseFormat, direction="write"
                ),
                "last_run_completion": last_run_completion,
                "last_run_duration_ms": last_run_duration_ms,
                "timezone": timezone,
                "max_files_open": max_files_open,
                "per_file_view_window_char_limit": per_file_view_window_char_limit,
                "hidden": hidden,
                "parallel_tool_calls": parallel_tool_calls,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentState,
                    construct_type(
                        type_=AgentState,  # 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,
        *,
        search: typing.Optional[typing.Sequence[AgentsSearchRequestSearchItem]] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        combinator: typing.Optional[typing.Literal["AND"]] = OMIT,
        limit: typing.Optional[float] = OMIT,
        after: typing.Optional[str] = OMIT,
        sort_by: typing.Optional[AgentsSearchRequestSortBy] = OMIT,
        ascending: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AgentsSearchResponse]:
        """
        <Note>This endpoint is only available on Letta Cloud.</Note>

        Search deployed agents.

        Parameters
        ----------
        search : typing.Optional[typing.Sequence[AgentsSearchRequestSearchItem]]

        project_id : typing.Optional[str]

        combinator : typing.Optional[typing.Literal["AND"]]

        limit : typing.Optional[float]

        after : typing.Optional[str]

        sort_by : typing.Optional[AgentsSearchRequestSortBy]

        ascending : typing.Optional[bool]

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

        Returns
        -------
        AsyncHttpResponse[AgentsSearchResponse]
            200
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/agents/search",
            method="POST",
            json={
                "search": convert_and_respect_annotation_metadata(
                    object_=search, annotation=typing.Sequence[AgentsSearchRequestSearchItem], direction="write"
                ),
                "project_id": project_id,
                "combinator": combinator,
                "limit": limit,
                "after": after,
                "sortBy": sort_by,
                "ascending": ascending,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AgentsSearchResponse,
                    construct_type(
                        type_=AgentsSearchResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _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)
