diff --git a/robosystems_client/api/operations/resume_operation.py b/robosystems_client/api/operations/resume_operation.py new file mode 100644 index 0000000..355d07e --- /dev/null +++ b/robosystems_client/api/operations/resume_operation.py @@ -0,0 +1,263 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error_response import ErrorResponse +from ...models.http_validation_error import HTTPValidationError +from ...models.operation_resume_request import OperationResumeRequest +from ...models.resume_operation_response_resumeoperation import ( + ResumeOperationResponseResumeoperation, +) +from ...types import Response + + +def _get_kwargs( + operation_id: str, + *, + body: OperationResumeRequest, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "post", + "url": "/v1/operations/{operation_id}/resume".format( + operation_id=quote(str(operation_id), safe=""), + ), + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> ( + Any + | ErrorResponse + | HTTPValidationError + | ResumeOperationResponseResumeoperation + | None +): + if response.status_code == 202: + response_202 = ResumeOperationResponseResumeoperation.from_dict(response.json()) + + return response_202 + + if response.status_code == 400: + response_400 = ErrorResponse.from_dict(response.json()) + + return response_400 + + if response.status_code == 401: + response_401 = ErrorResponse.from_dict(response.json()) + + return response_401 + + if response.status_code == 403: + response_403 = ErrorResponse.from_dict(response.json()) + + return response_403 + + if response.status_code == 404: + response_404 = ErrorResponse.from_dict(response.json()) + + return response_404 + + if response.status_code == 409: + response_409 = cast(Any, None) + return response_409 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 429: + response_429 = ErrorResponse.from_dict(response.json()) + + return response_429 + + if response.status_code == 500: + response_500 = ErrorResponse.from_dict(response.json()) + + return response_500 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Response[ + Any | ErrorResponse | HTTPValidationError | ResumeOperationResponseResumeoperation +]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + operation_id: str, + *, + client: AuthenticatedClient, + body: OperationResumeRequest, +) -> Response[ + Any | ErrorResponse | HTTPValidationError | ResumeOperationResponseResumeoperation +]: + """Resume Operation + + Answers an operation that paused at a checkpoint (status `awaiting_input`) and puts it back on the + worker queue with the answer. The operation keeps its id, so the stream, status and cancel links + stay valid; reconnect to `/stream` to follow the resumed run. Consumes no credits. + + Args: + operation_id (str): Operation identifier + body (OperationResumeRequest): Answer for an operation paused at a checkpoint + (`awaiting_input`). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any | ErrorResponse | HTTPValidationError | ResumeOperationResponseResumeoperation] + """ + + kwargs = _get_kwargs( + operation_id=operation_id, + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + operation_id: str, + *, + client: AuthenticatedClient, + body: OperationResumeRequest, +) -> ( + Any + | ErrorResponse + | HTTPValidationError + | ResumeOperationResponseResumeoperation + | None +): + """Resume Operation + + Answers an operation that paused at a checkpoint (status `awaiting_input`) and puts it back on the + worker queue with the answer. The operation keeps its id, so the stream, status and cancel links + stay valid; reconnect to `/stream` to follow the resumed run. Consumes no credits. + + Args: + operation_id (str): Operation identifier + body (OperationResumeRequest): Answer for an operation paused at a checkpoint + (`awaiting_input`). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Any | ErrorResponse | HTTPValidationError | ResumeOperationResponseResumeoperation + """ + + return sync_detailed( + operation_id=operation_id, + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + operation_id: str, + *, + client: AuthenticatedClient, + body: OperationResumeRequest, +) -> Response[ + Any | ErrorResponse | HTTPValidationError | ResumeOperationResponseResumeoperation +]: + """Resume Operation + + Answers an operation that paused at a checkpoint (status `awaiting_input`) and puts it back on the + worker queue with the answer. The operation keeps its id, so the stream, status and cancel links + stay valid; reconnect to `/stream` to follow the resumed run. Consumes no credits. + + Args: + operation_id (str): Operation identifier + body (OperationResumeRequest): Answer for an operation paused at a checkpoint + (`awaiting_input`). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any | ErrorResponse | HTTPValidationError | ResumeOperationResponseResumeoperation] + """ + + kwargs = _get_kwargs( + operation_id=operation_id, + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + operation_id: str, + *, + client: AuthenticatedClient, + body: OperationResumeRequest, +) -> ( + Any + | ErrorResponse + | HTTPValidationError + | ResumeOperationResponseResumeoperation + | None +): + """Resume Operation + + Answers an operation that paused at a checkpoint (status `awaiting_input`) and puts it back on the + worker queue with the answer. The operation keeps its id, so the stream, status and cancel links + stay valid; reconnect to `/stream` to follow the resumed run. Consumes no credits. + + Args: + operation_id (str): Operation identifier + body (OperationResumeRequest): Answer for an operation paused at a checkpoint + (`awaiting_input`). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Any | ErrorResponse | HTTPValidationError | ResumeOperationResponseResumeoperation + """ + + return ( + await asyncio_detailed( + operation_id=operation_id, + client=client, + body=body, + ) + ).parsed diff --git a/robosystems_client/api/operator/auto_select_operator.py b/robosystems_client/api/operator/auto_select_operator.py index b3141dc..9c73c08 100644 --- a/robosystems_client/api/operator/auto_select_operator.py +++ b/robosystems_client/api/operator/auto_select_operator.py @@ -132,12 +132,16 @@ def sync_detailed( by querying the graph; supports `quick`, `standard`, `extended`) and `mapping` (autonomous Chart of Accounts → rs-gaap mapping; roboledger graphs only, `extended` only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. Credits are consumed by actual token - usage, not a fixed price per mode. Execution strategy (sync/SSE/async) auto-selected; override with - `?mode=sync|async`. + usage, not a fixed price per mode. The run executes on the background worker: the default answer is + 202 with the operation's `_links` (stream, status, cancel); `?mode=sync` waits up to 50s and answers + 200 with the result. Args: graph_id (str): - mode (None | ResponseMode | Unset): Override execution mode: sync, async, stream, or auto + mode (None | ResponseMode | Unset): `sync` waits up to 50s for the answer and returns 200 + with it (202 with the operation links if the worker is still busy). Anything else — + `async`, `stream`, `auto` or unset — queues the run and returns 202; follow + `_links.stream` for progress and the result. body (OperatorRequest): Request model for operator interactions. Raises: @@ -174,12 +178,16 @@ def sync( by querying the graph; supports `quick`, `standard`, `extended`) and `mapping` (autonomous Chart of Accounts → rs-gaap mapping; roboledger graphs only, `extended` only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. Credits are consumed by actual token - usage, not a fixed price per mode. Execution strategy (sync/SSE/async) auto-selected; override with - `?mode=sync|async`. + usage, not a fixed price per mode. The run executes on the background worker: the default answer is + 202 with the operation's `_links` (stream, status, cancel); `?mode=sync` waits up to 50s and answers + 200 with the result. Args: graph_id (str): - mode (None | ResponseMode | Unset): Override execution mode: sync, async, stream, or auto + mode (None | ResponseMode | Unset): `sync` waits up to 50s for the answer and returns 200 + with it (202 with the operation links if the worker is still busy). Anything else — + `async`, `stream`, `auto` or unset — queues the run and returns 202; follow + `_links.stream` for progress and the result. body (OperatorRequest): Request model for operator interactions. Raises: @@ -211,12 +219,16 @@ async def asyncio_detailed( by querying the graph; supports `quick`, `standard`, `extended`) and `mapping` (autonomous Chart of Accounts → rs-gaap mapping; roboledger graphs only, `extended` only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. Credits are consumed by actual token - usage, not a fixed price per mode. Execution strategy (sync/SSE/async) auto-selected; override with - `?mode=sync|async`. + usage, not a fixed price per mode. The run executes on the background worker: the default answer is + 202 with the operation's `_links` (stream, status, cancel); `?mode=sync` waits up to 50s and answers + 200 with the result. Args: graph_id (str): - mode (None | ResponseMode | Unset): Override execution mode: sync, async, stream, or auto + mode (None | ResponseMode | Unset): `sync` waits up to 50s for the answer and returns 200 + with it (202 with the operation links if the worker is still busy). Anything else — + `async`, `stream`, `auto` or unset — queues the run and returns 202; follow + `_links.stream` for progress and the result. body (OperatorRequest): Request model for operator interactions. Raises: @@ -251,12 +263,16 @@ async def asyncio( by querying the graph; supports `quick`, `standard`, `extended`) and `mapping` (autonomous Chart of Accounts → rs-gaap mapping; roboledger graphs only, `extended` only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. Credits are consumed by actual token - usage, not a fixed price per mode. Execution strategy (sync/SSE/async) auto-selected; override with - `?mode=sync|async`. + usage, not a fixed price per mode. The run executes on the background worker: the default answer is + 202 with the operation's `_links` (stream, status, cancel); `?mode=sync` waits up to 50s and answers + 200 with the result. Args: graph_id (str): - mode (None | ResponseMode | Unset): Override execution mode: sync, async, stream, or auto + mode (None | ResponseMode | Unset): `sync` waits up to 50s for the answer and returns 200 + with it (202 with the operation links if the worker is still busy). Anything else — + `async`, `stream`, `auto` or unset — queues the run and returns 202; follow + `_links.stream` for progress and the result. body (OperatorRequest): Request model for operator interactions. Raises: diff --git a/robosystems_client/api/operator/execute_specific_operator.py b/robosystems_client/api/operator/execute_specific_operator.py index 01a49f2..1c0ff25 100644 --- a/robosystems_client/api/operator/execute_specific_operator.py +++ b/robosystems_client/api/operator/execute_specific_operator.py @@ -133,13 +133,17 @@ def sync_detailed( Available: `cypher` (natural-language questions answered by querying the graph; RAG retrieval is one of its capabilities, not a separate operator) and `mapping` (Chart of Accounts → rs-gaap mapping, - roboledger graphs only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. Execution - strategy auto-selected; override with `?mode=sync|async`. + roboledger graphs only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. The run + executes on the background worker: the default answer is 202 with the operation's `_links` (stream, + status, cancel); `?mode=sync` waits up to 50s and answers 200 with the result. Args: graph_id (str): operator_type (str): - mode (None | ResponseMode | Unset): Override execution mode: sync, async, stream, or auto + mode (None | ResponseMode | Unset): `sync` waits up to 50s for the answer and returns 200 + with it (202 with the operation links if the worker is still busy). Anything else — + `async`, `stream`, `auto` or unset — queues the run and returns 202; follow + `_links.stream` for progress and the result. body (OperatorRequest): Request model for operator interactions. Raises: @@ -176,13 +180,17 @@ def sync( Available: `cypher` (natural-language questions answered by querying the graph; RAG retrieval is one of its capabilities, not a separate operator) and `mapping` (Chart of Accounts → rs-gaap mapping, - roboledger graphs only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. Execution - strategy auto-selected; override with `?mode=sync|async`. + roboledger graphs only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. The run + executes on the background worker: the default answer is 202 with the operation's `_links` (stream, + status, cancel); `?mode=sync` waits up to 50s and answers 200 with the result. Args: graph_id (str): operator_type (str): - mode (None | ResponseMode | Unset): Override execution mode: sync, async, stream, or auto + mode (None | ResponseMode | Unset): `sync` waits up to 50s for the answer and returns 200 + with it (202 with the operation links if the worker is still busy). Anything else — + `async`, `stream`, `auto` or unset — queues the run and returns 202; follow + `_links.stream` for progress and the result. body (OperatorRequest): Request model for operator interactions. Raises: @@ -214,13 +222,17 @@ async def asyncio_detailed( Available: `cypher` (natural-language questions answered by querying the graph; RAG retrieval is one of its capabilities, not a separate operator) and `mapping` (Chart of Accounts → rs-gaap mapping, - roboledger graphs only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. Execution - strategy auto-selected; override with `?mode=sync|async`. + roboledger graphs only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. The run + executes on the background worker: the default answer is 202 with the operation's `_links` (stream, + status, cancel); `?mode=sync` waits up to 50s and answers 200 with the result. Args: graph_id (str): operator_type (str): - mode (None | ResponseMode | Unset): Override execution mode: sync, async, stream, or auto + mode (None | ResponseMode | Unset): `sync` waits up to 50s for the answer and returns 200 + with it (202 with the operation links if the worker is still busy). Anything else — + `async`, `stream`, `auto` or unset — queues the run and returns 202; follow + `_links.stream` for progress and the result. body (OperatorRequest): Request model for operator interactions. Raises: @@ -255,13 +267,17 @@ async def asyncio( Available: `cypher` (natural-language questions answered by querying the graph; RAG retrieval is one of its capabilities, not a separate operator) and `mapping` (Chart of Accounts → rs-gaap mapping, - roboledger graphs only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. Execution - strategy auto-selected; override with `?mode=sync|async`. + roboledger graphs only). `GET /v1/graphs/{graph_id}/operator` lists what is registered. The run + executes on the background worker: the default answer is 202 with the operation's `_links` (stream, + status, cancel); `?mode=sync` waits up to 50s and answers 200 with the result. Args: graph_id (str): operator_type (str): - mode (None | ResponseMode | Unset): Override execution mode: sync, async, stream, or auto + mode (None | ResponseMode | Unset): `sync` waits up to 50s for the answer and returns 200 + with it (202 with the operation links if the worker is still busy). Anything else — + `async`, `stream`, `auto` or unset — queues the run and returns 202; follow + `_links.stream` for progress and the result. body (OperatorRequest): Request model for operator interactions. Raises: diff --git a/robosystems_client/graphql/schema.graphql b/robosystems_client/graphql/schema.graphql index 013a44b..f29d262 100644 --- a/robosystems_client/graphql/schema.graphql +++ b/robosystems_client/graphql/schema.graphql @@ -2001,6 +2001,7 @@ envelope-build time — accounting equation, totals foot, etc. """ type InformationBlockValidation { passed: Boolean! + status: String! checks: [String!]! failures: [String!]! warnings: [String!]! @@ -2085,6 +2086,11 @@ type ReportBundleDownload { """Bundle generation number stamped on the Report.""" generationCount: Int! + + """ + Content the Report carries that this flavor does not. ``disclosure_notes``: the XBRL 2.1 zip ships statements only — tenant-authored disclosure notes render on screen and ride the JSON-LD and holon flavors, but are excluded from this file. + """ + omittedContent: [String!]! } enum ReportDownloadFormat { @@ -2165,11 +2171,24 @@ type FactRow { depth: Int! } -"""Aggregate result of running reporting rules over a structure.""" +""" +Aggregate result of running reporting rules over a structure. + +Every rule runs once per rendered period column; on a multi-column +statement each failure and warning is prefixed with the column it was +found in (``[Prior] …``). +""" type ValidationCheck { - """True iff every rule produced zero failures.""" + """ + True iff at least one rule ran and every rule produced zero failures on every rendered column. False when nothing was checked (`status == 'inconclusive'`). + """ passed: Boolean! + """ + `passed` — every rule ran on every column with zero failures; `failed` — at least one rule failed; `inconclusive` — no validation rules exist for this block type, so nothing was checked. + """ + status: String! + """Names of rules that were evaluated.""" checks: [String!]! diff --git a/robosystems_client/models/__init__.py b/robosystems_client/models/__init__.py index 49ae413..88f9c24 100644 --- a/robosystems_client/models/__init__.py +++ b/robosystems_client/models/__init__.py @@ -618,6 +618,8 @@ ) from .operation_error import OperationError from .operation_error_detail_type_1 import OperationErrorDetailType1 +from .operation_resume_request import OperationResumeRequest +from .operation_resume_request_input import OperationResumeRequestInput from .operator_list_response import OperatorListResponse from .operator_list_response_operators import OperatorListResponseOperators from .operator_list_response_operators_additional_property import ( @@ -741,6 +743,9 @@ ) from .resolved_report_info import ResolvedReportInfo from .response_mode import ResponseMode +from .resume_operation_response_resumeoperation import ( + ResumeOperationResponseResumeoperation, +) from .revoke_report_share_operation import RevokeReportShareOperation from .revoke_report_share_response import RevokeReportShareResponse from .rollforward_mechanics import RollforwardMechanics @@ -931,6 +936,7 @@ from .upgrade_subscription_request import UpgradeSubscriptionRequest from .user_graphs_response import UserGraphsResponse from .user_response import UserResponse +from .validation_check_response import ValidationCheckResponse from .validation_error import ValidationError from .validation_error_context import ValidationErrorContext from .validation_lite import ValidationLite @@ -1345,6 +1351,8 @@ "OperationEnvelopeViewResponseStatus", "OperationError", "OperationErrorDetailType1", + "OperationResumeRequest", + "OperationResumeRequestInput", "OperatorListResponse", "OperatorListResponseOperators", "OperatorListResponseOperatorsAdditionalProperty", @@ -1450,6 +1458,7 @@ "ResolveReconcilingItemResponse", "ResolveReconcilingItemResponseDisposition", "ResponseMode", + "ResumeOperationResponseResumeoperation", "RevokeReportShareOperation", "RevokeReportShareResponse", "RollforwardMechanics", @@ -1592,6 +1601,7 @@ "UpgradeSubscriptionRequest", "UserGraphsResponse", "UserResponse", + "ValidationCheckResponse", "ValidationError", "ValidationErrorContext", "ValidationLite", diff --git a/robosystems_client/models/element_summary.py b/robosystems_client/models/element_summary.py index 9182591..51527b0 100644 --- a/robosystems_client/models/element_summary.py +++ b/robosystems_client/models/element_summary.py @@ -1,11 +1,13 @@ from __future__ import annotations from collections.abc import Mapping -from typing import Any, TypeVar +from typing import Any, TypeVar, cast from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..types import UNSET, Unset + T = TypeVar("T", bound="ElementSummary") @@ -14,41 +16,53 @@ class ElementSummary: """ Attributes: count (int): Number of facts for this element - total (float): Sum of values across the returned facts - average (float): Mean value across the returned facts min_ (float): Minimum value across the returned facts max_ (float): Maximum value across the returned facts + total (float | None | Unset): Sum of values across the returned facts. Duration elements only — a balance summed + across periods is not a balance, so instants omit it. + average (float | None | Unset): Mean value across the returned facts. Duration elements only; omitted for + instants. """ count: int - total: float - average: float min_: float max_: float + total: float | None | Unset = UNSET + average: float | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: count = self.count - total = self.total - - average = self.average - min_ = self.min_ max_ = self.max_ + total: float | None | Unset + if isinstance(self.total, Unset): + total = UNSET + else: + total = self.total + + average: float | None | Unset + if isinstance(self.average, Unset): + average = UNSET + else: + average = self.average + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( { "count": count, - "total": total, - "average": average, "min": min_, "max": max_, } ) + if total is not UNSET: + field_dict["total"] = total + if average is not UNSET: + field_dict["average"] = average return field_dict @@ -57,20 +71,34 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: d = dict(src_dict) count = d.pop("count") - total = d.pop("total") - - average = d.pop("average") - min_ = d.pop("min") max_ = d.pop("max") + def _parse_total(data: object) -> float | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(float | None | Unset, data) + + total = _parse_total(d.pop("total", UNSET)) + + def _parse_average(data: object) -> float | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(float | None | Unset, data) + + average = _parse_average(d.pop("average", UNSET)) + element_summary = cls( count=count, - total=total, - average=average, min_=min_, max_=max_, + total=total, + average=average, ) element_summary.additional_properties = d diff --git a/robosystems_client/models/financial_statement_analysis_request.py b/robosystems_client/models/financial_statement_analysis_request.py index 022a66c..05e744a 100644 --- a/robosystems_client/models/financial_statement_analysis_request.py +++ b/robosystems_client/models/financial_statement_analysis_request.py @@ -22,7 +22,7 @@ class FinancialStatementAnalysisRequest: filters. fiscal_year (int | None | Unset): Filter by fiscal year focus when auto-resolving the report period_type (None | str | Unset): annual | quarterly | instant - limit (int | Unset): Default: 50. + limit (int | Unset): Default: 1000. """ statement_type: str @@ -30,7 +30,7 @@ class FinancialStatementAnalysisRequest: report_id: None | str | Unset = UNSET fiscal_year: int | None | Unset = UNSET period_type: None | str | Unset = UNSET - limit: int | Unset = 50 + limit: int | Unset = 1000 additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: diff --git a/robosystems_client/models/live_financial_statement_request.py b/robosystems_client/models/live_financial_statement_request.py index 0abc03e..5fa90c5 100644 --- a/robosystems_client/models/live_financial_statement_request.py +++ b/robosystems_client/models/live_financial_statement_request.py @@ -17,12 +17,15 @@ class LiveFinancialStatementRequest: """Request for live-financial-statement (OLTP, entity graphs only). Attributes: - statement_type (str): income_statement | balance_sheet | cash_flow_statement | equity_statement + statement_type (str): income_statement | balance_sheet | cash_flow_statement | equity_statement. + ``equity_statement`` is provisional — equity balances, not a rollforward — and is not offered on the MCP surface + until it articulates. period_start (datetime.date | None | Unset): Explicit window start. Overrides period_type/fiscal_year. period_end (datetime.date | None | Unset): Explicit window end. Overrides period_type/fiscal_year. period_type (None | str | Unset): annual | quarterly | instant (ignored when dates supplied) fiscal_year (int | None | Unset): Fiscal year for annual window (anchored on FiscalCalendar) - limit (int | Unset): Max fact rows returned Default: 50. + limit (int | Unset): Max fact rows returned. Defaults to the ceiling so a statement is never cut mid-section — + visible rows would stop footing to visible subtotals. Lower it only for a preview. Default: 1000. """ statement_type: str @@ -30,7 +33,7 @@ class LiveFinancialStatementRequest: period_end: datetime.date | None | Unset = UNSET period_type: None | str | Unset = UNSET fiscal_year: int | None | Unset = UNSET - limit: int | Unset = 50 + limit: int | Unset = 1000 additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: diff --git a/robosystems_client/models/live_financial_statement_response.py b/robosystems_client/models/live_financial_statement_response.py index c8923e4..b85590e 100644 --- a/robosystems_client/models/live_financial_statement_response.py +++ b/robosystems_client/models/live_financial_statement_response.py @@ -1,7 +1,7 @@ from __future__ import annotations from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar, cast from attrs import define as _attrs_define from attrs import field as _attrs_field @@ -11,6 +11,7 @@ if TYPE_CHECKING: from ..models.live_statement_fact_row import LiveStatementFactRow from ..models.period_spec import PeriodSpec + from ..models.validation_check_response import ValidationCheckResponse T = TypeVar("T", bound="LiveFinancialStatementResponse") @@ -23,9 +24,13 @@ class LiveFinancialStatementResponse: Attributes: graph_id (str): statement_type (str): - periods (list[PeriodSpec]): + periods (list[PeriodSpec]): Rendered columns, aligned with each row's ``values``. Current and prior for + income_statement and balance_sheet; current only for cash_flow_statement — the prior period is pivoted as the + indirect-method delta basis and not rendered. facts (list[LiveStatementFactRow]): fact_count (int): + validation (None | Unset | ValidationCheckResponse): Guard-rail outcome for the rendered columns — accounting + equation, net-income equation, totals footing, operating-plug size. Null only when no structure rendered. unmapped_count (int | Unset): Default: 0. truncated (bool | Unset): Default: False. """ @@ -35,11 +40,14 @@ class LiveFinancialStatementResponse: periods: list[PeriodSpec] facts: list[LiveStatementFactRow] fact_count: int + validation: None | Unset | ValidationCheckResponse = UNSET unmapped_count: int | Unset = 0 truncated: bool | Unset = False additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: + from ..models.validation_check_response import ValidationCheckResponse + graph_id = self.graph_id statement_type = self.statement_type @@ -56,6 +64,14 @@ def to_dict(self) -> dict[str, Any]: fact_count = self.fact_count + validation: dict[str, Any] | None | Unset + if isinstance(self.validation, Unset): + validation = UNSET + elif isinstance(self.validation, ValidationCheckResponse): + validation = self.validation.to_dict() + else: + validation = self.validation + unmapped_count = self.unmapped_count truncated = self.truncated @@ -71,6 +87,8 @@ def to_dict(self) -> dict[str, Any]: "fact_count": fact_count, } ) + if validation is not UNSET: + field_dict["validation"] = validation if unmapped_count is not UNSET: field_dict["unmapped_count"] = unmapped_count if truncated is not UNSET: @@ -82,6 +100,7 @@ def to_dict(self) -> dict[str, Any]: def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: from ..models.live_statement_fact_row import LiveStatementFactRow from ..models.period_spec import PeriodSpec + from ..models.validation_check_response import ValidationCheckResponse d = dict(src_dict) graph_id = d.pop("graph_id") @@ -104,6 +123,23 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: fact_count = d.pop("fact_count") + def _parse_validation(data: object) -> None | Unset | ValidationCheckResponse: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + validation_type_0 = ValidationCheckResponse.from_dict(data) + + return validation_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | Unset | ValidationCheckResponse, data) + + validation = _parse_validation(d.pop("validation", UNSET)) + unmapped_count = d.pop("unmapped_count", UNSET) truncated = d.pop("truncated", UNSET) @@ -114,6 +150,7 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: periods=periods, facts=facts, fact_count=fact_count, + validation=validation, unmapped_count=unmapped_count, truncated=truncated, ) diff --git a/robosystems_client/models/operation_resume_request.py b/robosystems_client/models/operation_resume_request.py new file mode 100644 index 0000000..76064d9 --- /dev/null +++ b/robosystems_client/models/operation_resume_request.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.operation_resume_request_input import OperationResumeRequestInput + + +T = TypeVar("T", bound="OperationResumeRequest") + + +@_attrs_define +class OperationResumeRequest: + """Answer for an operation paused at a checkpoint (`awaiting_input`). + + Attributes: + input_ (OperationResumeRequestInput | Unset): The decision the paused run asked for, in whatever shape its + prompt described. Delivered to the task as `params['resume']['input']`. + """ + + input_: OperationResumeRequestInput | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + input_: dict[str, Any] | Unset = UNSET + if not isinstance(self.input_, Unset): + input_ = self.input_.to_dict() + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if input_ is not UNSET: + field_dict["input"] = input_ + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.operation_resume_request_input import OperationResumeRequestInput + + d = dict(src_dict) + _input_ = d.pop("input", UNSET) + input_: OperationResumeRequestInput | Unset + if isinstance(_input_, Unset): + input_ = UNSET + else: + input_ = OperationResumeRequestInput.from_dict(_input_) + + operation_resume_request = cls( + input_=input_, + ) + + operation_resume_request.additional_properties = d + return operation_resume_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/robosystems_client/models/operation_resume_request_input.py b/robosystems_client/models/operation_resume_request_input.py new file mode 100644 index 0000000..b651448 --- /dev/null +++ b/robosystems_client/models/operation_resume_request_input.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="OperationResumeRequestInput") + + +@_attrs_define +class OperationResumeRequestInput: + """The decision the paused run asked for, in whatever shape its prompt described. Delivered to the task as + `params['resume']['input']`. + + """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + operation_resume_request_input = cls() + + operation_resume_request_input.additional_properties = d + return operation_resume_request_input + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/robosystems_client/models/operator_request.py b/robosystems_client/models/operator_request.py index 669535a..4ae7d27 100644 --- a/robosystems_client/models/operator_request.py +++ b/robosystems_client/models/operator_request.py @@ -33,6 +33,9 @@ class OperatorRequest: force_extended_analysis (bool | Unset): Force extended analysis mode with comprehensive research Default: False. enable_rag (bool | Unset): Enable RAG context enrichment Default: True. stream (bool | Unset): Enable streaming response Default: False. + max_credits (float | None | Unset): Per-question credit ceiling. Once the run's consumed credits reach this + number, no further tool step starts and the operator answers from what it has (the wrap-up itself may carry the + total slightly past the ceiling). Omit for the mode's default step-bounded behavior. """ message: str @@ -44,6 +47,7 @@ class OperatorRequest: force_extended_analysis: bool | Unset = False enable_rag: bool | Unset = True stream: bool | Unset = False + max_credits: float | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -95,6 +99,12 @@ def to_dict(self) -> dict[str, Any]: stream = self.stream + max_credits: float | None | Unset + if isinstance(self.max_credits, Unset): + max_credits = UNSET + else: + max_credits = self.max_credits + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -118,6 +128,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["enable_rag"] = enable_rag if stream is not UNSET: field_dict["stream"] = stream + if max_credits is not UNSET: + field_dict["max_credits"] = max_credits return field_dict @@ -205,6 +217,15 @@ def _parse_selection_criteria(data: object) -> None | SelectionCriteria | Unset: stream = d.pop("stream", UNSET) + def _parse_max_credits(data: object) -> float | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(float | None | Unset, data) + + max_credits = _parse_max_credits(d.pop("max_credits", UNSET)) + operator_request = cls( message=message, history=history, @@ -215,6 +236,7 @@ def _parse_selection_criteria(data: object) -> None | SelectionCriteria | Unset: force_extended_analysis=force_extended_analysis, enable_rag=enable_rag, stream=stream, + max_credits=max_credits, ) operator_request.additional_properties = d diff --git a/robosystems_client/models/resume_operation_response_resumeoperation.py b/robosystems_client/models/resume_operation_response_resumeoperation.py new file mode 100644 index 0000000..50d1fdf --- /dev/null +++ b/robosystems_client/models/resume_operation_response_resumeoperation.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="ResumeOperationResponseResumeoperation") + + +@_attrs_define +class ResumeOperationResponseResumeoperation: + """ """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + resume_operation_response_resumeoperation = cls() + + resume_operation_response_resumeoperation.additional_properties = d + return resume_operation_response_resumeoperation + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/robosystems_client/models/validation_check_response.py b/robosystems_client/models/validation_check_response.py new file mode 100644 index 0000000..4014924 --- /dev/null +++ b/robosystems_client/models/validation_check_response.py @@ -0,0 +1,100 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="ValidationCheckResponse") + + +@_attrs_define +class ValidationCheckResponse: + """Aggregate result of running reporting rules over a structure. + + Every rule runs once per rendered period column; on a multi-column + statement each failure and warning is prefixed with the column it was + found in (``[Prior] …``). + + Attributes: + passed (bool): True iff at least one rule ran and every rule produced zero failures on every rendered column. + False when nothing was checked (`status == 'inconclusive'`). + status (str): `passed` — every rule ran on every column with zero failures; `failed` — at least one rule failed; + `inconclusive` — no validation rules exist for this block type, so nothing was checked. + checks (list[str]): Names of rules that were evaluated. + failures (list[str]): Human-readable descriptions of rule failures. + warnings (list[str]): Non-blocking advisories from rule evaluation. + """ + + passed: bool + status: str + checks: list[str] + failures: list[str] + warnings: list[str] + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + passed = self.passed + + status = self.status + + checks = self.checks + + failures = self.failures + + warnings = self.warnings + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "passed": passed, + "status": status, + "checks": checks, + "failures": failures, + "warnings": warnings, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + passed = d.pop("passed") + + status = d.pop("status") + + checks = cast(list[str], d.pop("checks")) + + failures = cast(list[str], d.pop("failures")) + + warnings = cast(list[str], d.pop("warnings")) + + validation_check_response = cls( + passed=passed, + status=status, + checks=checks, + failures=failures, + warnings=warnings, + ) + + validation_check_response.additional_properties = d + return validation_check_response + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/robosystems_client/models/validation_lite.py b/robosystems_client/models/validation_lite.py index 5652a4d..6be50e7 100644 --- a/robosystems_client/models/validation_lite.py +++ b/robosystems_client/models/validation_lite.py @@ -22,12 +22,14 @@ class ValidationLite: Attributes: passed (bool | Unset): Default: True. + status (str | Unset): Default: 'passed'. checks (list[str] | Unset): failures (list[str] | Unset): warnings (list[str] | Unset): """ passed: bool | Unset = True + status: str | Unset = "passed" checks: list[str] | Unset = UNSET failures: list[str] | Unset = UNSET warnings: list[str] | Unset = UNSET @@ -36,6 +38,8 @@ class ValidationLite: def to_dict(self) -> dict[str, Any]: passed = self.passed + status = self.status + checks: list[str] | Unset = UNSET if not isinstance(self.checks, Unset): checks = self.checks @@ -53,6 +57,8 @@ def to_dict(self) -> dict[str, Any]: field_dict.update({}) if passed is not UNSET: field_dict["passed"] = passed + if status is not UNSET: + field_dict["status"] = status if checks is not UNSET: field_dict["checks"] = checks if failures is not UNSET: @@ -67,6 +73,8 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: d = dict(src_dict) passed = d.pop("passed", UNSET) + status = d.pop("status", UNSET) + checks = cast(list[str], d.pop("checks", UNSET)) failures = cast(list[str], d.pop("failures", UNSET)) @@ -75,6 +83,7 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: validation_lite = cls( passed=passed, + status=status, checks=checks, failures=failures, warnings=warnings, diff --git a/robosystems_client/models/view_response.py b/robosystems_client/models/view_response.py index a2ef126..0834512 100644 --- a/robosystems_client/models/view_response.py +++ b/robosystems_client/models/view_response.py @@ -31,10 +31,11 @@ class ViewResponse: metadata (ViewMetadata): dimensions (list[Dimension] | Unset): Aspects spanned by the returned facts facts (list[FactRecord] | Unset): Deduplicated fact records - summary (None | Unset | ViewResponseSummaryType0): Per-element aggregates, only when include_summary=true. Note - that `total` sums across every returned period, which is meaningful for duration facts and not for instants. - Overlapping duration windows sharing a period_end (quarter + year-to-date) contribute only the narrowest window, - so a quarter is never double-counted inside its own YTD figure. + summary (None | Unset | ViewResponseSummaryType0): Per-element aggregates, only when include_summary=true. + `total` and `average` span every returned period, so they are present for duration elements only — instants omit + both (a balance summed across periods is not a balance). Overlapping duration windows sharing a period_end + (quarter + year-to-date) contribute only the narrowest window, so a quarter is never double-counted inside its + own YTD figure. """ metadata: ViewMetadata