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

import contextlib
import json
import typing
import uuid
from json.decoder import JSONDecodeError

import httpx_sse
from ..common.types.collaborator import Collaborator
from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from .types.configuration import Configuration
from .types.create_conversation_response import CreateConversationResponse
from .types.create_copilot_response import CreateCopilotResponse
from .types.delete_copilot_response import DeleteCopilotResponse
from .types.input_variable import InputVariable
from .types.message_feedback import MessageFeedback
from .types.send_agent_message_response import SendAgentMessageResponse
from .types.streaming_chunk import StreamingChunk

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


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

    def create_copilot(
        self,
        *,
        name: str,
        description: str,
        collaborators: typing.Sequence[Collaborator],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CreateCopilotResponse]:
        """
        Create a new agent. The API key used will be added to the agent for future Requests

        Parameters
        ----------
        name : str
            A descriptive name for the agent.

        description : str
            An in depth name for the agent's function. Useful for routing requests to the right agent.

        collaborators : typing.Sequence[Collaborator]
            A list of collaborator emails and roles that will have access to the agent.

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

        Returns
        -------
        HttpResponse[CreateCopilotResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/copilots/createCopilot",
            method="POST",
            json={
                "name": name,
                "description": description,
                "collaborators": convert_and_respect_annotation_metadata(
                    object_=collaborators, annotation=typing.Sequence[Collaborator], direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateCopilotResponse,
                    parse_obj_as(
                        type_=CreateCopilotResponse,  # 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)

    def create_conversation(
        self, *, agent_id: uuid.UUID, user_email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CreateConversationResponse]:
        """
        OPTIONAL. Create a new conversation with the Agent. The conversation ID can be used in the `sendMessage` endpoint. The `sendMessage` endpoint automatically creates new conversations upon first request, but calling this endpoint can simplify certain use cases where it is helpful for the application to have the conversation ID before the first message is sent.

        Parameters
        ----------
        agent_id : uuid.UUID
            Credal-generated Agent ID to specify which agent to route the request to.

        user_email : str
            End-user for the conversation.

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

        Returns
        -------
        HttpResponse[CreateConversationResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/copilots/createConversation",
            method="POST",
            json={
                "agentId": agent_id,
                "userEmail": user_email,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateConversationResponse,
                    parse_obj_as(
                        type_=CreateConversationResponse,  # 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)

    def provide_message_feedback(
        self,
        *,
        agent_id: uuid.UUID,
        user_email: str,
        message_id: uuid.UUID,
        message_feedback: MessageFeedback,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[None]:
        """
        Parameters
        ----------
        agent_id : uuid.UUID
            Credal-generated Agent ID to specify which agent to route the request to.

        user_email : str
            The user profile you want to use when providing feedback.

        message_id : uuid.UUID
            The message ID for which feedback is being provided.

        message_feedback : MessageFeedback
            The feedback provided by the user.

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/copilots/provideMessageFeedback",
            method="POST",
            json={
                "agentId": agent_id,
                "userEmail": user_email,
                "messageId": message_id,
                "messageFeedback": convert_and_respect_annotation_metadata(
                    object_=message_feedback, annotation=MessageFeedback, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def send_message(
        self,
        *,
        agent_id: uuid.UUID,
        message: str,
        user_email: str,
        conversation_id: typing.Optional[uuid.UUID] = OMIT,
        input_variables: typing.Optional[typing.Sequence[InputVariable]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[SendAgentMessageResponse]:
        """
        Parameters
        ----------
        agent_id : uuid.UUID
            Credal-generated Agent ID to specify which agent to route the request to.

        message : str
            The message you want to send to your agent.

        user_email : str
            The user profile you want to use when sending the message.

        conversation_id : typing.Optional[uuid.UUID]
            Credal-generated conversation ID for sending follow up messages. Conversation ID is returned after initial message. Optional, to be left off for first messages on new conversations.

        input_variables : typing.Optional[typing.Sequence[InputVariable]]
            Optional input variables to be used in the message. Map the name of the variable to a list of urls.

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

        Returns
        -------
        HttpResponse[SendAgentMessageResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/copilots/sendMessage",
            method="POST",
            json={
                "agentId": agent_id,
                "message": message,
                "userEmail": user_email,
                "conversationId": conversation_id,
                "inputVariables": convert_and_respect_annotation_metadata(
                    object_=input_variables, annotation=typing.Sequence[InputVariable], direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SendAgentMessageResponse,
                    parse_obj_as(
                        type_=SendAgentMessageResponse,  # 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)

    @contextlib.contextmanager
    def stream_message(
        self,
        *,
        copilot_id: uuid.UUID,
        message: str,
        email: str,
        conversation_id: typing.Optional[uuid.UUID] = OMIT,
        input_variables: typing.Optional[typing.Sequence[InputVariable]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[HttpResponse[typing.Iterator[StreamingChunk]]]:
        """
        This endpoint allows you to send a message to a specific agent and get the response back as a streamed set of Server-Sent Events.

        Parameters
        ----------
        copilot_id : uuid.UUID
            Credal-generated Agent ID to specify which agent to route the request to.

        message : str
            The message you want to send to your agent.

        email : str
            The user profile you want to use when sending the message.

        conversation_id : typing.Optional[uuid.UUID]
            Credal-generated conversation ID for sending follow up messages. Conversation ID is returned after initial message. Optional, to be left off for first messages on new conversations.

        input_variables : typing.Optional[typing.Sequence[InputVariable]]
            Optional input variables to be used in the message. Map the name of the variable to a list of urls.

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

        Yields
        ------
        typing.Iterator[HttpResponse[typing.Iterator[StreamingChunk]]]
            This endpoint returns a stream of server sent events. These can be in two formats - one is an initial event, followed by multiple data chunks, followed by a final chunk, or the other format is just one blocked event. See the examples for more details.
        """
        with self._client_wrapper.httpx_client.stream(
            "v0/copilots/streamMessage",
            method="POST",
            json={
                "copilotId": copilot_id,
                "message": message,
                "email": email,
                "conversationId": conversation_id,
                "inputVariables": convert_and_respect_annotation_metadata(
                    object_=input_variables, annotation=typing.Sequence[InputVariable], direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            def _stream() -> HttpResponse[typing.Iterator[StreamingChunk]]:
                try:
                    if 200 <= _response.status_code < 300:

                        def _iter():
                            _event_source = httpx_sse.EventSource(_response)
                            for _sse in _event_source.iter_sse():
                                if _sse.data == None:
                                    return
                                try:
                                    yield typing.cast(
                                        StreamingChunk,
                                        parse_obj_as(
                                            type_=StreamingChunk,  # type: ignore
                                            object_=json.loads(_sse.data),
                                        ),
                                    )
                                except Exception:
                                    pass
                            return

                        return HttpResponse(response=_response, data=_iter())
                    _response.read()
                    _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)

            yield _stream()

    def add_collection_to_copilot(
        self,
        *,
        copilot_id: uuid.UUID,
        collection_id: uuid.UUID,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[None]:
        """
        Link a collection with a agent. The API Key used must be added to both the collection and the agent beforehand.

        Parameters
        ----------
        copilot_id : uuid.UUID
            Credal-generated Agent ID to add the collection to.

        collection_id : uuid.UUID
            Credal-generated collection ID to add.

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/copilots/addCollectionToCopilot",
            method="POST",
            json={
                "copilotId": copilot_id,
                "collectionId": collection_id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def remove_collection_from_copilot(
        self,
        *,
        copilot_id: uuid.UUID,
        collection_id: uuid.UUID,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[None]:
        """
        Unlink a collection with a agent. The API Key used must be added to both the collection and the agent beforehand.

        Parameters
        ----------
        copilot_id : uuid.UUID
            Credal-generated agent ID to add the collection to.

        collection_id : uuid.UUID
            Credal-generated collection ID to add.

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/copilots/removeCollectionFromCopilot",
            method="POST",
            json={
                "copilotId": copilot_id,
                "collectionId": collection_id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update_configuration(
        self,
        *,
        copilot_id: uuid.UUID,
        configuration: Configuration,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[None]:
        """
        Update the configuration for a agent

        Parameters
        ----------
        copilot_id : uuid.UUID
            Credal-generated agent ID to add the collection to.

        configuration : Configuration

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

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/copilots/updateConfiguration",
            method="POST",
            json={
                "copilotId": copilot_id,
                "configuration": convert_and_respect_annotation_metadata(
                    object_=configuration, annotation=Configuration, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete_copilot(
        self, *, id: uuid.UUID, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[DeleteCopilotResponse]:
        """
        Parameters
        ----------
        id : uuid.UUID
            Copilot ID

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

        Returns
        -------
        HttpResponse[DeleteCopilotResponse]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/copilots/deleteCopilot",
            method="DELETE",
            json={
                "id": id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteCopilotResponse,
                    parse_obj_as(
                        type_=DeleteCopilotResponse,  # 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 AsyncRawCopilotsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create_copilot(
        self,
        *,
        name: str,
        description: str,
        collaborators: typing.Sequence[Collaborator],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CreateCopilotResponse]:
        """
        Create a new agent. The API key used will be added to the agent for future Requests

        Parameters
        ----------
        name : str
            A descriptive name for the agent.

        description : str
            An in depth name for the agent's function. Useful for routing requests to the right agent.

        collaborators : typing.Sequence[Collaborator]
            A list of collaborator emails and roles that will have access to the agent.

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

        Returns
        -------
        AsyncHttpResponse[CreateCopilotResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/copilots/createCopilot",
            method="POST",
            json={
                "name": name,
                "description": description,
                "collaborators": convert_and_respect_annotation_metadata(
                    object_=collaborators, annotation=typing.Sequence[Collaborator], direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateCopilotResponse,
                    parse_obj_as(
                        type_=CreateCopilotResponse,  # 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)

    async def create_conversation(
        self, *, agent_id: uuid.UUID, user_email: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CreateConversationResponse]:
        """
        OPTIONAL. Create a new conversation with the Agent. The conversation ID can be used in the `sendMessage` endpoint. The `sendMessage` endpoint automatically creates new conversations upon first request, but calling this endpoint can simplify certain use cases where it is helpful for the application to have the conversation ID before the first message is sent.

        Parameters
        ----------
        agent_id : uuid.UUID
            Credal-generated Agent ID to specify which agent to route the request to.

        user_email : str
            End-user for the conversation.

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

        Returns
        -------
        AsyncHttpResponse[CreateConversationResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/copilots/createConversation",
            method="POST",
            json={
                "agentId": agent_id,
                "userEmail": user_email,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateConversationResponse,
                    parse_obj_as(
                        type_=CreateConversationResponse,  # 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)

    async def provide_message_feedback(
        self,
        *,
        agent_id: uuid.UUID,
        user_email: str,
        message_id: uuid.UUID,
        message_feedback: MessageFeedback,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[None]:
        """
        Parameters
        ----------
        agent_id : uuid.UUID
            Credal-generated Agent ID to specify which agent to route the request to.

        user_email : str
            The user profile you want to use when providing feedback.

        message_id : uuid.UUID
            The message ID for which feedback is being provided.

        message_feedback : MessageFeedback
            The feedback provided by the user.

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/copilots/provideMessageFeedback",
            method="POST",
            json={
                "agentId": agent_id,
                "userEmail": user_email,
                "messageId": message_id,
                "messageFeedback": convert_and_respect_annotation_metadata(
                    object_=message_feedback, annotation=MessageFeedback, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def send_message(
        self,
        *,
        agent_id: uuid.UUID,
        message: str,
        user_email: str,
        conversation_id: typing.Optional[uuid.UUID] = OMIT,
        input_variables: typing.Optional[typing.Sequence[InputVariable]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[SendAgentMessageResponse]:
        """
        Parameters
        ----------
        agent_id : uuid.UUID
            Credal-generated Agent ID to specify which agent to route the request to.

        message : str
            The message you want to send to your agent.

        user_email : str
            The user profile you want to use when sending the message.

        conversation_id : typing.Optional[uuid.UUID]
            Credal-generated conversation ID for sending follow up messages. Conversation ID is returned after initial message. Optional, to be left off for first messages on new conversations.

        input_variables : typing.Optional[typing.Sequence[InputVariable]]
            Optional input variables to be used in the message. Map the name of the variable to a list of urls.

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

        Returns
        -------
        AsyncHttpResponse[SendAgentMessageResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/copilots/sendMessage",
            method="POST",
            json={
                "agentId": agent_id,
                "message": message,
                "userEmail": user_email,
                "conversationId": conversation_id,
                "inputVariables": convert_and_respect_annotation_metadata(
                    object_=input_variables, annotation=typing.Sequence[InputVariable], direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SendAgentMessageResponse,
                    parse_obj_as(
                        type_=SendAgentMessageResponse,  # 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)

    @contextlib.asynccontextmanager
    async def stream_message(
        self,
        *,
        copilot_id: uuid.UUID,
        message: str,
        email: str,
        conversation_id: typing.Optional[uuid.UUID] = OMIT,
        input_variables: typing.Optional[typing.Sequence[InputVariable]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[StreamingChunk]]]:
        """
        This endpoint allows you to send a message to a specific agent and get the response back as a streamed set of Server-Sent Events.

        Parameters
        ----------
        copilot_id : uuid.UUID
            Credal-generated Agent ID to specify which agent to route the request to.

        message : str
            The message you want to send to your agent.

        email : str
            The user profile you want to use when sending the message.

        conversation_id : typing.Optional[uuid.UUID]
            Credal-generated conversation ID for sending follow up messages. Conversation ID is returned after initial message. Optional, to be left off for first messages on new conversations.

        input_variables : typing.Optional[typing.Sequence[InputVariable]]
            Optional input variables to be used in the message. Map the name of the variable to a list of urls.

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

        Yields
        ------
        typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[StreamingChunk]]]
            This endpoint returns a stream of server sent events. These can be in two formats - one is an initial event, followed by multiple data chunks, followed by a final chunk, or the other format is just one blocked event. See the examples for more details.
        """
        async with self._client_wrapper.httpx_client.stream(
            "v0/copilots/streamMessage",
            method="POST",
            json={
                "copilotId": copilot_id,
                "message": message,
                "email": email,
                "conversationId": conversation_id,
                "inputVariables": convert_and_respect_annotation_metadata(
                    object_=input_variables, annotation=typing.Sequence[InputVariable], direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[StreamingChunk]]:
                try:
                    if 200 <= _response.status_code < 300:

                        async def _iter():
                            _event_source = httpx_sse.EventSource(_response)
                            async for _sse in _event_source.aiter_sse():
                                if _sse.data == None:
                                    return
                                try:
                                    yield typing.cast(
                                        StreamingChunk,
                                        parse_obj_as(
                                            type_=StreamingChunk,  # type: ignore
                                            object_=json.loads(_sse.data),
                                        ),
                                    )
                                except Exception:
                                    pass
                            return

                        return AsyncHttpResponse(response=_response, data=_iter())
                    await _response.aread()
                    _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)

            yield await _stream()

    async def add_collection_to_copilot(
        self,
        *,
        copilot_id: uuid.UUID,
        collection_id: uuid.UUID,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[None]:
        """
        Link a collection with a agent. The API Key used must be added to both the collection and the agent beforehand.

        Parameters
        ----------
        copilot_id : uuid.UUID
            Credal-generated Agent ID to add the collection to.

        collection_id : uuid.UUID
            Credal-generated collection ID to add.

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/copilots/addCollectionToCopilot",
            method="POST",
            json={
                "copilotId": copilot_id,
                "collectionId": collection_id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def remove_collection_from_copilot(
        self,
        *,
        copilot_id: uuid.UUID,
        collection_id: uuid.UUID,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[None]:
        """
        Unlink a collection with a agent. The API Key used must be added to both the collection and the agent beforehand.

        Parameters
        ----------
        copilot_id : uuid.UUID
            Credal-generated agent ID to add the collection to.

        collection_id : uuid.UUID
            Credal-generated collection ID to add.

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/copilots/removeCollectionFromCopilot",
            method="POST",
            json={
                "copilotId": copilot_id,
                "collectionId": collection_id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update_configuration(
        self,
        *,
        copilot_id: uuid.UUID,
        configuration: Configuration,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[None]:
        """
        Update the configuration for a agent

        Parameters
        ----------
        copilot_id : uuid.UUID
            Credal-generated agent ID to add the collection to.

        configuration : Configuration

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

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/copilots/updateConfiguration",
            method="POST",
            json={
                "copilotId": copilot_id,
                "configuration": convert_and_respect_annotation_metadata(
                    object_=configuration, annotation=Configuration, direction="write"
                ),
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete_copilot(
        self, *, id: uuid.UUID, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[DeleteCopilotResponse]:
        """
        Parameters
        ----------
        id : uuid.UUID
            Copilot ID

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

        Returns
        -------
        AsyncHttpResponse[DeleteCopilotResponse]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/copilots/deleteCopilot",
            method="DELETE",
            json={
                "id": id,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteCopilotResponse,
                    parse_obj_as(
                        type_=DeleteCopilotResponse,  # 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)
