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

import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.request_options import RequestOptions
from .prompts.client import AsyncPromptsClient, PromptsClient
from .raw_client import AsyncRawAgentClient, RawAgentClient
from .types.agent_chat_response import AgentChatResponse
from .types.agent_delete_response import AgentDeleteResponse
from .types.agent_fhir_config import AgentFhirConfig
from .types.agent_get_chat_messages_request_order import AgentGetChatMessagesRequestOrder
from .types.agent_get_chat_messages_response import AgentGetChatMessagesResponse
from .types.agent_list_response import AgentListResponse
from .types.agent_provider import AgentProvider
from .types.agent_response import AgentResponse
from .types.chat_fhir_client_config import ChatFhirClientConfig
from .types.json_patch import JsonPatch

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


class AgentClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawAgentClient(client_wrapper=client_wrapper)
        self.prompts = PromptsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawAgentClient
        """
        return self._raw_client

    def create(
        self,
        *,
        name: str,
        prompts: typing.Sequence[str],
        is_active: bool,
        description: typing.Optional[str] = OMIT,
        tools: typing.Optional[typing.Sequence[str]] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        provider: typing.Optional[AgentProvider] = OMIT,
        meta: typing.Optional[AgentFhirConfig] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentResponse:
        """
        Creates a new PhenoAgent with specified configuration

        Parameters
        ----------
        name : str
            Agent name

        prompts : typing.Sequence[str]
            Array of prompt IDs to use for this agent

        is_active : bool
            Whether the agent is active

        description : typing.Optional[str]
            Agent description

        tools : typing.Optional[typing.Sequence[str]]
            Array of MCP server tool IDs to use for this agent

        tags : typing.Optional[typing.Sequence[str]]
            Tags for categorizing the agent

        provider : typing.Optional[AgentProvider]
            FHIR provider type - can be a single provider or array of providers

        meta : typing.Optional[AgentFhirConfig]

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

        Returns
        -------
        AgentResponse
            Agent created successfully

        Examples
        --------
        from phenoml import phenoml

        client = phenoml(
            token="YOUR_TOKEN",
        )
        client.agent.create(
            name="name",
            prompts=["prompt_123", "prompt_456"],
            is_active=True,
        )
        """
        _response = self._raw_client.create(
            name=name,
            prompts=prompts,
            is_active=is_active,
            description=description,
            tools=tools,
            tags=tags,
            provider=provider,
            meta=meta,
            request_options=request_options,
        )
        return _response.data

    def list(
        self,
        *,
        is_active: typing.Optional[bool] = None,
        tags: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentListResponse:
        """
        Retrieves a list of PhenoAgents belonging to the authenticated user

        Parameters
        ----------
        is_active : typing.Optional[bool]
            Filter by active status

        tags : typing.Optional[str]
            Filter by tags

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

        Returns
        -------
        AgentListResponse
            Agents retrieved successfully

        Examples
        --------
        from phenoml import phenoml

        client = phenoml(
            token="YOUR_TOKEN",
        )
        client.agent.list()
        """
        _response = self._raw_client.list(is_active=is_active, tags=tags, request_options=request_options)
        return _response.data

    def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> AgentResponse:
        """
        Retrieves a specific agent by its ID

        Parameters
        ----------
        id : str
            Agent ID

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

        Returns
        -------
        AgentResponse
            Agent retrieved successfully

        Examples
        --------
        from phenoml import phenoml

        client = phenoml(
            token="YOUR_TOKEN",
        )
        client.agent.get(
            id="id",
        )
        """
        _response = self._raw_client.get(id, request_options=request_options)
        return _response.data

    def update(
        self,
        id: str,
        *,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        prompts: typing.Optional[typing.Sequence[str]] = OMIT,
        tools: typing.Optional[typing.Sequence[str]] = OMIT,
        is_active: typing.Optional[bool] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        provider: typing.Optional[AgentProvider] = OMIT,
        meta: typing.Optional[AgentFhirConfig] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentResponse:
        """
        Updates an existing agent's configuration

        Parameters
        ----------
        id : str
            Agent ID

        name : typing.Optional[str]
            Agent name

        description : typing.Optional[str]
            Agent description

        prompts : typing.Optional[typing.Sequence[str]]
            Array of prompt IDs to use for this agent

        tools : typing.Optional[typing.Sequence[str]]
            Array of MCP server tool IDs to use for this agent

        is_active : typing.Optional[bool]
            Whether the agent is active

        tags : typing.Optional[typing.Sequence[str]]
            Tags for categorizing the agent

        provider : typing.Optional[AgentProvider]
            FHIR provider type - can be a single provider or array of providers

        meta : typing.Optional[AgentFhirConfig]

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

        Returns
        -------
        AgentResponse
            Agent updated successfully

        Examples
        --------
        from phenoml import phenoml

        client = phenoml(
            token="YOUR_TOKEN",
        )
        client.agent.update(
            id="id",
        )
        """
        _response = self._raw_client.update(
            id,
            name=name,
            description=description,
            prompts=prompts,
            tools=tools,
            is_active=is_active,
            tags=tags,
            provider=provider,
            meta=meta,
            request_options=request_options,
        )
        return _response.data

    def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> AgentDeleteResponse:
        """
        Deletes an existing agent

        Parameters
        ----------
        id : str
            Agent ID

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

        Returns
        -------
        AgentDeleteResponse
            Agent deleted successfully

        Examples
        --------
        from phenoml import phenoml

        client = phenoml(
            token="YOUR_TOKEN",
        )
        client.agent.delete(
            id="id",
        )
        """
        _response = self._raw_client.delete(id, request_options=request_options)
        return _response.data

    def patch(
        self, id: str, *, request: JsonPatch, request_options: typing.Optional[RequestOptions] = None
    ) -> AgentResponse:
        """
        Patches an existing agent's configuration

        Parameters
        ----------
        id : str
            Agent ID

        request : JsonPatch

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

        Returns
        -------
        AgentResponse
            Agent patched successfully

        Examples
        --------
        from phenoml import phenoml
        from phenoml.agent import JsonPatchOperation

        client = phenoml(
            token="YOUR_TOKEN",
        )
        client.agent.patch(
            id="id",
            request=[
                JsonPatchOperation(
                    op="replace",
                    path="/name",
                    value="Updated Agent Name",
                ),
                JsonPatchOperation(
                    op="add",
                    path="/tags/-",
                    value="new-tag",
                ),
                JsonPatchOperation(
                    op="remove",
                    path="/description",
                ),
            ],
        )
        """
        _response = self._raw_client.patch(id, request=request, request_options=request_options)
        return _response.data

    def chat(
        self,
        *,
        message: str,
        agent_id: str,
        context: typing.Optional[str] = OMIT,
        session_id: typing.Optional[str] = OMIT,
        meta: typing.Optional[ChatFhirClientConfig] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentChatResponse:
        """
        Send a message to an agent and receive a response

        Parameters
        ----------
        message : str
            The message to send to the agent

        agent_id : str
            The ID of the agent to chat with

        context : typing.Optional[str]
            Optional context for the conversation

        session_id : typing.Optional[str]
            Optional session ID for conversation continuity

        meta : typing.Optional[ChatFhirClientConfig]
            Optional user-specific FHIR configuration overrides

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

        Returns
        -------
        AgentChatResponse
            Chat response received successfully

        Examples
        --------
        from phenoml import phenoml

        client = phenoml(
            token="YOUR_TOKEN",
        )
        client.agent.chat(
            message="What is the patient's current condition?",
            agent_id="agent-123",
        )
        """
        _response = self._raw_client.chat(
            message=message,
            agent_id=agent_id,
            context=context,
            session_id=session_id,
            meta=meta,
            request_options=request_options,
        )
        return _response.data

    def get_chat_messages(
        self,
        *,
        chat_session_id: str,
        num_messages: typing.Optional[int] = None,
        role: typing.Optional[str] = None,
        order: typing.Optional[AgentGetChatMessagesRequestOrder] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentGetChatMessagesResponse:
        """
        Retrieves a list of chat messages for a given chat session

        Parameters
        ----------
        chat_session_id : str
            Chat session ID

        num_messages : typing.Optional[int]
            Number of messages to return

        role : typing.Optional[str]
            Filter by role

        order : typing.Optional[AgentGetChatMessagesRequestOrder]
            Order of messages

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

        Returns
        -------
        AgentGetChatMessagesResponse
            Chat messages retrieved successfully

        Examples
        --------
        from phenoml import phenoml

        client = phenoml(
            token="YOUR_TOKEN",
        )
        client.agent.get_chat_messages(
            chat_session_id="chat_session_id",
        )
        """
        _response = self._raw_client.get_chat_messages(
            chat_session_id=chat_session_id,
            num_messages=num_messages,
            role=role,
            order=order,
            request_options=request_options,
        )
        return _response.data


class AsyncAgentClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawAgentClient(client_wrapper=client_wrapper)
        self.prompts = AsyncPromptsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawAgentClient
        """
        return self._raw_client

    async def create(
        self,
        *,
        name: str,
        prompts: typing.Sequence[str],
        is_active: bool,
        description: typing.Optional[str] = OMIT,
        tools: typing.Optional[typing.Sequence[str]] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        provider: typing.Optional[AgentProvider] = OMIT,
        meta: typing.Optional[AgentFhirConfig] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentResponse:
        """
        Creates a new PhenoAgent with specified configuration

        Parameters
        ----------
        name : str
            Agent name

        prompts : typing.Sequence[str]
            Array of prompt IDs to use for this agent

        is_active : bool
            Whether the agent is active

        description : typing.Optional[str]
            Agent description

        tools : typing.Optional[typing.Sequence[str]]
            Array of MCP server tool IDs to use for this agent

        tags : typing.Optional[typing.Sequence[str]]
            Tags for categorizing the agent

        provider : typing.Optional[AgentProvider]
            FHIR provider type - can be a single provider or array of providers

        meta : typing.Optional[AgentFhirConfig]

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

        Returns
        -------
        AgentResponse
            Agent created successfully

        Examples
        --------
        import asyncio

        from phenoml import Asyncphenoml

        client = Asyncphenoml(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.agent.create(
                name="name",
                prompts=["prompt_123", "prompt_456"],
                is_active=True,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create(
            name=name,
            prompts=prompts,
            is_active=is_active,
            description=description,
            tools=tools,
            tags=tags,
            provider=provider,
            meta=meta,
            request_options=request_options,
        )
        return _response.data

    async def list(
        self,
        *,
        is_active: typing.Optional[bool] = None,
        tags: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentListResponse:
        """
        Retrieves a list of PhenoAgents belonging to the authenticated user

        Parameters
        ----------
        is_active : typing.Optional[bool]
            Filter by active status

        tags : typing.Optional[str]
            Filter by tags

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

        Returns
        -------
        AgentListResponse
            Agents retrieved successfully

        Examples
        --------
        import asyncio

        from phenoml import Asyncphenoml

        client = Asyncphenoml(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.agent.list()


        asyncio.run(main())
        """
        _response = await self._raw_client.list(is_active=is_active, tags=tags, request_options=request_options)
        return _response.data

    async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> AgentResponse:
        """
        Retrieves a specific agent by its ID

        Parameters
        ----------
        id : str
            Agent ID

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

        Returns
        -------
        AgentResponse
            Agent retrieved successfully

        Examples
        --------
        import asyncio

        from phenoml import Asyncphenoml

        client = Asyncphenoml(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.agent.get(
                id="id",
            )


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

    async def update(
        self,
        id: str,
        *,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        prompts: typing.Optional[typing.Sequence[str]] = OMIT,
        tools: typing.Optional[typing.Sequence[str]] = OMIT,
        is_active: typing.Optional[bool] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        provider: typing.Optional[AgentProvider] = OMIT,
        meta: typing.Optional[AgentFhirConfig] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentResponse:
        """
        Updates an existing agent's configuration

        Parameters
        ----------
        id : str
            Agent ID

        name : typing.Optional[str]
            Agent name

        description : typing.Optional[str]
            Agent description

        prompts : typing.Optional[typing.Sequence[str]]
            Array of prompt IDs to use for this agent

        tools : typing.Optional[typing.Sequence[str]]
            Array of MCP server tool IDs to use for this agent

        is_active : typing.Optional[bool]
            Whether the agent is active

        tags : typing.Optional[typing.Sequence[str]]
            Tags for categorizing the agent

        provider : typing.Optional[AgentProvider]
            FHIR provider type - can be a single provider or array of providers

        meta : typing.Optional[AgentFhirConfig]

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

        Returns
        -------
        AgentResponse
            Agent updated successfully

        Examples
        --------
        import asyncio

        from phenoml import Asyncphenoml

        client = Asyncphenoml(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.agent.update(
                id="id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update(
            id,
            name=name,
            description=description,
            prompts=prompts,
            tools=tools,
            is_active=is_active,
            tags=tags,
            provider=provider,
            meta=meta,
            request_options=request_options,
        )
        return _response.data

    async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> AgentDeleteResponse:
        """
        Deletes an existing agent

        Parameters
        ----------
        id : str
            Agent ID

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

        Returns
        -------
        AgentDeleteResponse
            Agent deleted successfully

        Examples
        --------
        import asyncio

        from phenoml import Asyncphenoml

        client = Asyncphenoml(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.agent.delete(
                id="id",
            )


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

    async def patch(
        self, id: str, *, request: JsonPatch, request_options: typing.Optional[RequestOptions] = None
    ) -> AgentResponse:
        """
        Patches an existing agent's configuration

        Parameters
        ----------
        id : str
            Agent ID

        request : JsonPatch

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

        Returns
        -------
        AgentResponse
            Agent patched successfully

        Examples
        --------
        import asyncio

        from phenoml import Asyncphenoml
        from phenoml.agent import JsonPatchOperation

        client = Asyncphenoml(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.agent.patch(
                id="id",
                request=[
                    JsonPatchOperation(
                        op="replace",
                        path="/name",
                        value="Updated Agent Name",
                    ),
                    JsonPatchOperation(
                        op="add",
                        path="/tags/-",
                        value="new-tag",
                    ),
                    JsonPatchOperation(
                        op="remove",
                        path="/description",
                    ),
                ],
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.patch(id, request=request, request_options=request_options)
        return _response.data

    async def chat(
        self,
        *,
        message: str,
        agent_id: str,
        context: typing.Optional[str] = OMIT,
        session_id: typing.Optional[str] = OMIT,
        meta: typing.Optional[ChatFhirClientConfig] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentChatResponse:
        """
        Send a message to an agent and receive a response

        Parameters
        ----------
        message : str
            The message to send to the agent

        agent_id : str
            The ID of the agent to chat with

        context : typing.Optional[str]
            Optional context for the conversation

        session_id : typing.Optional[str]
            Optional session ID for conversation continuity

        meta : typing.Optional[ChatFhirClientConfig]
            Optional user-specific FHIR configuration overrides

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

        Returns
        -------
        AgentChatResponse
            Chat response received successfully

        Examples
        --------
        import asyncio

        from phenoml import Asyncphenoml

        client = Asyncphenoml(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.agent.chat(
                message="What is the patient's current condition?",
                agent_id="agent-123",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.chat(
            message=message,
            agent_id=agent_id,
            context=context,
            session_id=session_id,
            meta=meta,
            request_options=request_options,
        )
        return _response.data

    async def get_chat_messages(
        self,
        *,
        chat_session_id: str,
        num_messages: typing.Optional[int] = None,
        role: typing.Optional[str] = None,
        order: typing.Optional[AgentGetChatMessagesRequestOrder] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AgentGetChatMessagesResponse:
        """
        Retrieves a list of chat messages for a given chat session

        Parameters
        ----------
        chat_session_id : str
            Chat session ID

        num_messages : typing.Optional[int]
            Number of messages to return

        role : typing.Optional[str]
            Filter by role

        order : typing.Optional[AgentGetChatMessagesRequestOrder]
            Order of messages

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

        Returns
        -------
        AgentGetChatMessagesResponse
            Chat messages retrieved successfully

        Examples
        --------
        import asyncio

        from phenoml import Asyncphenoml

        client = Asyncphenoml(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.agent.get_chat_messages(
                chat_session_id="chat_session_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_chat_messages(
            chat_session_id=chat_session_id,
            num_messages=num_messages,
            role=role,
            order=order,
            request_options=request_options,
        )
        return _response.data
