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

import typing
from ..core.client_wrapper import SyncClientWrapper
from .. import core
from ..core.request_options import RequestOptions
from ..types.report_create_response import ReportCreateResponse
from ..core.pydantic_utilities import parse_obj_as
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.http_validation_error import HttpValidationError
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..types.report_state import ReportState
from ..types.paginated_report_response import PaginatedReportResponse
from ..types.report_response import ReportResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..types.report_metadata import ReportMetadata
from ..types.report import Report
from ..core.serialization import convert_and_respect_annotation_metadata
from ..types.report_plan import ReportPlan
from .types.action import Action
from ..types.report_event_item import ReportEventItem
from ..types.chat_message import ChatMessage
from ..types.edit_suggestion import EditSuggestion
from ..core.client_wrapper import AsyncClientWrapper

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


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

    def create_report(
        self,
        *,
        name: str,
        files: typing.List[core.File],
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        template_text: typing.Optional[str] = OMIT,
        template_instructions: typing.Optional[str] = OMIT,
        existing_retriever_id: typing.Optional[str] = OMIT,
        template_file: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportCreateResponse:
        """
        Create a new report.

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

        files : typing.List[core.File]
            See core.File for more documentation

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

        template_text : typing.Optional[str]

        template_instructions : typing.Optional[str]

        existing_retriever_id : typing.Optional[str]

        template_file : typing.Optional[str]

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

        Returns
        -------
        ReportCreateResponse
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.create_report(
            name="name",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/v1/reports/",
            method="POST",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            data={
                "name": name,
                "template_text": template_text,
                "template_instructions": template_instructions,
                "existing_retriever_id": existing_retriever_id,
                "template_file": template_file,
            },
            files={
                "files": files,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportCreateResponse,
                    parse_obj_as(
                        type_=ReportCreateResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def list_reports(
        self,
        *,
        state: typing.Optional[ReportState] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PaginatedReportResponse:
        """
        List all reports for a project.

        Parameters
        ----------
        state : typing.Optional[ReportState]

        limit : typing.Optional[int]

        offset : typing.Optional[int]

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        PaginatedReportResponse
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.list_reports()
        """
        _response = self._client_wrapper.httpx_client.request(
            "api/v1/reports/list",
            method="GET",
            params={
                "state": state,
                "limit": limit,
                "offset": offset,
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    PaginatedReportResponse,
                    parse_obj_as(
                        type_=PaginatedReportResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_report(
        self,
        report_id: str,
        *,
        version: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportResponse:
        """
        Get a specific report.

        Parameters
        ----------
        report_id : str

        version : typing.Optional[int]

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportResponse
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.get_report(
            report_id="report_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}",
            method="GET",
            params={
                "version": version,
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportResponse,
                    parse_obj_as(
                        type_=ReportResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_report_metadata(
        self,
        report_id: str,
        *,
        name: str,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportMetadata:
        """
        Update metadata for a report.

        Parameters
        ----------
        report_id : str

        name : str
            The name of the report

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportMetadata
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.update_report_metadata(
            report_id="report_id",
            name="name",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}",
            method="POST",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            json={
                "name": name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportMetadata,
                    parse_obj_as(
                        type_=ReportMetadata,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete_report(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Delete a report.

        Parameters
        ----------
        report_id : str

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.delete_report(
            report_id="report_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}",
            method="DELETE",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_report(
        self,
        report_id: str,
        *,
        content: Report,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportResponse:
        """
        Update a report's content.

        Parameters
        ----------
        report_id : str

        content : Report
            The content of the report version

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportResponse
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud, Report

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.update_report(
            report_id="report_id",
            content=Report(
                id="id",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}",
            method="PATCH",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            json={
                "content": convert_and_respect_annotation_metadata(
                    object_=content, annotation=Report, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportResponse,
                    parse_obj_as(
                        type_=ReportResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_report_plan(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportPlan:
        """
        Get the plan for a report.

        Parameters
        ----------
        report_id : str

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportPlan
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.get_report_plan(
            report_id="report_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/plan",
            method="GET",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportPlan,
                    parse_obj_as(
                        type_=ReportPlan,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_report_plan(
        self,
        report_id: str,
        *,
        action: Action,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request: typing.Optional[ReportPlan] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportResponse:
        """
        Update the plan of a report, including approval, rejection, and editing.

        Parameters
        ----------
        report_id : str

        action : Action

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

        request : typing.Optional[ReportPlan]

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

        Returns
        -------
        ReportResponse
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.update_report_plan(
            report_id="report_id",
            action="approve",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/plan",
            method="PATCH",
            params={
                "action": action,
                "project_id": project_id,
                "organization_id": organization_id,
            },
            json=convert_and_respect_annotation_metadata(object_=request, annotation=ReportPlan, direction="write"),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportResponse,
                    parse_obj_as(
                        type_=ReportResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_report_events(
        self,
        report_id: str,
        *,
        last_sequence: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[ReportEventItem]:
        """
        Get all historical events for a report.

        Parameters
        ----------
        report_id : str

        last_sequence : typing.Optional[int]

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        typing.List[ReportEventItem]
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.get_report_events(
            report_id="report_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/events",
            method="GET",
            params={
                "last_sequence": last_sequence,
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[ReportEventItem],
                    parse_obj_as(
                        type_=typing.List[ReportEventItem],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_report_metadata(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportMetadata:
        """
        Get metadata for a report.

        Parameters
        ----------
        report_id : str

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportMetadata
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.get_report_metadata(
            report_id="report_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/metadata",
            method="GET",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportMetadata,
                    parse_obj_as(
                        type_=ReportMetadata,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def suggest_edits_endpoint(
        self,
        report_id: str,
        *,
        user_query: str,
        chat_history: typing.Sequence[ChatMessage],
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[EditSuggestion]:
        """
        Suggest edits to a report based on user query and chat history.

        Parameters
        ----------
        report_id : str

        user_query : str

        chat_history : typing.Sequence[ChatMessage]

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        typing.List[EditSuggestion]
            Successful Response

        Examples
        --------
        from llama_index import ChatMessage, LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.suggest_edits_endpoint(
            report_id="report_id",
            user_query="user_query",
            chat_history=[ChatMessage()],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/suggest_edits",
            method="POST",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            json={
                "user_query": user_query,
                "chat_history": convert_and_respect_annotation_metadata(
                    object_=chat_history, annotation=typing.Sequence[ChatMessage], direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[EditSuggestion],
                    parse_obj_as(
                        type_=typing.List[EditSuggestion],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def restart_report(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Restart a report from scratch.

        Parameters
        ----------
        report_id : str

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from llama_index import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.restart_report(
            report_id="report_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/restart",
            method="POST",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncReportsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create_report(
        self,
        *,
        name: str,
        files: typing.List[core.File],
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        template_text: typing.Optional[str] = OMIT,
        template_instructions: typing.Optional[str] = OMIT,
        existing_retriever_id: typing.Optional[str] = OMIT,
        template_file: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportCreateResponse:
        """
        Create a new report.

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

        files : typing.List[core.File]
            See core.File for more documentation

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

        template_text : typing.Optional[str]

        template_instructions : typing.Optional[str]

        existing_retriever_id : typing.Optional[str]

        template_file : typing.Optional[str]

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

        Returns
        -------
        ReportCreateResponse
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.create_report(
                name="name",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/v1/reports/",
            method="POST",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            data={
                "name": name,
                "template_text": template_text,
                "template_instructions": template_instructions,
                "existing_retriever_id": existing_retriever_id,
                "template_file": template_file,
            },
            files={
                "files": files,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportCreateResponse,
                    parse_obj_as(
                        type_=ReportCreateResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def list_reports(
        self,
        *,
        state: typing.Optional[ReportState] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PaginatedReportResponse:
        """
        List all reports for a project.

        Parameters
        ----------
        state : typing.Optional[ReportState]

        limit : typing.Optional[int]

        offset : typing.Optional[int]

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        PaginatedReportResponse
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.list_reports()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "api/v1/reports/list",
            method="GET",
            params={
                "state": state,
                "limit": limit,
                "offset": offset,
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    PaginatedReportResponse,
                    parse_obj_as(
                        type_=PaginatedReportResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_report(
        self,
        report_id: str,
        *,
        version: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportResponse:
        """
        Get a specific report.

        Parameters
        ----------
        report_id : str

        version : typing.Optional[int]

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportResponse
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.get_report(
                report_id="report_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}",
            method="GET",
            params={
                "version": version,
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportResponse,
                    parse_obj_as(
                        type_=ReportResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_report_metadata(
        self,
        report_id: str,
        *,
        name: str,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportMetadata:
        """
        Update metadata for a report.

        Parameters
        ----------
        report_id : str

        name : str
            The name of the report

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportMetadata
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.update_report_metadata(
                report_id="report_id",
                name="name",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}",
            method="POST",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            json={
                "name": name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportMetadata,
                    parse_obj_as(
                        type_=ReportMetadata,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete_report(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Delete a report.

        Parameters
        ----------
        report_id : str

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.delete_report(
                report_id="report_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}",
            method="DELETE",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_report(
        self,
        report_id: str,
        *,
        content: Report,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportResponse:
        """
        Update a report's content.

        Parameters
        ----------
        report_id : str

        content : Report
            The content of the report version

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportResponse
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud, Report

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.update_report(
                report_id="report_id",
                content=Report(
                    id="id",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}",
            method="PATCH",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            json={
                "content": convert_and_respect_annotation_metadata(
                    object_=content, annotation=Report, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportResponse,
                    parse_obj_as(
                        type_=ReportResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_report_plan(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportPlan:
        """
        Get the plan for a report.

        Parameters
        ----------
        report_id : str

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportPlan
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.get_report_plan(
                report_id="report_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/plan",
            method="GET",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportPlan,
                    parse_obj_as(
                        type_=ReportPlan,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_report_plan(
        self,
        report_id: str,
        *,
        action: Action,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request: typing.Optional[ReportPlan] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportResponse:
        """
        Update the plan of a report, including approval, rejection, and editing.

        Parameters
        ----------
        report_id : str

        action : Action

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

        request : typing.Optional[ReportPlan]

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

        Returns
        -------
        ReportResponse
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.update_report_plan(
                report_id="report_id",
                action="approve",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/plan",
            method="PATCH",
            params={
                "action": action,
                "project_id": project_id,
                "organization_id": organization_id,
            },
            json=convert_and_respect_annotation_metadata(object_=request, annotation=ReportPlan, direction="write"),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportResponse,
                    parse_obj_as(
                        type_=ReportResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_report_events(
        self,
        report_id: str,
        *,
        last_sequence: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[ReportEventItem]:
        """
        Get all historical events for a report.

        Parameters
        ----------
        report_id : str

        last_sequence : typing.Optional[int]

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        typing.List[ReportEventItem]
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.get_report_events(
                report_id="report_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/events",
            method="GET",
            params={
                "last_sequence": last_sequence,
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[ReportEventItem],
                    parse_obj_as(
                        type_=typing.List[ReportEventItem],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_report_metadata(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ReportMetadata:
        """
        Get metadata for a report.

        Parameters
        ----------
        report_id : str

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        ReportMetadata
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.get_report_metadata(
                report_id="report_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/metadata",
            method="GET",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ReportMetadata,
                    parse_obj_as(
                        type_=ReportMetadata,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def suggest_edits_endpoint(
        self,
        report_id: str,
        *,
        user_query: str,
        chat_history: typing.Sequence[ChatMessage],
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[EditSuggestion]:
        """
        Suggest edits to a report based on user query and chat history.

        Parameters
        ----------
        report_id : str

        user_query : str

        chat_history : typing.Sequence[ChatMessage]

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        typing.List[EditSuggestion]
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud, ChatMessage

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.suggest_edits_endpoint(
                report_id="report_id",
                user_query="user_query",
                chat_history=[ChatMessage()],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/suggest_edits",
            method="POST",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            json={
                "user_query": user_query,
                "chat_history": convert_and_respect_annotation_metadata(
                    object_=chat_history, annotation=typing.Sequence[ChatMessage], direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[EditSuggestion],
                    parse_obj_as(
                        type_=typing.List[EditSuggestion],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def restart_report(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Restart a report from scratch.

        Parameters
        ----------
        report_id : str

        project_id : typing.Optional[str]

        organization_id : typing.Optional[str]

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

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from llama_index import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.reports.restart_report(
                report_id="report_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"api/v1/reports/{jsonable_encoder(report_id)}/restart",
            method="POST",
            params={
                "project_id": project_id,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
