diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f35672..e170d31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## [1.6.0] - 2026-10-04 + +### Changed + +- Sync the bundled OpenAPI spec, adding 10 paths and 18 schemas. The typed models gain the new response fields, including `attachments` on a run and on each step +- Move `LATEST_API_VERSION` to `2026-10-03` + +### Added + +- Add `list_cloud_drives()`, `get_cloud_drive()`, `update_cloud_drive()`, `disconnect_cloud_drive()`, `delete_cloud_drive()`, `list_cloud_drive_providers()`, `get_agents_using_cloud_drive()` and `list_cloud_drive_rejections()` for cloud-drive connections. The list methods return the items on either response shape +- Add `list_source_contents()` and `get_source_content_status()` to read the indexing status of a source's content, keyed by the `content_version_id` the upload methods return +- Add `list_embedding_models()` and `list_reranker_models()`, with the pricing and defaults that sit beside each list +- Add `ApiVersion` members for `2026-08-03`, `2026-08-21`, `2026-09-28`, `2026-09-30` and `2026-10-03`, so each can be selected without `allow_unknown_api_version` +- Add a `param_style` argument to `paginate()` for endpoints that page by `offset` rather than `page` + +### Fixed + +- Read the body of an error response in the streaming methods. A 422 from `run_streaming_agent_and_wait()` escaped as `httpx.ResponseNotRead`, a 422 from `run_streaming_agent()` lost its field-level detail, and every streaming error had an empty `response_text` +- Raise `SeclaiAPIStatusError` on a 422 whose `detail` is a plain string, from every method including the typed ones and the uploads. Decoding it as field-level validation raised `ValueError` from inside the generated models +- Apply the unknown-version guard to a `Seclai-Version` passed in a per-request `headers` argument, on `request()` and the streaming methods. Any value was sent +- Replace a header case-insensitively when a per-request `headers` argument or the auth layer supplies one the client already set. Both spellings were sent +- Yield the items from `paginate()` when the endpoint answers with a bare array, or under `data` while a per-resource `items_key` was given. It yielded nothing in both cases, and now raises `SeclaiError` on a shape it cannot read +- Copy `default_headers` at construction. Mutating the mapping afterwards put an unvalidated `Seclai-Version` on the wire +- Reject an empty `Seclai-Version` in `default_headers`. It was read as absent, sent anyway, and suppressed `api_version` + ## [1.5.0] - 2026-07-27 ### Changed @@ -158,6 +183,7 @@ _Stable release. Packaging, CI, and documentation deployment only; no API change _Initial release._ +[1.6.0]: https://github.com/seclai/seclai-python/releases/tag/1.6.0 [1.5.0]: https://github.com/seclai/seclai-python/releases/tag/1.5.0 [1.4.0]: https://github.com/seclai/seclai-python/releases/tag/1.4.0 [1.3.0]: https://github.com/seclai/seclai-python/releases/tag/1.3.0 diff --git a/README.md b/README.md index 53c0051..e6a2859 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,9 @@ reshape responses, and this client would decode them incorrectly rather than reject them. Upgrade the package to adopt a new version, or pass `allow_unknown_api_version=True` if you have to move first and accept that risk. -The guard only covers the header. An account pinned server-side can still be +The guard covers the header however it is supplied — `api_version`, +`default_headers`, or a per-request `headers` argument — and nothing else. An +account pinned server-side can still be newer than this release — `get_api_version()` reports the `effective_version` the request resolved to, and comparing it against `LATEST_API_VERSION` is how you detect the gap. @@ -184,8 +186,6 @@ of being ignored, and list endpoints move to the canonical `{"data": [...], "pagination": {...}}` envelope. The affected methods read both shapes, so they keep working either way — but the metadata moves: -| Method | Before | From 2026-07-27 | -| --- | --- | --- | | Method | Before | From 2026-07-27 | Legacy paging | | --- | --- | --- | --- | | `list_evaluation_criteria_page()` | bare list | `data` + `pagination` | none — returns everything | @@ -210,8 +210,25 @@ then removed once the canonical envelope is the default. The two evaluation endpoints are **unpaginated** on the legacy shape — they ignore `page`/`limit` and return everything — so a paginate-until-empty loop over -them only terminates once you have opted in. The other four paginate on either -shape. +them only terminates once you have opted in. `get_generation_tiers()` takes no +paging arguments at all and always returns the full set. The remaining three +paginate on either shape. + +**Later versions.** Each is cumulative, and none changes a response shape this +client decodes: + +| Version | What it changes | +| --- | --- | +| `2026-08-03` | `create_memory_bank()` and `update_memory_bank()` reject a non-zero `max_age_days` with a 400, and an omitted `retention_days` on create resolves per bank type | +| `2026-08-21` | `create_source()` rejects an embedding dimension its embedder does not support with a 400 — `list_embedding_models()` reports the supported ones | +| `2026-09-28` | Agent-definition writes use the current file-list grammar: an omitted `attachments` keeps the stored list and `[]` means no files | +| `2026-09-30` | A run's and a step's `output`, and a step's `input`, are the text rather than a JSON manifest; files are in `attachments` on every version | +| `2026-10-03` | A new LLM step written without `attachments` takes its parent's files, and a new retrieval step's matched media are its files | + +The cloud-drive listings and `list_embedding_models()` / `list_reranker_models()` +follow the `2026-07-27` envelope rule as well. The cloud-drive methods return +the items on either shape; read the two model listings with +`unwrap_items(result, "models")`. ## Resources @@ -282,9 +299,9 @@ search = client.search_agent_runs({"query": "test"}) # Fetch run details (optionally with step outputs) detail = client.get_agent_run("run_id", include_step_outputs=True) -# Cancel or delete +# Cancel an in-flight or queued run. `delete_agent_run()` is the same +# operation on the same endpoint, returning a typed model instead of a dict. client.cancel_agent_run("run_id") -client.delete_agent_run("run_id") ``` ### Streaming @@ -366,8 +383,8 @@ with response: steps = client.generate_agent_steps("agent_id", {"user_input": "Build a RAG pipeline"}) config = client.generate_step_config("agent_id", {"step_type": "llm", "user_input": "..."}) -# Conversation history -history = client.get_agent_ai_conversation_history("agent_id") +# Conversation history — step_type is required by the API +history = client.get_agent_ai_conversation_history("agent_id", step_type="llm") client.mark_agent_ai_suggestion("agent_id", "conversation_id", {"accepted": True}) ``` @@ -448,6 +465,33 @@ client.update_source("source_id", {"name": "Updated"}) client.delete_source("source_id") ``` +Indexing status of a source's content, keyed by the `content_version_id` the +upload methods return: + +```python +failed = client.list_source_contents("source_id", status="failed") +batch = client.list_source_contents( + "source_id", content_version_ids=["cv_1", "cv_2"] +) +one = client.get_source_content_status("source_id", "cv_1") +``` + +### Cloud drives + +```python +providers = client.list_cloud_drive_providers() +drives = client.list_cloud_drives() +drive = client.get_cloud_drive("connection_id") +client.update_cloud_drive("connection_id", {"name": "Contracts"}) + +# Which agents depend on it, and which files it skipped and why +agents = client.get_agents_using_cloud_drive("connection_id") +skipped = client.list_cloud_drive_rejections("connection_id", limit=20) + +client.disconnect_cloud_drive("connection_id") # keeps the connection +client.delete_cloud_drive("connection_id") +``` + ### File uploads Upload a file to a source (max 200 MiB): @@ -657,6 +701,10 @@ print(removed.get("cleanup_note")) # set when the domain was Seclai-managed # Media-generation quality tiers (fast/balanced/thorough) and what each resolves to tiers = client.get_generation_tiers() +# Embedding and reranker models, with their pricing +embedders = unwrap_items(client.list_embedding_models(), "models") +rerankers = unwrap_items(client.list_reranker_models(), "models") + alerts = client.list_model_alerts() client.mark_model_alert_read("alert_id") client.mark_all_model_alerts_read() @@ -719,8 +767,14 @@ All list methods accept `page` and `limit` parameters. For auto-pagination acros for agent in client.paginate("GET", "/agents"): print(agent["name"]) -# With a custom items key -for alert in client.paginate("GET", "/alerts", items_key="items"): +# With a per-resource items key; `data` is read first, so this works on +# either response shape +for config in client.paginate("GET", "/alerts/configs", items_key="configs"): + print(config["id"]) + +# Endpoints that declare `offset` rather than `page` +for alert in client.paginate("GET", "/models/alerts", items_key="alerts", + param_style="offset"): print(alert["id"]) ``` diff --git a/openapi/seclai.openapi.json b/openapi/seclai.openapi.json index c497763..3d86fdc 100644 --- a/openapi/seclai.openapi.json +++ b/openapi/seclai.openapi.json @@ -373,7 +373,7 @@ "title": "Evaluation Criteria" }, "export_version": { - "description": "Schema version of the export format (currently \"2\").", + "description": "Schema version of the export format (currently \"5\").", "title": "Export Version", "type": "string" }, @@ -491,6 +491,60 @@ "title": "AgentRunAttemptResponse", "type": "object" }, + "AgentRunFileResponse": { + "description": "A file in a run's or a step's output.", + "properties": { + "bytes": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Size of the file in bytes, when known.", + "title": "Bytes" + }, + "download_url": { + "description": "`GET` URL that streams the file; accepts an API key or OAuth token.", + "title": "Download Url", + "type": "string" + }, + "id": { + "description": "File identifier, used to download it.", + "format": "uuid", + "title": "Id", + "type": "string" + }, + "mime": { + "description": "MIME type of the file.", + "title": "Mime", + "type": "string" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The file's name in this run, as sent to email recipients and webhooks and matched by `{{attachments[...]}}` selectors.", + "title": "Name" + } + }, + "required": [ + "id", + "name", + "mime", + "bytes", + "download_url" + ], + "title": "AgentRunFileResponse", + "type": "object" + }, "AgentRunRequest": { "properties": { "input": { @@ -515,7 +569,7 @@ "type": "null" } ], - "description": "ID of a previously uploaded file (via POST /{agent_id}/upload-input) to use as the run input for dynamic-input triggers. Mutually exclusive with the 'input' field. Use ``input_upload_ids`` to attach multiple files.\n\n**Attachment visibility:** a step only sees the upload when its template references the input \u2014 via ``{{input}}`` / ``{{agent.input}}`` / ``{{step..input|output}}`` (implicit, all attachments) or the ``{{attachments[\u2026]}}`` family (explicit narrowing \u2014 e.g. ``{{attachments[0]}}``, ``{{attachments[*.pdf]}}``).\n\n**Per-batch validation:** every selector the agent's definition declares must be satisfied or the run is rejected with HTTP 400. Exact-name selectors require that filename to be present; indexed selectors require at least N+1 files; glob patterns require at least one matching filename.", + "description": "ID of a previously uploaded file (via POST /{agent_id}/upload-input) to use as the run input for dynamic-input triggers. Mutually exclusive with ``input_upload_ids`` \u2014 use that field to attach multiple files. May be combined with ``input``: the prompt text leads and the file's extracted text follows under a ``# {filename}`` heading.\n\n**Attachment visibility:** a step only sees the upload when its template references the input \u2014 via ``{{input}}`` / ``{{agent.input}}`` / ``{{step..input|output}}`` (implicit, all attachments) or the ``{{attachments[\u2026]}}`` family (explicit narrowing \u2014 e.g. ``{{attachments[0]}}``, ``{{attachments[*.pdf]}}``).\n\n**Per-batch validation:** every selector the agent's definition declares must be satisfied or the run is rejected with HTTP 400. Exact-name selectors require that filename to be present; indexed selectors require at least N+1 files; glob patterns require at least one matching filename.", "title": "Input Upload Id" }, "input_upload_ids": { @@ -532,7 +586,7 @@ "type": "null" } ], - "description": "IDs of multiple previously uploaded files. Each upload's extracted text is concatenated under a heading; each upload's binary is surfaced as a separate ``MediaAttachment`` so multi-modal prompt steps reason over all files at once. Steps narrow visibility via ``{{attachments[\u2026]}}`` selectors (by index, filename, or fnmatch glob). The batch must satisfy every selector the agent declares \u2014 exact names, indexed references (length must exceed the highest index), and glob patterns (each pattern needs at least one match). Mismatches return HTTP 400 with the unmet requirements listed. Mutually exclusive with ``input`` and ``input_upload_id`` \u2014 pass exactly one of the three. Max 20 uploads per run.", + "description": "IDs of multiple previously uploaded files. Each upload's extracted text is concatenated under a heading; each upload's binary is surfaced as a separate ``MediaAttachment`` so multi-modal prompt steps reason over all files at once. Steps narrow visibility via ``{{attachments[\u2026]}}`` selectors (by index, filename, or fnmatch glob). The batch must satisfy every selector the agent declares \u2014 exact names, indexed references (length must exceed the highest index), and glob patterns (each pattern needs at least one match). Mismatches return HTTP 400 with the unmet requirements listed. Mutually exclusive with ``input_upload_id`` (two spellings of the same batch), but may be combined with ``input`` \u2014 the prompt text leads and the per-file sections follow, so \"a photo plus a sentence about it\" needs no synthetic text upload. Max 20 uploads per run.", "title": "Input Upload Ids" }, "metadata": { @@ -575,6 +629,14 @@ }, "AgentRunResponse": { "properties": { + "attachments": { + "description": "Files in the run's output, in order. Empty for runs that produced none, for runs made before files were listed here, and once the run's trace is purged.", + "items": { + "$ref": "#/components/schemas/AgentRunFileResponse" + }, + "title": "Attachments", + "type": "array" + }, "attempts": { "description": "List of attempts made for this agent run.", "items": { @@ -600,7 +662,7 @@ "type": "null" } ], - "description": "Credits consumed by the agent run, if applicable.", + "description": "Credits consumed by the agent run, if applicable. Can still rise briefly after the run ends, while governance screening finishes.", "title": "Credits" }, "error_count": { @@ -685,7 +747,7 @@ "type": "null" } ], - "description": "Output produced by the agent run.", + "description": "The run's output text; its files are in `attachments`. Below `Seclai-Version: 2026-09-30` an output that has files is instead the manifest JSON `{schema, text, attachments: [{storage_key, mime, name, label, bytes}]}`; `bytes` is absent on runs made before that version shipped.", "title": "Output" }, "output_content_type": { @@ -697,7 +759,7 @@ "type": "null" } ], - "description": "MIME type of `output` \u2014 mirrors the terminal step's `output_content_type`. Consumers interpret `output` differently depending on this value: `application/vnd.seclai.manifest+json` is a multi-asset manifest with shape `{text, attachments: [{storage_key, mime, name, bytes}]}` \u2014 fetch each attachment via `GET /v2/agent-runs/{run_id}/attachments/{attachment_id}`, where `attachment_id` is the URL-safe base64 of the attachment's `storage_key` (accepts an API key or OAuth token). `text/plain` / `text/*` are free-form text. `application/json` is a JSON document. Null on runs that produced no terminal output or that pre-date this column.", + "description": "MIME type of `output` \u2014 mirrors the terminal step's `output_content_type`. `text/plain` / `text/*` are free-form text and `application/json` is a JSON document. Below `Seclai-Version: 2026-09-30` an output that has files reads `application/vnd.seclai.manifest+json` (see `output`); the same files are in `attachments` on every version, each with a `download_url`. Null on runs that produced no terminal output or that pre-date this column.", "title": "Output Content Type" }, "priority": { @@ -741,6 +803,19 @@ "description": "Step outputs and per-step timing/credits. Only included when requested.", "title": "Steps" }, + "trace_purged_at": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When this run's trace content was deleted under the account's agent-trace retention window. Non-null means `input`, `output` and every step's and tool call's I/O are null **by design** and will never be available again \u2014 the run aged out, it did not fail. Branch on this rather than on a null `output`: a run that genuinely produced nothing looks identical. Status, timing and credits remain accurate.", + "title": "Trace Purged At" + }, "wait_ms": { "anyOf": [ { @@ -774,8 +849,16 @@ "title": "Agent Step Id", "type": "string" }, + "attachments": { + "description": "Files in this step's output, in order. Empty for steps that produced none, for steps run before files were listed here, and once the run's trace is purged.", + "items": { + "$ref": "#/components/schemas/AgentRunFileResponse" + }, + "title": "Attachments", + "type": "array" + }, "credits_used": { - "description": "Credits consumed by the step attempt, if applicable.", + "description": "Credits consumed by this step across every attempt it made. Some charges made outside any step, such as governance screening of the run's input, count toward the run's total but no step's. The timestamps above and the tool calls below describe the latest attempt only.", "title": "Credits Used", "type": "number" }, @@ -812,7 +895,7 @@ "type": "null" } ], - "description": "Input provided to the step, if any.", + "description": "Input text provided to the step, if any. Below `Seclai-Version: 2026-09-30`, the manifest JSON when the step that produced it output files and is not a `for_each`.", "title": "Input" }, "output": { @@ -824,7 +907,7 @@ "type": "null" } ], - "description": "Output produced by the step, if any.", + "description": "Output text produced by the step, if any; its files are in `attachments`. Below `Seclai-Version: 2026-09-30`, the manifest JSON when the step output files and is not a `for_each`.", "title": "Output" }, "output_content_type": { @@ -867,6 +950,21 @@ }, "title": "Tool Calls", "type": "array" + }, + "warnings": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Authoring problems the step ran into, whether or not it then failed, such as a file name selector that matched none of its source's files.", + "title": "Warnings" } }, "required": [ @@ -908,7 +1006,7 @@ "type": "null" } ], - "description": "ID of a previously uploaded file (via POST /{agent_id}/upload-input) to use as the run input for dynamic-input triggers. Mutually exclusive with the 'input' field. Use ``input_upload_ids`` to attach multiple files. Subject to the same per-batch attachment-selector validation as the non-streaming endpoint.", + "description": "ID of a previously uploaded file (via POST /{agent_id}/upload-input) to use as the run input for dynamic-input triggers. Mutually exclusive with ``input_upload_ids`` \u2014 use that field to attach multiple files. May be combined with ``input``. Subject to the same per-batch attachment-selector validation as the non-streaming endpoint.", "title": "Input Upload Id" }, "input_upload_ids": { @@ -925,7 +1023,7 @@ "type": "null" } ], - "description": "IDs of multiple previously uploaded files. See the non-streaming endpoint for full semantics, including per-batch selector validation (exact names, indexed references, and glob patterns must all be satisfied or the run is rejected with HTTP 400). Max 20.", + "description": "IDs of multiple previously uploaded files. See the non-streaming endpoint for full semantics, including per-batch selector validation (exact names, indexed references, and glob patterns must all be satisfied or the run is rejected with HTTP 400) and combining the batch with ``input`` prompt text. Max 20.", "title": "Input Upload Ids" }, "metadata": { @@ -1047,7 +1145,7 @@ }, "sequence": { "default": 0, - "description": "0-based ordinal of this call within its step run.", + "description": "0-based ordinal of this call within one attempt of the step, so it repeats across a retried step's attempts. This list holds the latest attempt only.", "title": "Sequence", "type": "integer" }, @@ -1383,6 +1481,47 @@ "title": "AgentTraceSearchResponse", "type": "object" }, + "AgentUsingCloudDriveResponseModel": { + "properties": { + "agent_id": { + "description": "Agent identifier.", + "title": "Agent Id", + "type": "string" + }, + "agent_name": { + "description": "Agent name.", + "title": "Agent Name", + "type": "string" + }, + "trigger_types": { + "description": "File-change trigger types bound to this drive.", + "items": { + "type": "string" + }, + "title": "Trigger Types", + "type": "array" + }, + "via_prompt_tool": { + "description": "Uses a prompt_call cloud-drive tool.", + "title": "Via Prompt Tool", + "type": "boolean" + }, + "via_step": { + "description": "Uses a list/read/write cloud-drive step.", + "title": "Via Step", + "type": "boolean" + } + }, + "required": [ + "agent_id", + "agent_name", + "via_step", + "via_prompt_tool", + "trigger_types" + ], + "title": "AgentUsingCloudDriveResponseModel", + "type": "object" + }, "AiAssistantAcceptResponse": { "description": "Response from accepting and executing a plan.", "properties": { @@ -2210,149 +2349,85 @@ "title": "ChangeStatusRequest", "type": "object" }, - "CompactionEvaluationModel": { - "description": "Structured LLM-as-judge evaluation result.", + "CloudDriveAccessLevelResponseModel": { "properties": { - "reasoning": { - "description": "Explanation of the evaluation.", - "title": "Reasoning", - "type": "string" - }, - "score": { - "description": "Quality score from 1 to 5.", - "title": "Score", - "type": "integer" + "default": { + "description": "Whether connecting without a choice uses it.", + "title": "Default", + "type": "boolean" }, - "verdict": { - "description": "'pass' or 'fail'.", - "title": "Verdict", + "description": { + "description": "What agents can do at this level.", + "title": "Description", "type": "string" - } - }, - "required": [ - "verdict", - "score", - "reasoning" - ], - "title": "CompactionEvaluationModel", - "type": "object" - }, - "CompactionScheduledResponse": { - "description": "Acknowledgement that an on-demand compaction run was scheduled.", - "properties": { - "memory_bank_id": { - "title": "Memory Bank Id", + }, + "key": { + "description": "Level identifier, e.g. `read_write`/`read_only`.", + "title": "Key", "type": "string" }, - "status": { - "title": "Status", + "label": { + "description": "Short human-readable name.", + "title": "Label", "type": "string" } }, "required": [ - "memory_bank_id", - "status" + "key", + "label", + "description", + "default" ], - "title": "CompactionScheduledResponse", + "title": "CloudDriveAccessLevelResponseModel", "type": "object" }, - "CompactionTestResponseModel": { - "description": "Response from a compaction prompt test.", + "CloudDriveProviderResponseModel": { "properties": { - "compaction_summary": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "The generated compaction summary.", - "title": "Compaction Summary" - }, - "evaluation": { - "$ref": "#/components/schemas/CompactionEvaluationModel", - "description": "LLM-as-judge quality evaluation." - }, - "generated": { - "description": "True when entries were LLM-generated rather than real.", - "title": "Generated", - "type": "boolean" - }, - "original_entries": { - "description": "Entries fed into the compactor.", + "access_levels": { + "description": "Mutually-exclusive permission bundles offered when connecting. Connecting happens in the app, so this is informational here \u2014 it explains what a connection's `access_level` can be.", "items": { - "type": "string" + "$ref": "#/components/schemas/CloudDriveAccessLevelResponseModel" }, - "title": "Original Entries", + "title": "Access Levels", "type": "array" }, - "surviving_entries": { - "description": "Entries that survived after compaction.", - "items": { - "type": "string" - }, - "title": "Surviving Entries", - "type": "array" - } - }, - "required": [ - "original_entries", - "compaction_summary", - "surviving_entries", - "evaluation", - "generated" - ], - "title": "CompactionTestResponseModel", - "type": "object" - }, - "CompatibleRunListResponse": { - "description": "Paginated list of compatible runs.", - "properties": { - "data": { + "display_name": { + "description": "Human-readable provider name.", + "title": "Display Name", + "type": "string" + }, + "key": { + "description": "Provider key used as `provider` on a connection.", + "title": "Key", + "type": "string" + }, + "scopes": { + "description": "OAuth permissions this provider can request.", "items": { - "$ref": "#/components/schemas/CompatibleRunResponse" + "$ref": "#/components/schemas/CloudDriveScopeResponseModel" }, - "title": "Data", + "title": "Scopes", "type": "array" - }, - "limit": { - "title": "Limit", - "type": "integer" - }, - "page": { - "title": "Page", - "type": "integer" - }, - "total": { - "title": "Total", - "type": "integer" } }, "required": [ - "data", - "total", - "page", - "limit" + "key", + "display_name", + "scopes", + "access_levels" ], - "title": "CompatibleRunListResponse", + "title": "CloudDriveProviderResponseModel", "type": "object" }, - "CompatibleRunResponse": { - "description": "A run that has a completed step matching a criteria's step_id.", + "CloudDriveRejectionResponseModel": { + "description": "One file the connection deliberately did not process.", "properties": { - "agent_run_id": { - "format": "uuid", - "title": "Agent Run Id", - "type": "string" - }, - "agent_step_run_id": { - "format": "uuid", - "title": "Agent Step Run Id", + "created_at": { + "description": "When the file was skipped.", + "title": "Created At", "type": "string" }, - "completed_at": { + "detail": { "anyOf": [ { "type": "string" @@ -2361,9 +2436,10 @@ "type": "null" } ], - "title": "Completed At" + "description": "Extra context, e.g. the cap that was hit.", + "title": "Detail" }, - "input_preview": { + "file_id": { "anyOf": [ { "type": "string" @@ -2372,9 +2448,10 @@ "type": "null" } ], - "title": "Input Preview" + "description": "The provider's file id, when the file was known.", + "title": "File Id" }, - "output_storage_key": { + "file_path": { "anyOf": [ { "type": "string" @@ -2383,9 +2460,32 @@ "type": "null" } ], - "title": "Output Storage Key" + "description": "Path of the skipped file, when known.", + "title": "File Path" }, - "run_status": { + "id": { + "description": "Rejection identifier.", + "title": "Id", + "type": "string" + }, + "reason": { + "description": "`too_large`, `download_failed`, or `flood`.", + "title": "Reason", + "type": "string" + } + }, + "required": [ + "id", + "reason", + "created_at" + ], + "title": "CloudDriveRejectionResponseModel", + "type": "object" + }, + "CloudDriveResponseModel": { + "description": "A cloud-drive connection, without any secret material.", + "properties": { + "access_level": { "anyOf": [ { "type": "string" @@ -2394,10 +2494,21 @@ "type": "null" } ], - "title": "Run Status" + "description": "The permission bundle the granted scopes correspond to \u2014 `read_write` or `read_only`. Null when the grant matches no level the provider currently offers; treat that as unknown rather than assuming write access.", + "title": "Access Level" }, - "started_at": { - "anyOf": [ + "connected": { + "description": "True when the connection is usable.", + "title": "Connected", + "type": "boolean" + }, + "created_at": { + "description": "When the connection was created.", + "title": "Created At", + "type": "string" + }, + "drive_id": { + "anyOf": [ { "type": "string" }, @@ -2405,68 +2516,10 @@ "type": "null" } ], - "title": "Started At" - } - }, - "required": [ - "agent_run_id", - "agent_step_run_id", - "completed_at", - "output_storage_key" - ], - "title": "CompatibleRunResponse", - "type": "object" - }, - "ContentEmbeddingResponse": { - "description": "Response model for content embedding.", - "properties": { - "batch_duration": { - "title": "Batch Duration", - "type": "number" - }, - "batch_size": { - "title": "Batch Size", - "type": "integer" - }, - "id": { - "title": "Id", - "type": "string" - }, - "text": { - "title": "Text", - "type": "string" - }, - "text_end": { - "title": "Text End", - "type": "integer" - }, - "text_start": { - "title": "Text Start", - "type": "integer" + "description": "Opaque id of the shared drive the folder resolves to, or null for the user's own drive. Stable across renames \u2014 compare on this rather than on the name in `folder_path`.", + "title": "Drive Id" }, - "vector": { - "items": { - "type": "number" - }, - "title": "Vector", - "type": "array" - } - }, - "required": [ - "id", - "text_start", - "text_end", - "text", - "vector", - "batch_size", - "batch_duration" - ], - "title": "ContentEmbeddingResponse", - "type": "object" - }, - "CreateAlertConfigRequest": { - "properties": { - "agent_id": { + "drive_name": { "anyOf": [ { "type": "string" @@ -2475,48 +2528,37 @@ "type": "null" } ], - "description": "Agent ID (for agent alerts)", - "title": "Agent Id" - }, - "alert_type": { - "description": "Alert type", - "title": "Alert Type", - "type": "string" - }, - "cooldown_minutes": { - "default": 60, - "description": "Cooldown period in minutes", - "title": "Cooldown Minutes", - "type": "integer" + "description": "Display name the shared drive last resolved to. Presentation only; never match on it.", + "title": "Drive Name" }, - "distribution_type": { - "default": "owner", - "description": "Distribution type (owner, owner_admins, selected_members)", - "title": "Distribution Type", - "type": "string" - }, - "enabled": { - "default": true, - "description": "Whether the alert config is enabled", - "title": "Enabled", + "drive_name_stale": { + "description": "True when `drive_name` could not be re-confirmed (the drive was deleted, access was lost, or the provider was unreachable). The last known name is still reported \u2014 treat it as possibly out of date rather than current.", + "title": "Drive Name Stale", "type": "boolean" }, - "recipient_user_ids": { + "external_account_id": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "type": "string" }, { "type": "null" } ], - "description": "User IDs for selected_members distribution", - "title": "Recipient User Ids" + "description": "The provider's own opaque account identifier (never an email).", + "title": "External Account Id" }, - "source_connection_id": { + "folder_path": { + "description": "Watched folder; empty string means the drive root. A folder on a shared drive is written `/Shared drives//`.", + "title": "Folder Path", + "type": "string" + }, + "id": { + "description": "Connection identifier.", + "title": "Id", + "type": "string" + }, + "last_error": { "anyOf": [ { "type": "string" @@ -2525,33 +2567,22 @@ "type": "null" } ], - "description": "Source connection ID (for source alerts)", - "title": "Source Connection Id" + "description": "Most recent sync or authorization error, if any.", + "title": "Last Error" }, - "threshold": { + "last_synced_at": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "Threshold configuration", - "title": "Threshold" - } - }, - "required": [ - "alert_type" - ], - "title": "CreateAlertConfigRequest", - "type": "object" - }, - "CreateEvaluationCriteriaRequest": { - "description": "Request body for creating an evaluation criteria.\n\nThe evaluation mode, retry settings, and sample frequency are set at the\nagent level, not per-criteria.", - "properties": { - "description": { + "description": "When the connection last synced successfully.", + "title": "Last Synced At" + }, + "name": { "anyOf": [ { "type": "string" @@ -2560,14 +2591,10 @@ "type": "null" } ], - "title": "Description" - }, - "enabled": { - "default": true, - "title": "Enabled", - "type": "boolean" + "description": "Human-readable name.", + "title": "Name" }, - "evaluation_prompt": { + "oauth_scopes": { "anyOf": [ { "type": "string" @@ -2576,126 +2603,138 @@ "type": "null" } ], - "title": "Evaluation Prompt" + "description": "Space-separated OAuth scopes granted to this connection.", + "title": "Oauth Scopes" }, - "evaluation_tier": { - "anyOf": [ - { - "$ref": "#/components/schemas/AgentEvaluationTier" - }, - { - "type": "null" - } - ] + "provider": { + "description": "Provider key, e.g. `dropbox` or `google_drive`.", + "title": "Provider", + "type": "string" }, - "expectation_config": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "title": "Expectation Config" + "realtime_updates": { + "description": "True when changes arrive via the provider's push notifications. False means the drive still syncs, but only on the scheduled backstop sweep rather than within seconds of a change.", + "title": "Realtime Updates", + "type": "boolean" }, - "pass_threshold": { - "default": 0.5, - "maximum": 1.0, - "minimum": 0.0, - "title": "Pass Threshold", - "type": "number" + "status": { + "description": "One of `active`, `pending_auth`, `error`, `disconnected`.", + "title": "Status", + "type": "string" }, - "step_id": { - "maxLength": 255, - "minLength": 1, - "title": "Step Id", + "updated_at": { + "description": "When the connection was last modified.", + "title": "Updated At", "type": "string" } }, "required": [ - "step_id" + "id", + "provider", + "status", + "folder_path", + "drive_name_stale", + "connected", + "realtime_updates", + "created_at", + "updated_at" ], - "title": "CreateEvaluationCriteriaRequest", + "title": "CloudDriveResponseModel", "type": "object" }, - "CreateEvaluationResultRequest": { - "description": "Request body for recording an evaluation result.", + "CloudDriveScopeResponseModel": { "properties": { - "agent_run_id": { - "format": "uuid", - "title": "Agent Run Id", + "description": { + "description": "What the scope allows.", + "title": "Description", "type": "string" }, - "agent_step_run_id": { - "anyOf": [ - { - "format": "uuid", - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Agent Step Run Id" + "key": { + "description": "The OAuth scope string sent to the provider.", + "title": "Key", + "type": "string" }, - "details": { + "label": { + "description": "Short human-readable name.", + "title": "Label", + "type": "string" + }, + "recommended": { + "description": "Whether this scope is requested by default on connect.", + "title": "Recommended", + "type": "boolean" + } + }, + "required": [ + "key", + "label", + "description", + "recommended" + ], + "title": "CloudDriveScopeResponseModel", + "type": "object" + }, + "CloudDriveUpdateRequest": { + "properties": { + "folder_path": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Details" - }, - "flagged": { - "default": false, - "title": "Flagged", - "type": "boolean" - }, - "retry_count": { - "default": 0, - "minimum": 0.0, - "title": "Retry Count", - "type": "integer" + "description": "New watched folder; empty means the whole drive. A folder on a shared drive is written `/Shared drives//`. Changing it resets the sync cursor, so files already in the new folder are NOT replayed as triggers \u2014 only subsequent changes fire, matching connect-time behaviour. Rejected when the new folder would make an agent that writes there re-trigger itself.", + "title": "Folder Path" }, - "retry_triggered": { - "default": false, - "title": "Retry Triggered", - "type": "boolean" - }, - "score": { + "name": { "anyOf": [ { - "maximum": 1.0, - "minimum": 0.0, - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Score" - }, - "status": { - "$ref": "#/components/schemas/EvaluationStatus" + "description": "New display name for the connection.", + "title": "Name" } }, - "required": [ - "agent_run_id", - "status" - ], - "title": "CreateEvaluationResultRequest", + "title": "CloudDriveUpdateRequest", "type": "object" }, - "CreateExperimentResponse": { + "CompactionEvaluationModel": { + "description": "Structured LLM-as-judge evaluation result.", "properties": { - "experiment_id": { - "title": "Experiment Id", + "reasoning": { + "description": "Explanation of the evaluation.", + "title": "Reasoning", + "type": "string" + }, + "score": { + "description": "Quality score from 1 to 5.", + "title": "Score", + "type": "integer" + }, + "verdict": { + "description": "'pass' or 'fail'.", + "title": "Verdict", + "type": "string" + } + }, + "required": [ + "verdict", + "score", + "reasoning" + ], + "title": "CompactionEvaluationModel", + "type": "object" + }, + "CompactionScheduledResponse": { + "description": "Acknowledgement that an on-demand compaction run was scheduled.", + "properties": { + "memory_bank_id": { + "title": "Memory Bank Id", "type": "string" }, "status": { @@ -2704,136 +2743,131 @@ } }, "required": [ - "experiment_id", + "memory_bank_id", "status" ], - "title": "CreateExperimentResponse", + "title": "CompactionScheduledResponse", "type": "object" }, - "CreateKnowledgeBaseBody": { - "description": "Request body for creating a knowledge base.", + "CompactionTestResponseModel": { + "description": "Response from a compaction prompt test.", "properties": { - "default_score_threshold": { - "anyOf": [ - { - "maximum": 1.0, - "minimum": 0.0, - "type": "number" - }, - { - "type": "null" - } - ], - "description": "Default minimum rerank score threshold.", - "title": "Default Score Threshold" - }, - "default_top_k": { - "anyOf": [ - { - "exclusiveMinimum": 0.0, - "maximum": 200.0, - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Default results after reranking.", - "title": "Default Top K" - }, - "default_top_n": { - "anyOf": [ - { - "exclusiveMinimum": 0.0, - "maximum": 200.0, - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Default number of results.", - "title": "Default Top N" - }, - "description": { + "compaction_summary": { "anyOf": [ { - "maxLength": 1000, "type": "string" }, { "type": "null" } ], - "description": "Optional description.", - "title": "Description" + "description": "The generated compaction summary.", + "title": "Compaction Summary" }, - "name": { - "description": "Knowledge base name.", - "maxLength": 255, - "minLength": 1, - "title": "Name", - "type": "string" + "evaluation": { + "$ref": "#/components/schemas/CompactionEvaluationModel", + "description": "LLM-as-judge quality evaluation." }, - "reranker_model": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Reranker model to use (null for no reranking).", - "title": "Reranker Model" + "generated": { + "description": "True when entries were LLM-generated rather than real.", + "title": "Generated", + "type": "boolean" }, - "source_ids": { - "description": "List of source connection IDs to link.", + "original_entries": { + "description": "Entries fed into the compactor.", "items": { "type": "string" }, - "minItems": 1, - "title": "Source Ids", + "title": "Original Entries", + "type": "array" + }, + "surviving_entries": { + "description": "Entries that survived after compaction.", + "items": { + "type": "string" + }, + "title": "Surviving Entries", "type": "array" } }, "required": [ - "name", - "source_ids" + "original_entries", + "compaction_summary", + "surviving_entries", + "evaluation", + "generated" ], - "title": "CreateKnowledgeBaseBody", + "title": "CompactionTestResponseModel", "type": "object" }, - "CreateMemoryBankBody": { - "description": "Request body for creating a memory bank.", + "CompatibleRunListResponse": { + "description": "Paginated list of compatible runs.", "properties": { - "chunk_overlap": { + "data": { + "items": { + "$ref": "#/components/schemas/CompatibleRunResponse" + }, + "title": "Data", + "type": "array" + }, + "limit": { + "title": "Limit", + "type": "integer" + }, + "page": { + "title": "Page", + "type": "integer" + }, + "total": { + "title": "Total", + "type": "integer" + } + }, + "required": [ + "data", + "total", + "page", + "limit" + ], + "title": "CompatibleRunListResponse", + "type": "object" + }, + "CompatibleRunResponse": { + "description": "A run that has a completed step matching a criteria's step_id.", + "properties": { + "agent_run_id": { + "format": "uuid", + "title": "Agent Run Id", + "type": "string" + }, + "agent_step_run_id": { + "format": "uuid", + "title": "Agent Step Run Id", + "type": "string" + }, + "completed_at": { "anyOf": [ { - "minimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Chunk overlap (custom mode only).", - "title": "Chunk Overlap" + "title": "Completed At" }, - "chunk_size": { + "input_preview": { "anyOf": [ { - "exclusiveMinimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Chunk size (custom mode only).", - "title": "Chunk Size" + "title": "Input Preview" }, - "compaction_prompt": { + "output_storage_key": { "anyOf": [ { "type": "string" @@ -2842,36 +2876,56 @@ "type": "null" } ], - "description": "Custom prompt used when compacting older entries. When set, entries that exceed a threshold are summarized into a new entry before being soft-deleted.", - "title": "Compaction Prompt" + "title": "Output Storage Key" }, - "description": { + "run_status": { "anyOf": [ { - "maxLength": 1000, "type": "string" }, { "type": "null" } ], - "description": "Optional description of the bank's purpose.", - "title": "Description" + "title": "Run Status" }, - "dimensions": { + "started_at": { "anyOf": [ { - "exclusiveMinimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Embedding dimensions (custom mode only).", - "title": "Dimensions" + "title": "Started At" + } + }, + "required": [ + "agent_run_id", + "agent_step_run_id", + "completed_at", + "output_storage_key" + ], + "title": "CompatibleRunResponse", + "type": "object" + }, + "ContentEmbeddingResponse": { + "description": "Response model for content embedding.", + "properties": { + "batch_duration": { + "title": "Batch Duration", + "type": "number" }, - "embedding_model": { + "batch_size": { + "title": "Batch Size", + "type": "integer" + }, + "id": { + "title": "Id", + "type": "string" + }, + "media_name": { "anyOf": [ { "type": "string" @@ -2880,164 +2934,132 @@ "type": "null" } ], - "description": "Custom embedding model (custom mode only).", - "title": "Embedding Model" + "title": "Media Name" }, - "max_age_days": { + "page_number": { "anyOf": [ { - "exclusiveMinimum": 0.0, "type": "integer" }, { "type": "null" } ], - "description": "Max entry age in days before compaction. Checked inline after each write and by the hourly background sweep.", - "title": "Max Age Days" + "title": "Page Number" }, - "max_size_tokens": { + "source_mime": { "anyOf": [ { - "exclusiveMinimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Max total tokens (per partition) before compaction. Checked inline after each write and by the hourly background sweep.", - "title": "Max Size Tokens" + "title": "Source Mime" }, - "max_turns": { + "source_url": { "anyOf": [ { - "exclusiveMinimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Max conversation turns (per partition) before compaction. Checked inline after each write and by the hourly background sweep.", - "title": "Max Turns" + "title": "Source Url" }, - "mode": { - "default": "fast_and_cheap", - "description": "Embedding quality / cost trade-off. One of: fast_and_cheap, balanced, slow_and_thorough, custom.", - "title": "Mode", - "type": "string" - }, - "name": { - "description": "Memory bank name.", - "maxLength": 255, - "minLength": 1, - "title": "Name", + "text": { + "title": "Text", "type": "string" }, - "retention_days": { - "anyOf": [ - { - "exclusiveMinimum": 0.0, - "type": "integer" - }, - { - "type": "null" - } - ], - "default": 30, - "description": "Content source retention in days.", - "title": "Retention Days" + "text_end": { + "title": "Text End", + "type": "integer" }, - "type": { - "default": "conversation", - "description": "Bank type. 'conversation' for chat-turn data with conversation_key + speaker; 'general' for flat entries with optional group_key.", - "title": "Type", - "type": "string" - } - }, - "required": [ - "name" - ], - "title": "CreateMemoryBankBody", - "type": "object" - }, - "CreateSolutionRequest": { - "description": "Request model for creating a new solution", - "properties": { - "description": { - "default": "", - "description": "Description of the solution", - "title": "Description", - "type": "string" + "text_start": { + "title": "Text Start", + "type": "integer" }, - "name": { - "description": "Name of the solution", - "title": "Name", - "type": "string" + "vector": { + "items": { + "type": "number" + }, + "title": "Vector", + "type": "array" } }, "required": [ - "name" + "id", + "text_start", + "text_end", + "text", + "vector", + "batch_size", + "batch_duration" ], - "title": "CreateSolutionRequest", + "title": "ContentEmbeddingResponse", "type": "object" }, - "CreateSourceBody": { - "description": "Request body for creating a content source.", + "CreateAlertConfigRequest": { "properties": { - "chunk_overlap": { + "agent_id": { "anyOf": [ { - "minimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Chunk overlap for content processing.", - "title": "Chunk Overlap" + "description": "Agent ID (for agent alerts)", + "title": "Agent Id" }, - "chunk_size": { + "alert_type": { + "description": "Alert type", + "title": "Alert Type", + "type": "string" + }, + "cooldown_minutes": { "anyOf": [ { - "exclusiveMinimum": 0.0, "type": "integer" }, { "type": "null" } ], - "description": "Chunk size for content processing.", - "title": "Chunk Size" + "description": "Cooldown period in minutes. Omit to use the per-alert-type default (1440 for credit alerts, 60 otherwise).", + "title": "Cooldown Minutes" }, - "content_filter": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Content filter type.", - "title": "Content Filter" + "distribution_type": { + "default": "owner", + "description": "Distribution type (owner, owner_admins, selected_members)", + "title": "Distribution Type", + "type": "string" }, - "dimensions": { + "enabled": { + "default": true, + "description": "Whether the alert config is enabled", + "title": "Enabled", + "type": "boolean" + }, + "recipient_user_ids": { "anyOf": [ { - "exclusiveMinimum": 0.0, - "type": "integer" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "description": "Embedding dimensions override.", - "title": "Dimensions" + "description": "User IDs for selected_members distribution", + "title": "Recipient User Ids" }, - "embedding_model": { + "source_connection_id": { "anyOf": [ { "type": "string" @@ -3046,43 +3068,49 @@ "type": "null" } ], - "description": "Embedding model override.", - "title": "Embedding Model" + "description": "Source connection ID (for source alerts)", + "title": "Source Connection Id" }, - "index_mode": { + "threshold": { "anyOf": [ { - "$ref": "#/components/schemas/SourceIndexMode" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Index mode for custom_index sources: fast_and_cheap (default), balanced, slow_and_thorough, or custom." - }, - "media_types": { + "description": "Threshold configuration", + "title": "Threshold" + } + }, + "required": [ + "alert_type" + ], + "title": "CreateAlertConfigRequest", + "type": "object" + }, + "CreateEvaluationCriteriaRequest": { + "description": "Request body for creating an evaluation criteria.\n\nThe evaluation mode, retry settings, and sample frequency are set at the\nagent level, not per-criteria.", + "properties": { + "description": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "type": "string" }, { "type": "null" } ], - "description": "Media kinds to extract from indexed content and embed as multi-modal KB chunks. Subset of ['images', 'video']. Only kinds the source's embedder can index are honored; unsupported values are dropped. Omit / [] for text-only.", - "title": "Media Types" + "title": "Description" }, - "name": { - "description": "Source name.", - "maxLength": 255, - "minLength": 1, - "title": "Name", - "type": "string" + "enabled": { + "default": true, + "title": "Enabled", + "type": "boolean" }, - "polling": { + "evaluation_prompt": { "anyOf": [ { "type": "string" @@ -3091,299 +3119,264 @@ "type": "null" } ], - "description": "Polling interval (e.g. hourly, daily).", - "title": "Polling" + "title": "Evaluation Prompt" }, - "polling_action": { + "evaluation_tier": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/AgentEvaluationTier" }, { "type": "null" } - ], - "description": "Polling action.", - "title": "Polling Action" + ] }, - "polling_max_items": { + "expectation_config": { "anyOf": [ { - "exclusiveMinimum": 0.0, - "type": "integer" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Max items per poll.", - "title": "Polling Max Items" + "title": "Expectation Config" }, - "retention": { - "anyOf": [ - { - "exclusiveMinimum": 0.0, - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Retention period in days.", - "title": "Retention" + "pass_threshold": { + "default": 0.5, + "maximum": 1.0, + "minimum": 0.0, + "title": "Pass Threshold", + "type": "number" }, - "source_type": { - "description": "Source type: rss, website, or custom_index. The legacy value 'file_uploads' is accepted as an alias for custom_index.", - "title": "Source Type", + "step_id": { + "maxLength": 255, + "minLength": 1, + "title": "Step Id", "type": "string" - }, - "url_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "URL record ID (required for rss/website sources).", - "title": "Url Id" } }, "required": [ - "name", - "source_type" + "step_id" ], - "title": "CreateSourceBody", + "title": "CreateEvaluationCriteriaRequest", "type": "object" }, - "DmarcFailingSourceResponse": { + "CreateEvaluationResultRequest": { + "description": "Request body for recording an evaluation result.", "properties": { - "failed_count": { - "title": "Failed Count", - "type": "integer" + "agent_run_id": { + "format": "uuid", + "title": "Agent Run Id", + "type": "string" }, - "header_from": { + "agent_step_run_id": { "anyOf": [ { + "format": "uuid", "type": "string" }, { "type": "null" } ], - "title": "Header From" + "title": "Agent Step Run Id" }, - "source_ip": { - "title": "Source Ip", - "type": "string" - } - }, - "required": [ - "source_ip", - "failed_count" - ], - "title": "DmarcFailingSourceResponse", - "type": "object" - }, - "DmarcSummaryResponse": { - "properties": { - "dispositions": { - "additionalProperties": { - "type": "integer" - }, - "title": "Dispositions", - "type": "object" + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" }, - "failed_messages": { - "title": "Failed Messages", + "flagged": { + "default": false, + "title": "Flagged", + "type": "boolean" + }, + "retry_count": { + "default": 0, + "minimum": 0.0, + "title": "Retry Count", "type": "integer" }, - "monitored": { - "default": true, - "title": "Monitored", + "retry_triggered": { + "default": false, + "title": "Retry Triggered", "type": "boolean" }, - "pass_rate": { + "score": { "anyOf": [ { + "maximum": 1.0, + "minimum": 0.0, "type": "number" }, { "type": "null" } ], - "title": "Pass Rate" - }, - "passed_messages": { - "title": "Passed Messages", - "type": "integer" - }, - "report_count": { - "title": "Report Count", - "type": "integer" - }, - "top_failing_sources": { - "items": { - "$ref": "#/components/schemas/DmarcFailingSourceResponse" - }, - "title": "Top Failing Sources", - "type": "array" - }, - "total_messages": { - "title": "Total Messages", - "type": "integer" + "title": "Score" }, - "window_days": { - "title": "Window Days", - "type": "integer" + "status": { + "$ref": "#/components/schemas/EvaluationStatus" } }, "required": [ - "window_days", - "report_count", - "total_messages", - "passed_messages", - "failed_messages" + "agent_run_id", + "status" ], - "title": "DmarcSummaryResponse", + "title": "CreateEvaluationResultRequest", "type": "object" }, - "DnsProviderResponse": { + "CreateExperimentResponse": { "properties": { - "dashboard_url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Dashboard Url" - }, - "key": { - "title": "Key", - "type": "string" - }, - "mx_priority_separate": { - "default": true, - "title": "Mx Priority Separate", - "type": "boolean" - }, - "name": { - "title": "Name", + "experiment_id": { + "title": "Experiment Id", "type": "string" }, - "tips": { - "items": { - "type": "string" - }, - "title": "Tips", - "type": "array" - }, - "txt_quotes": { - "default": "strip", - "title": "Txt Quotes", + "status": { + "title": "Status", "type": "string" } }, "required": [ - "key", - "name" + "experiment_id", + "status" ], - "title": "DnsProviderResponse", + "title": "CreateExperimentResponse", "type": "object" }, - "DnsRecordResponse": { + "CreateKnowledgeBaseBody": { + "description": "Request body for creating a knowledge base.", "properties": { - "detail": { + "default_score_threshold": { "anyOf": [ { - "type": "string" + "maximum": 1.0, + "minimum": 0.0, + "type": "number" }, { "type": "null" } ], - "title": "Detail" - }, - "key": { - "title": "Key", - "type": "string" + "description": "Prefilled into Minimum Rerank Score on a new retrieval step in the editor. Not applied at retrieval time \u2014 the step's own value is used.", + "title": "Default Score Threshold" }, - "mx_host": { + "default_top_k": { "anyOf": [ { - "type": "string" + "exclusiveMinimum": 0.0, + "maximum": 200.0, + "type": "integer" }, { "type": "null" } ], - "title": "Mx Host" + "description": "Prefilled into Top K on a new retrieval step in the editor. Not applied at retrieval time.", + "title": "Default Top K" }, - "mx_priority": { + "default_top_n": { "anyOf": [ { + "exclusiveMinimum": 0.0, + "maximum": 200.0, "type": "integer" }, { "type": "null" } ], - "title": "Mx Priority" + "description": "Prefilled into Top N on a new retrieval step in the editor. Not applied at retrieval time \u2014 the step's own value is used.", + "title": "Default Top N" + }, + "description": { + "anyOf": [ + { + "maxLength": 1000, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional description.", + "title": "Description" }, "name": { + "description": "Knowledge base name.", + "maxLength": 255, + "minLength": 1, "title": "Name", "type": "string" }, - "ok": { - "title": "Ok", - "type": "boolean" - }, - "relative_name": { - "title": "Relative Name", - "type": "string" - }, - "type": { - "title": "Type", - "type": "string" + "reranker_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Reranker model to use \u2014 a `model_type` from `GET /models/rerankers`. Pass \"none\" to disable reranking (not a value from that list). Omit it for a default chosen from the sources (\"none\" when every source embeds media natively, whose chunks carry no text for a reranker to score). \"\" is accepted as a synonym for \"none\".", + "title": "Reranker Model" }, - "value": { - "title": "Value", - "type": "string" + "source_ids": { + "description": "List of source connection IDs to link.", + "items": { + "type": "string" + }, + "minItems": 1, + "title": "Source Ids", + "type": "array" } }, "required": [ - "key", - "type", "name", - "relative_name", - "value", - "ok" + "source_ids" ], - "title": "DnsRecordResponse", + "title": "CreateKnowledgeBaseBody", "type": "object" }, - "DocsSearchResultResponse": { + "CreateMemoryBankBody": { + "description": "Request body for creating a memory bank.", "properties": { - "anchor": { + "chunk_overlap": { "anyOf": [ { - "type": "string" + "minimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "title": "Anchor" + "description": "Chunk overlap (custom mode only).", + "title": "Chunk Overlap" }, - "doc_slug": { - "title": "Doc Slug", - "type": "string" + "chunk_size": { + "anyOf": [ + { + "exclusiveMinimum": 0.0, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Chunk size (custom mode only).", + "title": "Chunk Size" }, - "highlight": { + "compaction_prompt": { "anyOf": [ { "type": "string" @@ -3392,58 +3385,36 @@ "type": "null" } ], - "title": "Highlight" - }, - "score": { - "title": "Score", - "type": "number" + "description": "Custom prompt used when compacting older entries. When set, entries that exceed a threshold are summarized into a new entry before being soft-deleted.", + "title": "Compaction Prompt" }, - "snippet": { + "description": { "anyOf": [ { + "maxLength": 1000, "type": "string" }, { "type": "null" } ], - "title": "Snippet" + "description": "Optional description of the bank's purpose.", + "title": "Description" }, - "title": { - "title": "Title", - "type": "string" - } - }, - "required": [ - "doc_slug", - "title", - "snippet", - "score", - "anchor", - "highlight" - ], - "title": "DocsSearchResultResponse", - "type": "object" - }, - "EmailDomainResponse": { - "properties": { - "delegated": { - "default": false, - "title": "Delegated", - "type": "boolean" - }, - "dns_records": { - "items": { - "$ref": "#/components/schemas/DnsRecordResponse" - }, - "title": "Dns Records", - "type": "array" - }, - "domain": { - "title": "Domain", - "type": "string" + "dimensions": { + "anyOf": [ + { + "exclusiveMinimum": 0.0, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Embedding dimensions (custom mode only).", + "title": "Dimensions" }, - "error_message": { + "embedding_model": { "anyOf": [ { "type": "string" @@ -3452,148 +3423,144 @@ "type": "null" } ], - "title": "Error Message" - }, - "id": { - "format": "uuid", - "title": "Id", - "type": "string" - }, - "is_primary": { - "title": "Is Primary", - "type": "boolean" - }, - "kind": { - "title": "Kind", - "type": "string" + "description": "Custom embedding model (custom mode only).", + "title": "Embedding Model" }, - "last_checked_at": { + "max_age_days": { "anyOf": [ { - "format": "date-time", - "type": "string" + "exclusiveMinimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "title": "Last Checked At" + "description": "DEPRECATED and no longer applied. Age used to trigger compaction, which duplicated retention_days \u2014 both removed the same entries at the same age. Age now belongs solely to retention_days, which deletes; compaction triggers on max_size_tokens and max_turns. Rejected with 400 for clients sending Seclai-Version 2026-08-03 or later; accepted and stored but inert for older clients.", + "title": "Max Age Days" }, - "provider": { + "max_size_tokens": { "anyOf": [ { - "$ref": "#/components/schemas/DnsProviderResponse" + "exclusiveMinimum": 0.0, + "type": "integer" }, { "type": "null" } - ] + ], + "description": "Max total tokens (per partition) before compaction. Checked inline after each write and by the hourly background sweep.", + "title": "Max Size Tokens" }, - "regressing": { - "default": false, - "title": "Regressing", - "type": "boolean" + "max_turns": { + "anyOf": [ + { + "exclusiveMinimum": 0.0, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Max conversation turns (per partition) before compaction. Checked inline after each write and by the hourly background sweep.", + "title": "Max Turns" }, - "status": { - "title": "Status", + "mode": { + "default": "fast_and_cheap", + "description": "Embedding quality / cost trade-off. One of: fast_and_cheap, balanced, slow_and_thorough, custom.", + "title": "Mode", "type": "string" }, - "verified": { - "default": false, - "title": "Verified", - "type": "boolean" + "name": { + "description": "Memory bank name.", + "maxLength": 255, + "minLength": 1, + "title": "Name", + "type": "string" }, - "verified_at": { + "retention_days": { "anyOf": [ { - "format": "date-time", - "type": "string" + "exclusiveMinimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "title": "Verified At" + "description": "Retention in days \u2014 when entries are deleted outright, text and embeddings. This is the only age-based control; compaction triggers on max_size_tokens and max_turns. For clients sending Seclai-Version 2026-08-03 or later, omitting the field resolves per bank type: 90 days for a conversation bank, indefinite for a general bank. Older clients keep the previous default of 30 days for a conversation bank \u2014 unless a longer max_age_days was sent, which wins, since the window is never lowered beneath the only age the caller expressed \u2014 while a general bank keeps entries indefinitely. Send an explicit value (or null for indefinite) to be unambiguous on every version.", + "title": "Retention Days" }, - "zone_apex": { - "default": "", - "title": "Zone Apex", + "strip_quoted_reply_chains": { + "default": false, + "description": "Conversation banks only. When true, a conversation turn written to this bank has the quoted reply chain an email client prepends to a reply dropped from it. Only inbound (user) turns are affected, and only words in a run of at least ~40 matching a recent turn word for word are dropped (line wrapping and punctuation at a word's edge are ignored). A word the sender changed is kept, including a one-character change inside a link, address or amount, unless the change is only to that edge punctuation.", + "title": "Strip Quoted Reply Chains", + "type": "boolean" + }, + "type": { + "default": "conversation", + "description": "Bank type. 'conversation' for chat-turn data with conversation_key + speaker; 'general' for flat entries with optional group_key.", + "title": "Type", "type": "string" } }, "required": [ - "id", - "domain", - "kind", - "status", - "is_primary" + "name" ], - "title": "EmailDomainResponse", + "title": "CreateMemoryBankBody", "type": "object" }, - "EmailDomainsListResponse": { + "CreateSolutionRequest": { + "description": "Request model for creating a new solution", "properties": { - "can_add_custom": { - "default": false, - "title": "Can Add Custom", - "type": "boolean" - }, - "can_add_vanity": { - "default": false, - "title": "Can Add Vanity", - "type": "boolean" - }, - "custom_plan_names": { - "items": { - "type": "string" - }, - "title": "Custom Plan Names", - "type": "array" - }, - "domains": { - "items": { - "$ref": "#/components/schemas/EmailDomainResponse" - }, - "title": "Domains", - "type": "array" - }, - "has_custom": { - "default": false, - "title": "Has Custom", - "type": "boolean" - }, - "has_vanity": { - "default": false, - "title": "Has Vanity", - "type": "boolean" + "description": { + "default": "", + "description": "Description of the solution", + "title": "Description", + "type": "string" }, - "vanity_plan_names": { - "items": { - "type": "string" - }, - "title": "Vanity Plan Names", - "type": "array" + "name": { + "description": "Name of the solution", + "title": "Name", + "type": "string" } }, - "title": "EmailDomainsListResponse", + "required": [ + "name" + ], + "title": "CreateSolutionRequest", "type": "object" }, - "EmailTriggerConfigResponse": { - "description": "An EMAIL_RECEIVED trigger's resolved address(es) and config.", + "CreateSourceBody": { + "description": "Request body for creating a content source.", "properties": { - "agent_id": { - "format": "uuid", - "title": "Agent Id", - "type": "string" + "chunk_overlap": { + "anyOf": [ + { + "minimum": 0.0, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Chunk overlap for content processing.", + "title": "Chunk Overlap" }, - "email_addresses": { - "items": { - "type": "string" - }, - "title": "Email Addresses", - "type": "array" + "chunk_size": { + "anyOf": [ + { + "exclusiveMinimum": 0.0, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Chunk size for content processing.", + "title": "Chunk Size" }, - "email_alias": { + "content_filter": { "anyOf": [ { "type": "string" @@ -3602,73 +3569,68 @@ "type": "null" } ], - "title": "Email Alias" + "description": "Content filter type.", + "title": "Content Filter" }, - "email_allowed_senders": { + "dimensions": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "exclusiveMinimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "title": "Email Allowed Senders" - }, - "email_ignore_auto_generated": { - "default": true, - "title": "Email Ignore Auto Generated", - "type": "boolean" - }, - "email_queue_on_quota": { - "default": false, - "title": "Email Queue On Quota", - "type": "boolean" + "description": "Embedding dimensions override.", + "title": "Dimensions" }, - "email_require_sender_auth": { - "default": true, - "title": "Email Require Sender Auth", - "type": "boolean" - }, - "trigger_id": { - "format": "uuid", - "title": "Trigger Id", - "type": "string" + "embedding_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Embedding model override \u2014 a `model_type` from `GET /models/embedders`, which also reports each embedder's `supported_input_media`. Defaults to the platform embedder (`default_model_type` on that endpoint) when omitted. Indexing images or video requires an embedder that lists that modality.", + "title": "Embedding Model" }, - "trigger_type": { - "title": "Trigger Type", - "type": "string" - } - }, - "required": [ - "trigger_id", - "agent_id", - "trigger_type" - ], - "title": "EmailTriggerConfigResponse", - "type": "object" - }, - "EvaluationCriteriaResponse": { - "description": "Response schema for evaluation criteria.", - "properties": { - "account_id": { - "format": "uuid", - "title": "Account Id", - "type": "string" + "index_mode": { + "anyOf": [ + { + "$ref": "#/components/schemas/SourceIndexMode" + }, + { + "type": "null" + } + ], + "description": "Index mode for custom_index sources: fast_and_cheap (default), balanced, slow_and_thorough, or custom." }, - "agent_id": { - "format": "uuid", - "title": "Agent Id", - "type": "string" + "media_types": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Media kinds to extract from indexed content and embed as multi-modal KB chunks. Subset of ['images', 'video']. Only kinds the source's embedder can index are honored (see `supported_input_media` on GET /models/embedders); unsupported values are dropped. Omit / [] for text-only.", + "title": "Media Types" }, - "created_at": { - "title": "Created At", + "name": { + "description": "Source name.", + "maxLength": 255, + "minLength": 1, + "title": "Name", "type": "string" }, - "description": { + "polling": { "anyOf": [ { "type": "string" @@ -3677,18 +3639,10 @@ "type": "null" } ], - "title": "Description" - }, - "enabled": { - "title": "Enabled", - "type": "boolean" - }, - "evaluation_mode": { - "description": "Runtime behavior mode. output_expectation (manual validation), eval_and_retry (every run + retry), sample_and_flag (sampled monitoring).", - "title": "Evaluation Mode", - "type": "string" + "description": "Polling interval (e.g. hourly, daily).", + "title": "Polling" }, - "evaluation_prompt": { + "polling_action": { "anyOf": [ { "type": "string" @@ -3697,59 +3651,41 @@ "type": "null" } ], - "title": "Evaluation Prompt" + "description": "Polling action.", + "title": "Polling Action" }, - "evaluation_tier": { + "polling_max_items": { "anyOf": [ { - "type": "string" + "exclusiveMinimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "title": "Evaluation Tier" + "description": "Max items per poll.", + "title": "Polling Max Items" }, - "expectation_config": { + "retention": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "exclusiveMinimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "title": "Expectation Config" + "description": "Retention period in days.", + "title": "Retention" }, - "id": { - "format": "uuid", - "title": "Id", + "source_type": { + "description": "Source type: rss, website, or custom_index. The legacy value 'file_uploads' is accepted as an alias for custom_index.", + "title": "Source Type", "type": "string" }, - "max_retries": { - "title": "Max Retries", - "type": "integer" - }, - "pass_threshold": { - "description": "Score cutoff for pass/fail, inclusive (0.0 to 1.0).", - "maximum": 1.0, - "minimum": 0.0, - "title": "Pass Threshold", - "type": "number" - }, - "result_summary": { - "additionalProperties": { - "type": "integer" - }, - "title": "Result Summary", - "type": "object" - }, - "retry_on_failure": { - "title": "Retry On Failure", - "type": "boolean" - }, - "step_id": { + "url_id": { "anyOf": [ { "type": "string" @@ -3758,266 +3694,173 @@ "type": "null" } ], - "title": "Step Id" - }, - "updated_at": { - "title": "Updated At", - "type": "string" + "description": "URL record ID (required for rss/website sources).", + "title": "Url Id" } }, "required": [ - "id", - "agent_id", - "account_id", - "description", - "evaluation_mode", - "enabled", - "step_id", - "expectation_config", - "max_retries", - "retry_on_failure", - "evaluation_prompt", - "pass_threshold", - "evaluation_tier", - "created_at", - "updated_at", - "result_summary" + "name", + "source_type" ], - "title": "EvaluationCriteriaResponse", + "title": "CreateSourceBody", "type": "object" }, - "EvaluationResultListResponse": { - "description": "Paginated list of evaluation results.", + "DmarcFailingSourceResponse": { "properties": { - "data": { - "items": { - "$ref": "#/components/schemas/EvaluationResultResponse" - }, - "title": "Data", - "type": "array" - }, - "limit": { - "title": "Limit", - "type": "integer" - }, - "page": { - "title": "Page", - "type": "integer" - }, - "total": { - "title": "Total", + "failed_count": { + "title": "Failed Count", "type": "integer" - } - }, - "required": [ - "data", - "total", - "page", - "limit" - ], - "title": "EvaluationResultListResponse", - "type": "object" - }, - "EvaluationResultResponse": { - "description": "Response schema for a single evaluation result.", - "properties": { - "agent_run_id": { - "format": "uuid", - "title": "Agent Run Id", - "type": "string" }, - "agent_step_run_id": { + "header_from": { "anyOf": [ { - "format": "uuid", "type": "string" }, { "type": "null" } ], - "title": "Agent Step Run Id" + "title": "Header From" }, - "created_at": { - "title": "Created At", + "source_ip": { + "title": "Source Ip", "type": "string" + } + }, + "required": [ + "source_ip", + "failed_count" + ], + "title": "DmarcFailingSourceResponse", + "type": "object" + }, + "DmarcSummaryResponse": { + "properties": { + "dispositions": { + "additionalProperties": { + "type": "integer" + }, + "title": "Dispositions", + "type": "object" }, - "criteria_id": { - "format": "uuid", - "title": "Criteria Id", - "type": "string" + "failed_messages": { + "title": "Failed Messages", + "type": "integer" }, - "details": { + "monitored": { + "default": true, + "title": "Monitored", + "type": "boolean" + }, + "pass_rate": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "number" }, { "type": "null" } ], - "description": "Evaluation details including explanation and raw LLM response.", - "title": "Details" + "title": "Pass Rate" }, - "evaluated_at": { - "title": "Evaluated At", - "type": "string" + "passed_messages": { + "title": "Passed Messages", + "type": "integer" }, - "flagged": { - "description": "True when the result was flagged for human review.", - "title": "Flagged", - "type": "boolean" - }, - "id": { - "format": "uuid", - "title": "Id", - "type": "string" - }, - "retry_count": { - "title": "Retry Count", + "report_count": { + "title": "Report Count", "type": "integer" }, - "retry_triggered": { - "title": "Retry Triggered", - "type": "boolean" + "top_failing_sources": { + "items": { + "$ref": "#/components/schemas/DmarcFailingSourceResponse" + }, + "title": "Top Failing Sources", + "type": "array" }, - "score": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "description": "LLM-assigned quality score between 0.0 (worst) and 1.0 (best).", - "title": "Score" + "total_messages": { + "title": "Total Messages", + "type": "integer" }, - "status": { - "description": "Outcome status: pending, passed, failed, skipped, or error.", - "title": "Status", - "type": "string" + "window_days": { + "title": "Window Days", + "type": "integer" } }, "required": [ - "id", - "criteria_id", - "agent_run_id", - "agent_step_run_id", - "status", - "retry_triggered", - "retry_count", - "flagged", - "evaluated_at", - "created_at" + "window_days", + "report_count", + "total_messages", + "passed_messages", + "failed_messages" ], - "title": "EvaluationResultResponse", + "title": "DmarcSummaryResponse", "type": "object" }, - "EvaluationResultSummaryResponse": { - "description": "Aggregated pass/fail/error counts and average score for a criteria.", + "DnsProviderResponse": { "properties": { - "average_score": { + "dashboard_url": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "description": "Mean score across all evaluated results, or null if none.", - "title": "Average Score" - }, - "error": { - "title": "Error", - "type": "integer" + "title": "Dashboard Url" }, - "failed": { - "title": "Failed", - "type": "integer" + "key": { + "title": "Key", + "type": "string" }, - "flagged": { - "title": "Flagged", - "type": "integer" + "mx_priority_separate": { + "default": true, + "title": "Mx Priority Separate", + "type": "boolean" }, - "passed": { - "title": "Passed", - "type": "integer" + "name": { + "title": "Name", + "type": "string" }, - "total": { - "title": "Total", - "type": "integer" - } - }, - "required": [ - "total", - "passed", - "failed", - "error", - "flagged" - ], - "title": "EvaluationResultSummaryResponse", - "type": "object" - }, - "EvaluationResultWithCriteriaListResponse": { - "description": "Paginated list of evaluation results with criteria context.", - "properties": { - "data": { + "tips": { "items": { - "$ref": "#/components/schemas/EvaluationResultWithCriteriaResponse" + "type": "string" }, - "title": "Data", + "title": "Tips", "type": "array" }, - "limit": { - "title": "Limit", - "type": "integer" - }, - "page": { - "title": "Page", - "type": "integer" - }, - "total": { - "title": "Total", - "type": "integer" + "txt_quotes": { + "default": "strip", + "title": "Txt Quotes", + "type": "string" } }, "required": [ - "data", - "total", - "page", - "limit" + "key", + "name" ], - "title": "EvaluationResultWithCriteriaListResponse", + "title": "DnsProviderResponse", "type": "object" }, - "EvaluationResultWithCriteriaResponse": { - "description": "Evaluation result including criteria context for aggregated listing.", + "DnsRecordResponse": { "properties": { - "agent_run_id": { - "format": "uuid", - "title": "Agent Run Id", - "type": "string" - }, - "agent_step_run_id": { + "detail": { "anyOf": [ { - "format": "uuid", "type": "string" }, { "type": "null" } ], - "title": "Agent Step Run Id" + "title": "Detail" }, - "created_at": { - "title": "Created At", + "key": { + "title": "Key", "type": "string" }, - "criteria_description": { + "mx_host": { "anyOf": [ { "type": "string" @@ -4026,66 +3869,69 @@ "type": "null" } ], - "title": "Criteria Description" - }, - "criteria_id": { - "format": "uuid", - "title": "Criteria Id", - "type": "string" + "title": "Mx Host" }, - "details": { + "mx_priority": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "integer" }, { "type": "null" } ], - "description": "Evaluation details including explanation and raw LLM response.", - "title": "Details" + "title": "Mx Priority" }, - "evaluated_at": { - "title": "Evaluated At", + "name": { + "title": "Name", "type": "string" }, - "flagged": { - "description": "True when the result was flagged for human review.", - "title": "Flagged", + "ok": { + "title": "Ok", "type": "boolean" }, - "id": { - "format": "uuid", - "title": "Id", + "relative_name": { + "title": "Relative Name", "type": "string" }, - "retry_count": { - "title": "Retry Count", - "type": "integer" - }, - "retry_triggered": { - "title": "Retry Triggered", - "type": "boolean" + "type": { + "title": "Type", + "type": "string" }, - "score": { + "value": { + "title": "Value", + "type": "string" + } + }, + "required": [ + "key", + "type", + "name", + "relative_name", + "value", + "ok" + ], + "title": "DnsRecordResponse", + "type": "object" + }, + "DocsSearchResultResponse": { + "properties": { + "anchor": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "description": "LLM-assigned quality score between 0.0 (worst) and 1.0 (best).", - "title": "Score" + "title": "Anchor" }, - "status": { - "description": "Outcome status: pending, passed, failed, skipped, or error.", - "title": "Status", + "doc_slug": { + "title": "Doc Slug", "type": "string" }, - "step_id": { + "highlight": { "anyOf": [ { "type": "string" @@ -4094,164 +3940,43 @@ "type": "null" } ], - "title": "Step Id" + "title": "Highlight" + }, + "score": { + "title": "Score", + "type": "number" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Snippet" + }, + "title": { + "title": "Title", + "type": "string" } }, "required": [ - "id", - "criteria_id", - "agent_run_id", - "agent_step_run_id", - "status", - "retry_triggered", - "retry_count", - "flagged", - "evaluated_at", - "created_at", - "step_id", - "criteria_description" - ], - "title": "EvaluationResultWithCriteriaResponse", - "type": "object" - }, - "EvaluationRunSummaryListResponse": { - "description": "Paginated list of per-run evaluation summaries.", - "properties": { - "data": { - "items": { - "$ref": "#/components/schemas/EvaluationRunSummaryResponse" - }, - "title": "Data", - "type": "array" - }, - "limit": { - "title": "Limit", - "type": "integer" - }, - "page": { - "title": "Page", - "type": "integer" - }, - "total": { - "title": "Total", - "type": "integer" - } - }, - "required": [ - "data", - "total", - "page", - "limit" - ], - "title": "EvaluationRunSummaryListResponse", - "type": "object" - }, - "EvaluationRunSummaryResponse": { - "description": "Per-run evaluation summary with pass/fail/error breakdown.", - "properties": { - "agent_run_id": { - "format": "uuid", - "title": "Agent Run Id", - "type": "string" - }, - "error_count": { - "title": "Error Count", - "type": "integer" - }, - "failed_count": { - "title": "Failed Count", - "type": "integer" - }, - "flagged_count": { - "title": "Flagged Count", - "type": "integer" - }, - "passed_count": { - "title": "Passed Count", - "type": "integer" - }, - "run_created_at": { - "title": "Run Created At", - "type": "string" - }, - "run_status": { - "description": "Status of the agent run (processing, completed, failed).", - "title": "Run Status", - "type": "string" - }, - "skipped_count": { - "title": "Skipped Count", - "type": "integer" - }, - "total_evaluations": { - "title": "Total Evaluations", - "type": "integer" - } - }, - "required": [ - "agent_run_id", - "run_status", - "run_created_at", - "total_evaluations", - "passed_count", - "failed_count", - "error_count", - "skipped_count", - "flagged_count" - ], - "title": "EvaluationRunSummaryResponse", - "type": "object" - }, - "EvaluationStatus": { - "description": "Result status of a single evaluation run.", - "enum": [ - "pending", - "passed", - "failed", - "skipped", - "error" + "doc_slug", + "title", + "snippet", + "score", + "anchor", + "highlight" ], - "title": "EvaluationStatus", - "type": "string" - }, - "ExamplePrompt": { - "additionalProperties": { - "type": "string" - }, + "title": "DocsSearchResultResponse", "type": "object" }, - "ExecutedActionResponse": { - "description": "A single executed action result.", + "EffortOptionsResponse": { + "description": "The reasoning-effort values a model accepts.", "properties": { - "action_type": { - "description": "Type of the executed action.", - "title": "Action Type", - "type": "string" - }, - "description": { - "description": "Human-readable description.", - "title": "Description", - "type": "string" - }, - "error": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Error message if failed.", - "title": "Error" - }, - "needs_clarification": { - "default": false, - "description": "True when the action paused for a clarifying question rather than failing. The created resource is kept and the question is in ``description``/``error``.", - "title": "Needs Clarification", - "type": "boolean" - }, - "resource_id": { + "default": { "anyOf": [ { "type": "string" @@ -4260,50 +3985,45 @@ "type": "null" } ], - "description": "ID of the affected resource.", - "title": "Resource Id" + "description": "The vendor's default level, when known.", + "title": "Default" }, - "resource_type": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Type of the affected resource.", - "title": "Resource Type" + "kind": { + "description": "`levels` today: `values` lists them.", + "title": "Kind", + "type": "string" }, - "success": { - "default": true, - "description": "Whether the action succeeded.", - "title": "Success", - "type": "boolean" + "values": { + "description": "Accepted values, weakest first.", + "items": { + "type": "string" + }, + "title": "Values", + "type": "array" } }, "required": [ - "action_type", - "description" + "kind" ], - "title": "ExecutedActionResponse", + "title": "EffortOptionsResponse", "type": "object" }, - "ExperimentDetailResponse": { + "EmailDomainResponse": { "properties": { - "completed_at": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Completed At" + "delegated": { + "default": false, + "title": "Delegated", + "type": "boolean" }, - "created_at": { - "title": "Created At", + "dns_records": { + "items": { + "$ref": "#/components/schemas/DnsRecordResponse" + }, + "title": "Dns Records", + "type": "array" + }, + "domain": { + "title": "Domain", "type": "string" }, "error_message": { @@ -4317,67 +4037,234 @@ ], "title": "Error Message" }, - "evaluation_complexity": { - "title": "Evaluation Complexity", + "id": { + "format": "uuid", + "title": "Id", "type": "string" }, - "evaluation_mode": { - "title": "Evaluation Mode", + "is_primary": { + "title": "Is Primary", + "type": "boolean" + }, + "kind": { + "title": "Kind", "type": "string" }, - "evaluator_model_id": { + "last_checked_at": { "anyOf": [ { + "format": "date-time", "type": "string" }, { "type": "null" } ], - "title": "Evaluator Model Id" + "title": "Last Checked At" }, - "id": { - "title": "Id", + "provider": { + "anyOf": [ + { + "$ref": "#/components/schemas/DnsProviderResponse" + }, + { + "type": "null" + } + ] + }, + "regressing": { + "default": false, + "title": "Regressing", + "type": "boolean" + }, + "status": { + "title": "Status", "type": "string" }, - "include_step_output_in_evaluation": { - "title": "Include Step Output In Evaluation", + "verified": { + "default": false, + "title": "Verified", "type": "boolean" }, - "json_template": { + "verified_at": { "anyOf": [ { + "format": "date-time", "type": "string" }, { "type": "null" } ], - "title": "Json Template" + "title": "Verified At" }, - "progress_current": { + "zone_apex": { + "default": "", + "title": "Zone Apex", + "type": "string" + } + }, + "required": [ + "id", + "domain", + "kind", + "status", + "is_primary" + ], + "title": "EmailDomainResponse", + "type": "object" + }, + "EmailDomainsListResponse": { + "properties": { + "can_add_custom": { + "default": false, + "title": "Can Add Custom", + "type": "boolean" + }, + "can_add_vanity": { + "default": false, + "title": "Can Add Vanity", + "type": "boolean" + }, + "custom_plan_names": { + "items": { + "type": "string" + }, + "title": "Custom Plan Names", + "type": "array" + }, + "domains": { + "items": { + "$ref": "#/components/schemas/EmailDomainResponse" + }, + "title": "Domains", + "type": "array" + }, + "has_custom": { + "default": false, + "title": "Has Custom", + "type": "boolean" + }, + "has_vanity": { + "default": false, + "title": "Has Vanity", + "type": "boolean" + }, + "vanity_plan_names": { + "items": { + "type": "string" + }, + "title": "Vanity Plan Names", + "type": "array" + } + }, + "title": "EmailDomainsListResponse", + "type": "object" + }, + "EmailTriggerConfigResponse": { + "description": "An EMAIL_RECEIVED trigger's resolved address(es) and config.", + "properties": { + "agent_id": { + "format": "uuid", + "title": "Agent Id", + "type": "string" + }, + "email_addresses": { + "items": { + "type": "string" + }, + "title": "Email Addresses", + "type": "array" + }, + "email_alias": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "title": "Progress Current" + "title": "Email Alias" }, - "progress_message": { + "email_allowed_senders": { "anyOf": [ { - "type": "string" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "title": "Progress Message" + "title": "Email Allowed Senders" }, - "progress_total": { + "email_ignore_auto_generated": { + "default": true, + "title": "Email Ignore Auto Generated", + "type": "boolean" + }, + "email_queue_on_quota": { + "default": false, + "title": "Email Queue On Quota", + "type": "boolean" + }, + "email_require_sender_auth": { + "default": true, + "title": "Email Require Sender Auth", + "type": "boolean" + }, + "trigger_id": { + "format": "uuid", + "title": "Trigger Id", + "type": "string" + }, + "trigger_type": { + "title": "Trigger Type", + "type": "string" + } + }, + "required": [ + "trigger_id", + "agent_id", + "trigger_type" + ], + "title": "EmailTriggerConfigResponse", + "type": "object" + }, + "EmbeddingModalityRateResponse": { + "description": "Per-modality rate for a multi-modal embedder.\n\nThe default ``credits`` field on :class:`EmbeddingModelResponse` is the\ntext rate (credits per ~1k English words). Embedders that index image or\nvideo chunks natively charge those modalities at a different rate and unit\n\u2014 e.g. Cohere Embed v4 prices images per record; Nova 2 Multimodal prices\nvideo per second. Surfacing the modality and unit lets a caller render an\nhonest cost breakdown alongside the text rate.", + "properties": { + "credits": { + "description": "Rate value in the unit below", + "title": "Credits", + "type": "number" + }, + "modality": { + "description": "Modality kind, e.g. image / video", + "title": "Modality", + "type": "string" + }, + "unit": { + "description": "Billing unit for this rate (credit_per_record / credit_per_second / credit_per_1000_tokens).", + "title": "Unit", + "type": "string" + } + }, + "required": [ + "modality", + "credits", + "unit" + ], + "title": "EmbeddingModalityRateResponse", + "type": "object" + }, + "EmbeddingModelListResponse": { + "description": "Legacy (header-less) response shape for the embedder catalog.", + "properties": { + "default_dimension": { "anyOf": [ { "type": "integer" @@ -4386,32 +4273,60 @@ "type": "null" } ], - "title": "Progress Total" - }, - "prompt": { - "title": "Prompt", - "type": "string" + "description": "Dimensions used with the default embedding model", + "title": "Default Dimension" }, - "result_data": { + "default_model_type": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Result Data" + "description": "Embedding model used when a source does not override it", + "title": "Default Model Type" }, - "selected_model_ids": { + "file_processing_credits_per_mb": { + "description": "Credits per MB for file processing at ingest", + "title": "File Processing Credits Per Mb", + "type": "number" + }, + "models": { + "description": "Available embedding models", "items": { - "type": "string" + "$ref": "#/components/schemas/EmbeddingModelResponse" }, - "title": "Selected Model Ids", + "title": "Models", "type": "array" }, - "selected_step_output": { + "storage_credits": { + "description": "Monthly storage credits per dimension count", + "items": { + "$ref": "#/components/schemas/EmbeddingStorageCreditsResponse" + }, + "title": "Storage Credits", + "type": "array" + } + }, + "required": [ + "models", + "storage_credits", + "file_processing_credits_per_mb" + ], + "title": "EmbeddingModelListResponse", + "type": "object" + }, + "EmbeddingModelResponse": { + "description": "Information about an embedding model.", + "properties": { + "credits": { + "description": "Estimated credits per 1,000 English words", + "title": "Credits", + "type": "number" + }, + "description": { "anyOf": [ { "type": "string" @@ -4420,148 +4335,90 @@ "type": "null" } ], - "title": "Selected Step Output" + "description": "Model description", + "title": "Description" }, - "started_at": { + "dimensions": { + "description": "Dimensions options", + "items": { + "type": "integer" + }, + "title": "Dimensions", + "type": "array" + }, + "is_new": { + "default": false, + "description": "Whether the model is newly released", + "title": "Is New", + "type": "boolean" + }, + "max_input_tokens": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Started At" + "description": "Max input tokens per request", + "title": "Max Input Tokens" }, - "status": { - "title": "Status", + "model_id": { + "description": "Model identifier", + "title": "Model Id", "type": "string" }, - "system_prompt": { - "title": "System Prompt", + "model_type": { + "description": "Full model type identifier (enum value). This is the value to send as embedding_model when creating a source.", + "title": "Model Type", "type": "string" - } - }, - "required": [ - "id", - "status", - "created_at", - "selected_model_ids", - "evaluation_mode", - "evaluation_complexity", - "prompt", - "system_prompt", - "evaluator_model_id", - "include_step_output_in_evaluation", - "selected_step_output", - "json_template", - "started_at", - "completed_at", - "error_message", - "progress_current", - "progress_total", - "progress_message", - "result_data" - ], - "title": "ExperimentDetailResponse", - "type": "object" - }, - "ExperimentListResponse": { - "description": "``GET /models/playground/experiments`` legacy/default shape; 2026-07-27+\nclients get the canonical ``{data, pagination}`` envelope.", - "properties": { - "experiments": { + }, + "mteb_retrieval_score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "MTEB retrieval score", + "title": "Mteb Retrieval Score" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Human-readable model name", + "title": "Name" + }, + "per_modality_rates": { + "description": "Non-text rates the vendor charges for this embedder (image, video, audio). Empty for text-only embedders.", "items": { - "$ref": "#/components/schemas/ExperimentSummaryResponse" + "$ref": "#/components/schemas/EmbeddingModalityRateResponse" }, - "title": "Experiments", + "title": "Per Modality Rates", "type": "array" }, - "total": { - "title": "Total", - "type": "integer" - } - }, - "required": [ - "experiments", - "total" - ], - "title": "ExperimentListResponse", - "type": "object" - }, - "ExperimentSummaryResponse": { - "properties": { - "created_at": { - "title": "Created At", - "type": "string" - }, - "evaluation_complexity": { - "title": "Evaluation Complexity", - "type": "string" - }, - "evaluation_mode": { - "title": "Evaluation Mode", - "type": "string" - }, - "id": { - "title": "Id", - "type": "string" - }, - "selected_model_ids": { - "items": { - "type": "string" - }, - "title": "Selected Model Ids", - "type": "array" - }, - "status": { - "title": "Status", - "type": "string" - } - }, - "required": [ - "id", - "status", - "created_at", - "selected_model_ids", - "evaluation_mode", - "evaluation_complexity" - ], - "title": "ExperimentSummaryResponse", - "type": "object" - }, - "ExportFormat": { - "description": "Supported export file formats.", - "enum": [ - "jsonl", - "csv", - "parquet", - "zip" - ], - "title": "ExportFormat", - "type": "string" - }, - "ExportListResponse": { - "description": "Paginated list of export jobs.", - "properties": { - "data": { - "items": {}, - "title": "Data", - "type": "array" + "provider": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Model provider identifier", + "title": "Provider" }, - "pagination": { - "$ref": "#/components/schemas/PaginationResponse" - } - }, - "required": [ - "data", - "pagination" - ], - "title": "ExportListResponse", - "type": "object" - }, - "GenerateAgentStepsRequest": { - "properties": { - "agent_description": { + "speed": { "anyOf": [ { "type": "string" @@ -4570,15 +4427,14 @@ "type": "null" } ], - "description": "Agent description for additional AI context.", - "title": "Agent Description" + "description": "Model processing speed", + "title": "Speed" }, - "agent_steps": { + "supported_input_media": { "anyOf": [ { "items": { - "additionalProperties": true, - "type": "object" + "type": "string" }, "type": "array" }, @@ -4586,16 +4442,25 @@ "type": "null" } ], - "description": "Current agent step hierarchy for context when modifying.", - "title": "Agent Steps" + "description": "Modalities the embedder accepts on input (short kinds like text / image / video, or full MIMEs). null means text-only. A source only honours a media_types entry its embedder lists here.", + "title": "Supported Input Media" }, - "mode": { - "default": "generate_full", - "description": "'generate_full' to create from scratch, 'modify_workflow' to refine.", - "title": "Mode", - "type": "string" + "supported_languages": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Supported languages", + "title": "Supported Languages" }, - "trigger_type": { + "url": { "anyOf": [ { "type": "string" @@ -4604,50 +4469,58 @@ "type": "null" } ], - "description": "Agent trigger type for context (e.g. 'dynamic_input', 'content_added').", - "title": "Trigger Type" + "description": "Model documentation URL", + "title": "Url" + } + }, + "required": [ + "model_id", + "model_type", + "dimensions", + "credits" + ], + "title": "EmbeddingModelResponse", + "type": "object" + }, + "EmbeddingStorageCreditsResponse": { + "description": "Monthly storage credits per stored record at a dimension count.", + "properties": { + "credits": { + "description": "Credits per record per month", + "title": "Credits", + "type": "integer" }, - "user_input": { - "description": "Natural language description of the desired agent workflow.", - "title": "User Input", - "type": "string" + "dimensions": { + "description": "Number of embedding dimensions", + "title": "Dimensions", + "type": "integer" } }, "required": [ - "user_input" + "dimensions", + "credits" ], - "title": "GenerateAgentStepsRequest", + "title": "EmbeddingStorageCreditsResponse", "type": "object" }, - "GenerateAgentStepsResponse": { + "EvaluationCriteriaResponse": { + "description": "Response schema for evaluation criteria.", "properties": { - "agent_config": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Suggested agent-level configuration, if any.", - "title": "Agent Config" + "account_id": { + "format": "uuid", + "title": "Account Id", + "type": "string" }, - "conversation_id": { - "description": "Conversation turn ID for tracking.", - "title": "Conversation Id", + "agent_id": { + "format": "uuid", + "title": "Agent Id", "type": "string" }, - "example_prompts": { - "description": "Example natural-language prompts that demonstrate the capabilities of this AI assistant for the given mode.", - "items": { - "$ref": "#/components/schemas/ExamplePrompt" - }, - "title": "Example Prompts", - "type": "array" + "created_at": { + "title": "Created At", + "type": "string" }, - "intent_assessment": { + "description": { "anyOf": [ { "type": "string" @@ -4656,408 +4529,331 @@ "type": "null" } ], - "description": "How the assistant interpreted the request: 'clear' when steps were generated, or an ask-path value (e.g. 'ambiguous_output', 'cannot_build') when it returned no steps and put a clarifying question or blocker in `note`. Mirrors the MCP surface so callers can distinguish a clarification pause from a hard failure.", - "title": "Intent Assessment" + "title": "Description" }, - "note": { - "description": "AI explanation of the proposed workflow.", - "title": "Note", - "type": "string" + "enabled": { + "title": "Enabled", + "type": "boolean" }, - "steps": { - "description": "Generated agent steps.", - "items": { - "additionalProperties": true, - "type": "object" - }, - "title": "Steps", - "type": "array" + "evaluation_mode": { + "description": "Runtime behavior mode. output_expectation (manual validation), eval_and_retry (every run + retry), sample_and_flag (sampled monitoring).", + "title": "Evaluation Mode", + "type": "string" }, - "success": { - "description": "Whether steps were successfully generated.", - "title": "Success", - "type": "boolean" - } - }, - "required": [ - "conversation_id", - "steps", - "note", - "success" - ], - "title": "GenerateAgentStepsResponse", - "type": "object" - }, - "GenerateStepConfigRequest": { - "properties": { - "agent_steps": { + "evaluation_prompt": { "anyOf": [ { - "items": { - "additionalProperties": true, - "type": "object" - }, - "type": "array" + "type": "string" }, { "type": "null" } ], - "description": "Current agent step hierarchy for context.", - "title": "Agent Steps" + "title": "Evaluation Prompt" }, - "current_config": { + "evaluation_tier": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "Current step configuration to refine, if any.", - "title": "Current Config" + "title": "Evaluation Tier" }, - "step_id": { + "expectation_config": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "ID of the specific step to refine. Omit for new steps.", - "title": "Step Id" + "title": "Expectation Config" }, - "step_type": { - "description": "The step type to generate config for (e.g. 'regex_replace', 'gate', 'text', 'prompt_call', 'retrieval').", - "title": "Step Type", + "id": { + "format": "uuid", + "title": "Id", "type": "string" }, - "user_input": { - "description": "Natural language description of what the step should do.", - "title": "User Input", - "type": "string" - } - }, - "required": [ - "step_type", - "user_input" - ], - "title": "GenerateStepConfigRequest", - "type": "object" - }, - "GenerateStepConfigResponse": { - "properties": { - "conversation_id": { - "description": "Conversation turn ID for tracking.", - "title": "Conversation Id", - "type": "string" + "max_retries": { + "title": "Max Retries", + "type": "integer" }, - "example_prompts": { - "description": "Example natural-language prompts that demonstrate the capabilities of this AI assistant for the given step type.", - "items": { - "$ref": "#/components/schemas/ExamplePrompt" + "pass_threshold": { + "description": "Score cutoff for pass/fail, inclusive (0.0 to 1.0).", + "maximum": 1.0, + "minimum": 0.0, + "title": "Pass Threshold", + "type": "number" + }, + "result_summary": { + "additionalProperties": { + "type": "integer" }, - "title": "Example Prompts", - "type": "array" + "title": "Result Summary", + "type": "object" }, - "note": { - "description": "AI explanation of the proposed configuration.", - "title": "Note", - "type": "string" + "retry_on_failure": { + "title": "Retry On Failure", + "type": "boolean" }, - "resulting_config": { + "step_id": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "The proposed step configuration.", - "title": "Resulting Config" + "title": "Step Id" }, - "step_type": { - "description": "The step type that was generated.", - "title": "Step Type", + "updated_at": { + "title": "Updated At", "type": "string" - }, - "success": { - "description": "Whether a valid configuration was generated.", - "title": "Success", - "type": "boolean" } }, "required": [ - "conversation_id", - "step_type", - "note", - "success" + "id", + "agent_id", + "account_id", + "description", + "evaluation_mode", + "enabled", + "step_id", + "expectation_config", + "max_retries", + "retry_on_failure", + "evaluation_prompt", + "pass_threshold", + "evaluation_tier", + "created_at", + "updated_at", + "result_summary" ], - "title": "GenerateStepConfigResponse", + "title": "EvaluationCriteriaResponse", "type": "object" }, - "GenerationTierListResponse": { - "description": "``GET /models/generation-tiers`` legacy/default shape; 2026-07-27+ clients\nget the canonical ``{data, pagination}`` envelope.", + "EvaluationResultListResponse": { + "description": "Paginated list of evaluation results.", "properties": { - "tiers": { + "data": { "items": { - "$ref": "#/components/schemas/GenerationTierResponse" + "$ref": "#/components/schemas/EvaluationResultResponse" }, - "title": "Tiers", + "title": "Data", "type": "array" + }, + "limit": { + "title": "Limit", + "type": "integer" + }, + "page": { + "title": "Page", + "type": "integer" + }, + "total": { + "title": "Total", + "type": "integer" } }, "required": [ - "tiers" + "data", + "total", + "page", + "limit" ], - "title": "GenerationTierListResponse", + "title": "EvaluationResultListResponse", "type": "object" }, - "GenerationTierResponse": { + "EvaluationResultResponse": { + "description": "Response schema for a single evaluation result.", "properties": { - "credits_per_unit": { + "agent_run_id": { + "format": "uuid", + "title": "Agent Run Id", + "type": "string" + }, + "agent_step_run_id": { "anyOf": [ { - "type": "integer" + "format": "uuid", + "type": "string" }, { "type": "null" } ], - "title": "Credits Per Unit" - }, - "modality": { - "title": "Modality", - "type": "string" + "title": "Agent Step Run Id" }, - "model_id": { - "title": "Model Id", + "created_at": { + "title": "Created At", "type": "string" }, - "model_name": { - "title": "Model Name", + "criteria_id": { + "format": "uuid", + "title": "Criteria Id", "type": "string" }, - "price_label": { + "details": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Price Label" + "description": "Evaluation details including explanation and raw LLM response.", + "title": "Details" }, - "tier": { - "title": "Tier", + "evaluated_at": { + "title": "Evaluated At", "type": "string" }, - "unit_label": { + "flagged": { + "description": "True when the result was flagged for human review.", + "title": "Flagged", + "type": "boolean" + }, + "id": { + "format": "uuid", + "title": "Id", + "type": "string" + }, + "retry_count": { + "title": "Retry Count", + "type": "integer" + }, + "retry_triggered": { + "title": "Retry Triggered", + "type": "boolean" + }, + "score": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "title": "Unit Label" + "description": "LLM-assigned quality score between 0.0 (worst) and 1.0 (best).", + "title": "Score" + }, + "status": { + "description": "Outcome status: pending, passed, failed, skipped, or error.", + "title": "Status", + "type": "string" } }, "required": [ - "modality", - "tier", - "model_id", - "model_name", - "credits_per_unit", - "unit_label", - "price_label" + "id", + "criteria_id", + "agent_run_id", + "agent_step_run_id", + "status", + "retry_triggered", + "retry_count", + "flagged", + "evaluated_at", + "created_at" ], - "title": "GenerationTierResponse", + "title": "EvaluationResultResponse", "type": "object" }, - "GovernanceAiAcceptResponse": { - "description": "Response from accepting a governance AI assistant plan.", + "EvaluationResultSummaryResponse": { + "description": "Aggregated pass/fail/error counts and average score for a criteria.", "properties": { - "actions_applied": { - "description": "Results of each action that was executed.", - "items": { - "$ref": "#/components/schemas/AppliedActionResponse" - }, - "title": "Actions Applied", - "type": "array" - }, - "conversation_id": { - "description": "Conversation ID that was accepted.", - "title": "Conversation Id", - "type": "string" - }, - "error": { + "average_score": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "description": "Overall error message if the plan failed, or null.", - "title": "Error" + "description": "Mean score across all evaluated results, or null if none.", + "title": "Average Score" }, - "success": { - "description": "Whether all actions were applied successfully.", - "title": "Success", - "type": "boolean" + "error": { + "title": "Error", + "type": "integer" + }, + "failed": { + "title": "Failed", + "type": "integer" + }, + "flagged": { + "title": "Flagged", + "type": "integer" + }, + "passed": { + "title": "Passed", + "type": "integer" + }, + "total": { + "title": "Total", + "type": "integer" } }, "required": [ - "conversation_id", - "actions_applied", - "success" - ], - "title": "GovernanceAiAcceptResponse", - "type": "object" - }, - "GovernanceAiAssistantResponse": { - "description": "Response from the governance AI assistant generate endpoint.", - "properties": { - "conversation_id": { - "description": "Conversation ID to accept or decline this plan.", - "title": "Conversation Id", - "type": "string" - }, - "example_prompts": { - "description": "Example natural-language prompts that demonstrate the capabilities of the governance AI assistant.", - "items": { - "$ref": "#/components/schemas/ExamplePrompt" - }, - "title": "Example Prompts", - "type": "array" - }, - "note": { - "description": "AI-generated summary of the proposed changes.", - "title": "Note", - "type": "string" - }, - "prompt_call_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Prompt call ID for credit tracking, or null.", - "title": "Prompt Call Id" - }, - "proposed_actions": { - "description": "Ordered list of policy actions the AI proposes to execute.", - "items": { - "$ref": "#/components/schemas/ProposedPolicyActionResponse" - }, - "title": "Proposed Actions", - "type": "array" - }, - "success": { - "description": "Whether the plan was generated successfully.", - "title": "Success", - "type": "boolean" - } - }, - "required": [ - "conversation_id", - "note", - "proposed_actions", - "success" + "total", + "passed", + "failed", + "error", + "flagged" ], - "title": "GovernanceAiAssistantResponse", + "title": "EvaluationResultSummaryResponse", "type": "object" }, - "HTTPValidationError": { + "EvaluationResultWithCriteriaListResponse": { + "description": "Paginated list of evaluation results with criteria context.", "properties": { - "detail": { + "data": { "items": { - "$ref": "#/components/schemas/ValidationError" + "$ref": "#/components/schemas/EvaluationResultWithCriteriaResponse" }, - "title": "Detail", + "title": "Data", "type": "array" - } - }, - "title": "HTTPValidationError", - "type": "object" - }, - "ImportFieldErrorModel": { - "description": "Single agent_definition validation error with source position.", - "properties": { - "column": { - "description": "1-indexed column in `source`.", - "title": "Column", - "type": "integer" }, - "line": { - "description": "1-indexed line in `source`.", - "title": "Line", + "limit": { + "title": "Limit", "type": "integer" }, - "message": { - "description": "Human-readable description of the problem.", - "title": "Message", - "type": "string" + "page": { + "title": "Page", + "type": "integer" }, - "path": { - "description": "Dotted path of the offending field, e.g. `agent.definition.child_steps[0].step_type`.", - "title": "Path", - "type": "string" + "total": { + "title": "Total", + "type": "integer" } }, "required": [ - "line", - "column", - "path", - "message" + "data", + "total", + "page", + "limit" ], - "title": "ImportFieldErrorModel", + "title": "EvaluationResultWithCriteriaListResponse", "type": "object" }, - "ImportSkipResponse": { - "description": "One item that was not applied during an agent import.\n\nUsed as the element type for ``import_warnings`` on every\nresponse model that accepts an ``agent_definition`` payload.\nSee ``services.agent_definition_import.AgentImportSkip`` for the\nfull category list.\n\nLives here (not on each router) so the authenticated and public\nAPI responses share one definition \u2014 keeping the shape that\nclients (UI modal, MCP, OpenAPI consumers) depend on aligned.", + "EvaluationResultWithCriteriaResponse": { + "description": "Evaluation result including criteria context for aggregated listing.", "properties": { - "category": { - "description": "The kind of item that was skipped or substituted: 'schedule', 'evaluation_criteria', 'alert_config', 'alert_recipient', 'governance_policy', 'governance_kb_link', 'solution_link'.", - "title": "Category", + "agent_run_id": { + "format": "uuid", + "title": "Agent Run Id", "type": "string" }, - "details": { - "additionalProperties": true, - "description": "Category-specific identifiers for the skipped item (step_id, alert_type, kb_name, etc.). Stable keys per category; absent keys are simply not applicable.", - "title": "Details", - "type": "object" - }, - "message": { - "description": "Human-readable explanation of what was skipped and why.", - "title": "Message", - "type": "string" - } - }, - "required": [ - "category", - "message" - ], - "title": "ImportSkipResponse", - "type": "object" - }, - "InboundEmailRejectionResponse": { - "description": "An inbound email that was discarded without running an agent.", - "properties": { - "agent_id": { + "agent_step_run_id": { "anyOf": [ { "format": "uuid", @@ -5067,52 +4863,81 @@ "type": "null" } ], - "title": "Agent Id" + "title": "Agent Step Run Id" }, "created_at": { "title": "Created At", "type": "string" }, - "id": { + "criteria_description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Criteria Description" + }, + "criteria_id": { "format": "uuid", - "title": "Id", + "title": "Criteria Id", "type": "string" }, - "message_id": { + "details": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Message Id" + "description": "Evaluation details including explanation and raw LLM response.", + "title": "Details" }, - "reason": { - "title": "Reason", + "evaluated_at": { + "title": "Evaluated At", "type": "string" }, - "recipient": { - "title": "Recipient", - "type": "string" + "flagged": { + "description": "True when the result was flagged for human review.", + "title": "Flagged", + "type": "boolean" }, - "sender": { - "title": "Sender", + "id": { + "format": "uuid", + "title": "Id", "type": "string" }, - "sender_ip": { + "retry_count": { + "title": "Retry Count", + "type": "integer" + }, + "retry_triggered": { + "title": "Retry Triggered", + "type": "boolean" + }, + "score": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "title": "Sender Ip" + "description": "LLM-assigned quality score between 0.0 (worst) and 1.0 (best).", + "title": "Score" }, - "subject": { + "status": { + "description": "Outcome status: pending, passed, failed, skipped, or error.", + "title": "Status", + "type": "string" + }, + "step_id": { "anyOf": [ { "type": "string" @@ -5121,45 +4946,146 @@ "type": "null" } ], - "title": "Subject" + "title": "Step Id" } }, "required": [ "id", + "criteria_id", + "agent_run_id", + "agent_step_run_id", + "status", + "retry_triggered", + "retry_count", + "flagged", + "evaluated_at", "created_at", - "recipient", - "sender", - "sender_ip", - "reason", - "message_id", - "agent_id", - "subject" + "step_id", + "criteria_description" ], - "title": "InboundEmailRejectionResponse", + "title": "EvaluationResultWithCriteriaResponse", "type": "object" }, - "InboundEmailStatusResponse": { + "EvaluationRunSummaryListResponse": { + "description": "Paginated list of per-run evaluation summaries.", "properties": { - "paused": { - "title": "Paused", - "type": "boolean" + "data": { + "items": { + "$ref": "#/components/schemas/EvaluationRunSummaryResponse" + }, + "title": "Data", + "type": "array" }, - "queued_backlog": { - "title": "Queued Backlog", + "limit": { + "title": "Limit", + "type": "integer" + }, + "page": { + "title": "Page", + "type": "integer" + }, + "total": { + "title": "Total", "type": "integer" } }, "required": [ - "paused", - "queued_backlog" - ], - "title": "InboundEmailStatusResponse", + "data", + "total", + "page", + "limit" + ], + "title": "EvaluationRunSummaryListResponse", "type": "object" }, - "InlineTextReplaceRequest": { - "description": "Request model for inline text content replacement.", + "EvaluationRunSummaryResponse": { + "description": "Per-run evaluation summary with pass/fail/error breakdown.", "properties": { - "content_type": { + "agent_run_id": { + "format": "uuid", + "title": "Agent Run Id", + "type": "string" + }, + "error_count": { + "title": "Error Count", + "type": "integer" + }, + "failed_count": { + "title": "Failed Count", + "type": "integer" + }, + "flagged_count": { + "title": "Flagged Count", + "type": "integer" + }, + "passed_count": { + "title": "Passed Count", + "type": "integer" + }, + "run_created_at": { + "title": "Run Created At", + "type": "string" + }, + "run_status": { + "description": "Status of the agent run (processing, completed, failed).", + "title": "Run Status", + "type": "string" + }, + "skipped_count": { + "title": "Skipped Count", + "type": "integer" + }, + "total_evaluations": { + "title": "Total Evaluations", + "type": "integer" + } + }, + "required": [ + "agent_run_id", + "run_status", + "run_created_at", + "total_evaluations", + "passed_count", + "failed_count", + "error_count", + "skipped_count", + "flagged_count" + ], + "title": "EvaluationRunSummaryResponse", + "type": "object" + }, + "EvaluationStatus": { + "description": "Result status of a single evaluation run.", + "enum": [ + "pending", + "passed", + "failed", + "skipped", + "error" + ], + "title": "EvaluationStatus", + "type": "string" + }, + "ExamplePrompt": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "ExecutedActionResponse": { + "description": "A single executed action result.", + "properties": { + "action_type": { + "description": "Type of the executed action.", + "title": "Action Type", + "type": "string" + }, + "description": { + "description": "Human-readable description.", + "title": "Description", + "type": "string" + }, + "error": { "anyOf": [ { "type": "string" @@ -5168,29 +5094,28 @@ "type": "null" } ], - "default": "text/plain", - "description": "MIME type for the text content", - "title": "Content Type" + "description": "Error message if failed.", + "title": "Error" }, - "metadata": { + "needs_clarification": { + "default": false, + "description": "True when the action paused for a clarifying question rather than failing. The created resource is kept and the question is in ``description``/``error``.", + "title": "Needs Clarification", + "type": "boolean" + }, + "resource_id": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "Optional metadata object", - "title": "Metadata" - }, - "text": { - "description": "Text content to upload", - "title": "Text", - "type": "string" + "description": "ID of the affected resource.", + "title": "Resource Id" }, - "title": { + "resource_type": { "anyOf": [ { "type": "string" @@ -5199,20 +5124,26 @@ "type": "null" } ], - "description": "Optional title", - "title": "Title" + "description": "Type of the affected resource.", + "title": "Resource Type" + }, + "success": { + "default": true, + "description": "Whether the action succeeded.", + "title": "Success", + "type": "boolean" } }, "required": [ - "text" + "action_type", + "description" ], - "title": "InlineTextReplaceRequest", + "title": "ExecutedActionResponse", "type": "object" }, - "InlineTextUploadRequest": { - "description": "Request model for inline text uploads.", + "ExperimentDetailResponse": { "properties": { - "content_type": { + "completed_at": { "anyOf": [ { "type": "string" @@ -5221,29 +5152,40 @@ "type": "null" } ], - "default": "text/plain", - "description": "MIME type for the text content", - "title": "Content Type" + "title": "Completed At" }, - "metadata": { + "created_at": { + "title": "Created At", + "type": "string" + }, + "effort": { + "additionalProperties": { + "type": "string" + }, + "description": "The reasoning effort each model was run at, by model ID.", + "title": "Effort", + "type": "object" + }, + "error_message": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "Optional metadata object", - "title": "Metadata" + "title": "Error Message" }, - "text": { - "description": "Text content to upload", - "title": "Text", + "evaluation_complexity": { + "title": "Evaluation Complexity", "type": "string" }, - "title": { + "evaluation_mode": { + "title": "Evaluation Mode", + "type": "string" + }, + "evaluator_model_id": { "anyOf": [ { "type": "string" @@ -5252,127 +5194,50 @@ "type": "null" } ], - "description": "Optional title", - "title": "Title" - } - }, - "required": [ - "text" - ], - "title": "InlineTextUploadRequest", - "type": "object" - }, - "InsufficientCreditsDetail": { - "description": "``detail`` body for a 402 ``insufficient_credits`` response.", - "properties": { - "account_id": { - "description": "UUID of the account that ran out of credits.", - "title": "Account Id", - "type": "string" + "title": "Evaluator Model Id" }, - "error": { - "const": "insufficient_credits", - "description": "Stable machine-readable error code.", - "title": "Error", + "id": { + "title": "Id", "type": "string" }, - "message": { - "description": "Human-readable explanation.", - "title": "Message", - "type": "string" - } - }, - "required": [ - "error", - "message", - "account_id" - ], - "title": "InsufficientCreditsDetail", - "type": "object" - }, - "InsufficientCreditsResponse": { - "description": "402 envelope returned when the account has exhausted its credits.", - "properties": { - "detail": { - "$ref": "#/components/schemas/InsufficientCreditsDetail" - } - }, - "required": [ - "detail" - ], - "title": "InsufficientCreditsResponse", - "type": "object" - }, - "JsonValue": {}, - "KnowledgeBaseListResponseModel": { - "description": "Paginated list of knowledge bases.", - "properties": { - "knowledge_bases": { - "description": "List of knowledge bases on this page.", - "items": { - "$ref": "#/components/schemas/KnowledgeBaseResponseModel" - }, - "title": "Knowledge Bases", - "type": "array" + "include_step_output_in_evaluation": { + "title": "Include Step Output In Evaluation", + "type": "boolean" }, - "limit": { - "description": "Items per page.", - "title": "Limit", - "type": "integer" + "json_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Json Template" }, - "page": { - "description": "Current page number (1-based).", - "title": "Page", - "type": "integer" - }, - "total": { - "description": "Total number of knowledge bases.", - "title": "Total", - "type": "integer" - } - }, - "required": [ - "knowledge_bases", - "page", - "limit", - "total" - ], - "title": "KnowledgeBaseListResponseModel", - "type": "object" - }, - "KnowledgeBaseResponseModel": { - "description": "Response model for a single knowledge base.", - "properties": { - "created_at": { - "description": "ISO-8601 creation timestamp.", - "title": "Created At", - "type": "string" - }, - "default_score_threshold": { + "progress_current": { "anyOf": [ { - "type": "number" + "type": "integer" }, { "type": "null" } ], - "description": "Default minimum rerank score.", - "title": "Default Score Threshold" + "title": "Progress Current" }, - "default_top_k": { + "progress_message": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Default results after reranking.", - "title": "Default Top K" + "title": "Progress Message" }, - "default_top_n": { + "progress_total": { "anyOf": [ { "type": "integer" @@ -5381,38 +5246,43 @@ "type": "null" } ], - "description": "Default number of results to return.", - "title": "Default Top N" + "title": "Progress Total" }, - "description": { + "prompt": { + "title": "Prompt", + "type": "string" + }, + "result_data": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Optional description.", - "title": "Description" - }, - "id": { - "description": "Unique knowledge base identifier.", - "title": "Id", - "type": "string" + "title": "Result Data" }, - "name": { - "description": "Human-readable name.", - "title": "Name", - "type": "string" + "selected_model_ids": { + "items": { + "type": "string" + }, + "title": "Selected Model Ids", + "type": "array" }, - "readonly": { - "default": false, - "description": "Whether the knowledge base is read-only.", - "title": "Readonly", - "type": "boolean" + "selected_step_output": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Selected Step Output" }, - "reranker_model": { + "started_at": { "anyOf": [ { "type": "string" @@ -5421,134 +5291,171 @@ "type": "null" } ], - "description": "Reranker model in use.", - "title": "Reranker Model" + "title": "Started At" }, - "sources": { - "description": "Linked source connections.", - "items": { - "$ref": "#/components/schemas/SourceConnectionResponseModel" - }, - "title": "Sources", - "type": "array" + "status": { + "title": "Status", + "type": "string" }, - "updated_at": { - "description": "ISO-8601 last-update timestamp.", - "title": "Updated At", + "system_prompt": { + "title": "System Prompt", "type": "string" } }, "required": [ "id", - "name", + "status", "created_at", - "updated_at" + "selected_model_ids", + "evaluation_mode", + "evaluation_complexity", + "prompt", + "system_prompt", + "evaluator_model_id", + "include_step_output_in_evaluation", + "selected_step_output", + "json_template", + "started_at", + "completed_at", + "error_message", + "progress_current", + "progress_total", + "progress_message", + "result_data" ], - "title": "KnowledgeBase", + "title": "ExperimentDetailResponse", "type": "object" }, - "LinkResourcesRequest": { + "ExperimentListResponse": { + "description": "``GET /models/playground/experiments`` legacy/default shape; 2026-07-27+\nclients get the canonical ``{data, pagination}`` envelope.", "properties": { - "ids": { - "description": "Resource IDs to link", + "experiments": { "items": { - "format": "uuid", - "type": "string" + "$ref": "#/components/schemas/ExperimentSummaryResponse" }, - "minItems": 1, - "title": "Ids", + "title": "Experiments", "type": "array" + }, + "total": { + "title": "Total", + "type": "integer" } }, "required": [ - "ids" + "experiments", + "total" ], - "title": "LinkResourcesRequest", + "title": "ExperimentListResponse", "type": "object" }, - "MarkAiSuggestionRequest": { + "ExperimentSummaryResponse": { "properties": { - "accepted": { - "description": "True to accept the suggestion, false to decline it.", - "title": "Accepted", - "type": "boolean" + "created_at": { + "title": "Created At", + "type": "string" + }, + "evaluation_complexity": { + "title": "Evaluation Complexity", + "type": "string" + }, + "evaluation_mode": { + "title": "Evaluation Mode", + "type": "string" + }, + "id": { + "title": "Id", + "type": "string" + }, + "selected_model_ids": { + "items": { + "type": "string" + }, + "title": "Selected Model Ids", + "type": "array" + }, + "status": { + "title": "Status", + "type": "string" } }, "required": [ - "accepted" + "id", + "status", + "created_at", + "selected_model_ids", + "evaluation_mode", + "evaluation_complexity" ], - "title": "MarkAiSuggestionRequest", + "title": "ExperimentSummaryResponse", "type": "object" }, - "MarkConversationTurnRequest": { - "properties": { - "accepted": { - "description": "Whether the suggestion was accepted", - "title": "Accepted", - "type": "boolean" - } - }, - "required": [ - "accepted" + "ExportFormat": { + "description": "Supported export file formats.", + "enum": [ + "jsonl", + "csv", + "parquet", + "zip" ], - "title": "MarkConversationTurnRequest", - "type": "object" + "title": "ExportFormat", + "type": "string" }, - "MeResponse": { + "ExportListResponse": { + "description": "Paginated list of export jobs.", "properties": { - "account_id": { - "format": "uuid", - "title": "Account Id", - "type": "string" - }, - "organizations": { - "items": { - "$ref": "#/components/schemas/OrganizationInfoResponse" - }, - "title": "Organizations", + "data": { + "items": {}, + "title": "Data", "type": "array" + }, + "pagination": { + "$ref": "#/components/schemas/PaginationResponse" } }, "required": [ - "account_id", - "organizations" + "data", + "pagination" ], - "title": "MeResponse", + "title": "ExportListResponse", "type": "object" }, - "MemoryBankAiAssistantResponse": { - "description": "Response from the memory bank AI assistant.", + "GenerateAgentStepsRequest": { "properties": { - "config": { + "agent_description": { "anyOf": [ { - "$ref": "#/components/schemas/MemoryBankConfigResponse" + "type": "string" }, { "type": "null" } ], - "description": "Proposed configuration, or null." - }, - "conversation_id": { - "description": "Conversation ID for follow-up.", - "title": "Conversation Id", - "type": "string" - }, - "example_prompts": { - "description": "Example natural-language prompts that demonstrate the capabilities of the memory bank AI assistant.", - "items": { - "$ref": "#/components/schemas/ExamplePrompt" - }, - "title": "Example Prompts", - "type": "array" + "description": "Agent description for additional AI context.", + "title": "Agent Description" }, - "note": { - "description": "AI-generated explanation.", - "title": "Note", + "agent_steps": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Current agent step hierarchy for context when modifying.", + "title": "Agent Steps" + }, + "mode": { + "default": "generate_full", + "description": "'generate_full' to create from scratch, 'modify_workflow' to refine.", + "title": "Mode", "type": "string" }, - "prompt_call_id": { + "trigger_type": { "anyOf": [ { "type": "string" @@ -5557,39 +5464,50 @@ "type": "null" } ], - "description": "Prompt call ID for credit tracking.", - "title": "Prompt Call Id" + "description": "Agent trigger type for context (e.g. 'dynamic_input', 'content_added').", + "title": "Trigger Type" }, - "success": { - "default": false, - "description": "Whether generation succeeded.", - "title": "Success", - "type": "boolean" + "user_input": { + "description": "Natural language description of the desired agent workflow.", + "title": "User Input", + "type": "string" } }, "required": [ - "conversation_id", - "note" + "user_input" ], - "title": "MemoryBankAiAssistantResponse", + "title": "GenerateAgentStepsRequest", "type": "object" }, - "MemoryBankConfigResponse": { - "description": "Suggested memory bank configuration from the AI assistant.", + "GenerateAgentStepsResponse": { "properties": { - "compaction_prompt": { + "agent_config": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Suggested compaction prompt.", - "title": "Compaction Prompt" + "description": "Suggested agent-level configuration, if any.", + "title": "Agent Config" }, - "description": { + "conversation_id": { + "description": "Conversation turn ID for tracking.", + "title": "Conversation Id", + "type": "string" + }, + "example_prompts": { + "description": "Example natural-language prompts that demonstrate the capabilities of this AI assistant for the given mode.", + "items": { + "$ref": "#/components/schemas/ExamplePrompt" + }, + "title": "Example Prompts", + "type": "array" + }, + "intent_assessment": { "anyOf": [ { "type": "string" @@ -5598,133 +5516,172 @@ "type": "null" } ], - "description": "Suggested description.", - "title": "Description" + "description": "How the assistant interpreted the request: 'clear' when steps were generated, or an ask-path value (e.g. 'ambiguous_output', 'cannot_build') when it returned no steps and put a clarifying question or blocker in `note`. Mirrors the MCP surface so callers can distinguish a clarification pause from a hard failure.", + "title": "Intent Assessment" }, - "max_age_days": { + "note": { + "description": "AI explanation of the proposed workflow.", + "title": "Note", + "type": "string" + }, + "steps": { + "description": "Generated agent steps.", + "items": { + "additionalProperties": true, + "type": "object" + }, + "title": "Steps", + "type": "array" + }, + "success": { + "description": "Whether steps were successfully generated.", + "title": "Success", + "type": "boolean" + } + }, + "required": [ + "conversation_id", + "steps", + "note", + "success" + ], + "title": "GenerateAgentStepsResponse", + "type": "object" + }, + "GenerateStepConfigRequest": { + "properties": { + "agent_steps": { "anyOf": [ { - "type": "integer" + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" }, { "type": "null" } ], - "description": "Max age in days.", - "title": "Max Age Days" + "description": "Current agent step hierarchy for context.", + "title": "Agent Steps" }, - "max_size_tokens": { + "current_config": { "anyOf": [ { - "type": "integer" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Max size in tokens.", - "title": "Max Size Tokens" + "description": "Current step configuration to refine, if any.", + "title": "Current Config" }, - "max_turns": { + "step_id": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Max conversation turns.", - "title": "Max Turns" + "description": "ID of the specific step to refine. Omit for new steps.", + "title": "Step Id" }, - "mode": { - "description": "Memory bank mode.", - "title": "Mode", + "step_type": { + "description": "The step type to generate config for (e.g. 'regex_replace', 'gate', 'text', 'prompt_call', 'retrieval').", + "title": "Step Type", "type": "string" }, - "name": { - "description": "Suggested name.", - "title": "Name", + "user_input": { + "description": "Natural language description of what the step should do.", + "title": "User Input", + "type": "string" + } + }, + "required": [ + "step_type", + "user_input" + ], + "title": "GenerateStepConfigRequest", + "type": "object" + }, + "GenerateStepConfigResponse": { + "properties": { + "conversation_id": { + "description": "Conversation turn ID for tracking.", + "title": "Conversation Id", "type": "string" }, - "retention_days": { + "example_prompts": { + "description": "Example natural-language prompts that demonstrate the capabilities of this AI assistant for the given step type.", + "items": { + "$ref": "#/components/schemas/ExamplePrompt" + }, + "title": "Example Prompts", + "type": "array" + }, + "note": { + "description": "AI explanation of the proposed configuration.", + "title": "Note", + "type": "string" + }, + "resulting_config": { "anyOf": [ { - "type": "integer" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Retention in days.", - "title": "Retention Days" + "description": "The proposed step configuration.", + "title": "Resulting Config" }, - "type": { - "description": "Memory bank type: conversation or general.", - "title": "Type", + "step_type": { + "description": "The step type that was generated.", + "title": "Step Type", "type": "string" + }, + "success": { + "description": "Whether a valid configuration was generated.", + "title": "Success", + "type": "boolean" } }, "required": [ - "name", - "type", - "mode" + "conversation_id", + "step_type", + "note", + "success" ], - "title": "MemoryBankConfigResponse", + "title": "GenerateStepConfigResponse", "type": "object" }, - "MemoryBankListResponseModel": { - "description": "Paginated list of memory banks.", + "GenerationTierListResponse": { + "description": "``GET /models/generation-tiers`` legacy/default shape; 2026-07-27+ clients\nget the canonical ``{data, pagination}`` envelope.", "properties": { - "limit": { - "description": "Items per page.", - "title": "Limit", - "type": "integer" - }, - "memory_banks": { - "description": "List of memory banks on this page.", + "tiers": { "items": { - "$ref": "#/components/schemas/MemoryBankResponseModel" + "$ref": "#/components/schemas/GenerationTierResponse" }, - "title": "Memory Banks", + "title": "Tiers", "type": "array" - }, - "page": { - "description": "Current page number (1-based).", - "title": "Page", - "type": "integer" - }, - "total": { - "description": "Total number of memory banks.", - "title": "Total", - "type": "integer" } }, "required": [ - "memory_banks", - "page", - "limit", - "total" + "tiers" ], - "title": "MemoryBankListResponseModel", + "title": "GenerationTierListResponse", "type": "object" }, - "MemoryBankResponseModel": { - "description": "Response model for a single memory bank.", + "GenerationTierResponse": { "properties": { - "chunk_overlap": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Character overlap between chunks.", - "title": "Chunk Overlap" - }, - "chunk_size": { + "credits_per_unit": { "anyOf": [ { "type": "integer" @@ -5733,51 +5690,21 @@ "type": "null" } ], - "description": "Characters per chunk.", - "title": "Chunk Size" + "title": "Credits Per Unit" }, - "compaction_prompt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Custom prompt used when compacting older entries. When set, entries that exceed a threshold are summarized into a new entry before being soft-deleted.", - "title": "Compaction Prompt" - }, - "created_at": { - "description": "ISO-8601 creation timestamp.", - "title": "Created At", + "modality": { + "title": "Modality", "type": "string" }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Optional description of the memory bank's purpose.", - "title": "Description" + "model_id": { + "title": "Model Id", + "type": "string" }, - "dimensions": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Vector embedding dimensions.", - "title": "Dimensions" + "model_name": { + "title": "Model Name", + "type": "string" }, - "embedding_model": { + "price_label": { "anyOf": [ { "type": "string" @@ -5786,73 +5713,53 @@ "type": "null" } ], - "description": "Embedding model identifier.", - "title": "Embedding Model" + "title": "Price Label" }, - "id": { - "description": "Unique memory bank identifier.", - "title": "Id", + "tier": { + "title": "Tier", "type": "string" }, - "max_age_days": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Max entry age in days before compaction. Checked both inline after each write and by the hourly background sweep.", - "title": "Max Age Days" - }, - "max_size_tokens": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Max total tokens (per partition) before compaction. Checked both inline after each write and by the hourly background sweep.", - "title": "Max Size Tokens" - }, - "max_turns": { + "unit_label": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Max conversation turns (per partition) before compaction. Checked both inline after each write and by the hourly background sweep.", - "title": "Max Turns" - }, - "mode": { - "description": "Embedding mode: fast_and_cheap, balanced, slow_and_thorough, or custom.", - "title": "Mode", - "type": "string" + "title": "Unit Label" + } + }, + "required": [ + "modality", + "tier", + "model_id", + "model_name", + "credits_per_unit", + "unit_label", + "price_label" + ], + "title": "GenerationTierResponse", + "type": "object" + }, + "GovernanceAiAcceptResponse": { + "description": "Response from accepting a governance AI assistant plan.", + "properties": { + "actions_applied": { + "description": "Results of each action that was executed.", + "items": { + "$ref": "#/components/schemas/AppliedActionResponse" + }, + "title": "Actions Applied", + "type": "array" }, - "name": { - "description": "Human-readable name.", - "title": "Name", + "conversation_id": { + "description": "Conversation ID that was accepted.", + "title": "Conversation Id", "type": "string" }, - "retention_days": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Content retention period in days (null = indefinite).", - "title": "Retention Days" - }, - "source_connection_id": { + "error": { "anyOf": [ { "type": "string" @@ -5861,204 +5768,177 @@ "type": "null" } ], - "description": "Linked content source ID (null if not yet provisioned).", - "title": "Source Connection Id" - }, - "type": { - "description": "Bank type: conversation (chat-turn with speaker) or general (flat entries).", - "title": "Type", - "type": "string" + "description": "Overall error message if the plan failed, or null.", + "title": "Error" }, - "updated_at": { - "description": "ISO-8601 last-update timestamp.", - "title": "Updated At", - "type": "string" + "success": { + "description": "Whether all actions were applied successfully.", + "title": "Success", + "type": "boolean" } }, "required": [ - "id", - "name", - "type", - "mode", - "created_at", - "updated_at" + "conversation_id", + "actions_applied", + "success" ], - "title": "MemoryBank", + "title": "GovernanceAiAcceptResponse", "type": "object" }, - "ModalityRateResponse": { - "description": "Per-modality rate for an LLM that prices image/audio/video output\n(or input) at a rate distinct from the default text rate.\n\nExample: Gemini 3.1 Flash Image charges $3/1M output tokens for\ntext but $60/1M output tokens for generated images. The image rate\nsurfaces here with ``modality=\"image\"`` and ``output_credits_per_1000_tokens``\nset; the default text rate stays on the parent model fields.", + "GovernanceAiAssistantResponse": { + "description": "Response from the governance AI assistant generate endpoint.", "properties": { - "input_credits_per_1000_tokens": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "title": "Input Credits Per 1000 Tokens" + "conversation_id": { + "description": "Conversation ID to accept or decline this plan.", + "title": "Conversation Id", + "type": "string" }, - "modality": { - "title": "Modality", + "example_prompts": { + "description": "Example natural-language prompts that demonstrate the capabilities of the governance AI assistant.", + "items": { + "$ref": "#/components/schemas/ExamplePrompt" + }, + "title": "Example Prompts", + "type": "array" + }, + "note": { + "description": "AI-generated summary of the proposed changes.", + "title": "Note", "type": "string" }, - "output_credits_per_1000_tokens": { + "prompt_call_id": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Output Credits Per 1000 Tokens" - } - }, - "required": [ - "modality" - ], - "title": "ModalityRateResponse", - "type": "object" - }, - "OkResponse": { - "description": "A minimal ``{\"ok\": true}`` acknowledgement for state-mutating actions\nthat have no richer resource to return (e.g. accept/decline a suggestion).", - "properties": { - "ok": { - "title": "Ok", + "description": "Prompt call ID for credit tracking, or null.", + "title": "Prompt Call Id" + }, + "proposed_actions": { + "description": "Ordered list of policy actions the AI proposes to execute.", + "items": { + "$ref": "#/components/schemas/ProposedPolicyActionResponse" + }, + "title": "Proposed Actions", + "type": "array" + }, + "success": { + "description": "Whether the plan was generated successfully.", + "title": "Success", "type": "boolean" } }, "required": [ - "ok" + "conversation_id", + "note", + "proposed_actions", + "success" ], - "title": "OkResponse", + "title": "GovernanceAiAssistantResponse", "type": "object" }, - "OrganizationAlertPreferenceListResponse": { + "HTTPValidationError": { "properties": { - "preferences": { + "detail": { "items": { - "$ref": "#/components/schemas/routers__api__alerts__OrganizationAlertPreferenceResponse" + "$ref": "#/components/schemas/ValidationError" }, - "title": "Preferences", + "title": "Detail", "type": "array" - }, - "total": { - "title": "Total", - "type": "integer" } }, - "required": [ - "preferences", - "total" - ], - "title": "OrganizationAlertPreferenceListResponse", + "title": "HTTPValidationError", "type": "object" }, - "OrganizationInfoResponse": { + "ImportFieldErrorModel": { + "description": "Single agent_definition validation error with source position.", "properties": { - "account_id": { - "format": "uuid", - "title": "Account Id", - "type": "string" + "column": { + "description": "1-indexed column in `source`.", + "title": "Column", + "type": "integer" }, - "id": { - "format": "uuid", - "title": "Id", + "line": { + "description": "1-indexed line in `source`.", + "title": "Line", + "type": "integer" + }, + "message": { + "description": "Human-readable description of the problem.", + "title": "Message", "type": "string" }, - "name": { - "title": "Name", + "path": { + "description": "Dotted path of the offending field, e.g. `agent.definition.child_steps[0].step_type`.", + "title": "Path", "type": "string" } }, "required": [ - "id", - "name", - "account_id" + "line", + "column", + "path", + "message" ], - "title": "OrganizationInfoResponse", + "title": "ImportFieldErrorModel", "type": "object" }, - "PaginationResponse": { - "description": "Pagination information.", + "ImportSkipResponse": { + "description": "One item that was not applied during an agent import.\n\nUsed as the element type for ``import_warnings`` on every\nresponse model that accepts an ``agent_definition`` payload.\nSee ``services.agent_definition_import.AgentImportSkip`` for the\nfull category list.\n\nLives here (not on each router) so the authenticated and public\nAPI responses share one definition \u2014 keeping the shape that\nclients (UI modal, MCP, OpenAPI consumers) depend on aligned.", "properties": { - "has_next": { - "title": "Has Next", - "type": "boolean" - }, - "has_prev": { - "title": "Has Prev", - "type": "boolean" - }, - "limit": { - "title": "Limit", - "type": "integer" - }, - "page": { - "title": "Page", - "type": "integer" + "category": { + "description": "The kind of item that was skipped or substituted: 'schedule', 'evaluation_criteria', 'alert_config', 'alert_recipient', 'governance_policy', 'governance_kb_link', 'solution_link'.", + "title": "Category", + "type": "string" }, - "pages": { - "title": "Pages", - "type": "integer" + "details": { + "additionalProperties": true, + "description": "Category-specific identifiers for the skipped item (step_id, alert_type, kb_name, etc.). Stable keys per category; absent keys are simply not applicable.", + "title": "Details", + "type": "object" }, - "total": { - "title": "Total", - "type": "integer" + "message": { + "description": "Human-readable explanation of what was skipped and why.", + "title": "Message", + "type": "string" } }, "required": [ - "page", - "limit", - "total", - "pages", - "has_next", - "has_prev" + "category", + "message" ], - "title": "PaginationResponse", + "title": "ImportSkipResponse", "type": "object" }, - "PendingProcessingCompletedFailedStatus": { - "enum": [ - "pending", - "processing", - "completed", - "failed", - "queued", - "waiting_human", - "waiting_scheduled" - ], - "title": "PendingProcessingCompletedFailedStatus", - "type": "string" - }, - "PlaygroundCreateRequest": { - "description": "Create a model playground experiment via the public API.", + "InboundEmailRejectionResponse": { + "description": "An inbound email that was discarded without running an agent.", "properties": { - "evaluation_complexity": { - "default": "medium", - "description": "simple, medium, or complex", - "enum": [ - "simple", - "medium", - "complex" + "agent_id": { + "anyOf": [ + { + "format": "uuid", + "type": "string" + }, + { + "type": "null" + } ], - "title": "Evaluation Complexity", + "title": "Agent Id" + }, + "created_at": { + "title": "Created At", "type": "string" }, - "evaluation_mode": { - "default": "manual", - "description": "manual or prompt", - "enum": [ - "manual", - "prompt" - ], - "title": "Evaluation Mode", + "id": { + "format": "uuid", + "title": "Id", "type": "string" }, - "evaluator_model_id": { + "message_id": { "anyOf": [ { "type": "string" @@ -6067,16 +5947,21 @@ "type": "null" } ], - "description": "Evaluator model ID when evaluation_mode is prompt.", - "title": "Evaluator Model Id" + "title": "Message Id" }, - "include_step_output_in_evaluation": { - "default": false, - "description": "Whether to include selected step output as evaluator context.", - "title": "Include Step Output In Evaluation", - "type": "boolean" + "reason": { + "title": "Reason", + "type": "string" }, - "json_template": { + "recipient": { + "title": "Recipient", + "type": "string" + }, + "sender": { + "title": "Sender", + "type": "string" + }, + "sender_ip": { "anyOf": [ { "type": "string" @@ -6085,25 +5970,9 @@ "type": "null" } ], - "description": "Optional JSON template for advanced mode.", - "title": "Json Template" - }, - "model_ids": { - "description": "Selected model IDs (1-10).", - "items": { - "type": "string" - }, - "maxItems": 10, - "minItems": 1, - "title": "Model Ids", - "type": "array" - }, - "prompt": { - "description": "Prompt text for the experiment.", - "title": "Prompt", - "type": "string" + "title": "Sender Ip" }, - "selected_step_output": { + "subject": { "anyOf": [ { "type": "string" @@ -6112,37 +5981,45 @@ "type": "null" } ], - "description": "Optional step output text for evaluator context.", - "title": "Selected Step Output" - }, - "system_prompt": { - "default": "", - "description": "Optional system prompt.", - "title": "System Prompt", - "type": "string" + "title": "Subject" } }, "required": [ - "model_ids", - "prompt" + "id", + "created_at", + "recipient", + "sender", + "sender_ip", + "reason", + "message_id", + "agent_id", + "subject" ], - "title": "PlaygroundCreateRequest", + "title": "InboundEmailRejectionResponse", "type": "object" }, - "PromptModelAutoUpgradeStrategy": { - "enum": [ - "none", - "early_adopter", - "middle_of_road", - "cautious_adopter" + "InboundEmailStatusResponse": { + "properties": { + "paused": { + "title": "Paused", + "type": "boolean" + }, + "queued_backlog": { + "title": "Queued Backlog", + "type": "integer" + } + }, + "required": [ + "paused", + "queued_backlog" ], - "title": "PromptModelAutoUpgradeStrategy", - "type": "string" + "title": "InboundEmailStatusResponse", + "type": "object" }, - "PromptToolResponse": { - "description": "Response model for a prompt tool.", + "InlineTextReplaceRequest": { + "description": "Request model for inline text content replacement.", "properties": { - "description": { + "content_type": { "anyOf": [ { "type": "string" @@ -6151,53 +6028,51 @@ "type": "null" } ], - "title": "Description" + "default": "text/plain", + "description": "MIME type for the text content", + "title": "Content Type" }, - "documentation_url": { + "metadata": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Documentation Url" + "description": "Optional metadata object", + "title": "Metadata" }, - "example": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Example" + "text": { + "description": "Text content to upload", + "title": "Text", + "type": "string" }, - "headers": { + "title": { "anyOf": [ { - "additionalProperties": { - "type": "string" - }, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Headers" - }, - "id": { - "title": "Id", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "notes": { + "description": "Optional title", + "title": "Title" + } + }, + "required": [ + "text" + ], + "title": "InlineTextReplaceRequest", + "type": "object" + }, + "InlineTextUploadRequest": { + "description": "Request model for inline text uploads.", + "properties": { + "content_type": { "anyOf": [ { "type": "string" @@ -6206,24 +6081,29 @@ "type": "null" } ], - "title": "Notes" + "default": "text/plain", + "description": "MIME type for the text content", + "title": "Content Type" }, - "tool_name": { + "metadata": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Tool Name" + "description": "Optional metadata object", + "title": "Metadata" }, - "tool_type": { - "title": "Tool Type", + "text": { + "description": "Text content to upload", + "title": "Text", "type": "string" }, - "tool_type_pattern": { + "title": { "anyOf": [ { "type": "string" @@ -6232,217 +6112,188 @@ "type": "null" } ], - "title": "Tool Type Pattern" + "description": "Optional title", + "title": "Title" } }, "required": [ - "id", - "tool_type", - "name" + "text" ], - "title": "PromptToolResponse", + "title": "InlineTextUploadRequest", "type": "object" }, - "ProposedActionResponse": { - "description": "A single proposed action.", + "InsufficientCreditsDetail": { + "description": "``detail`` body for a 402 ``insufficient_credits`` response.", "properties": { - "action_type": { - "description": "Type of the proposed action.", - "title": "Action Type", - "type": "string" - }, - "description": { - "description": "Human-readable description of the action.", - "title": "Description", + "account_id": { + "description": "UUID of the account that ran out of credits.", + "title": "Account Id", "type": "string" }, - "is_destructive": { - "default": false, - "description": "Whether the action is destructive.", - "title": "Is Destructive", - "type": "boolean" - }, - "params": { - "additionalProperties": true, - "description": "Parameters for the action.", - "title": "Params", - "type": "object" - }, - "preview": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Planning-time dry-run preview attached by the solution AI assistant for create_agent / update_agent actions. Contains ``steps`` (the generated step tree), ``step_count``, ``warnings`` (a mix of heuristic structural issues \u2014 e.g. brittle JSONPath, pass-through ``regex_replace``, ``prompt_call`` missing a model \u2014 and deterministic resource-usage issues: every pre-bound knowledge base / memory bank must be referenced by at least one step, and no step may reference an unknown id), and ``skipped`` / ``skipped_reason`` when preview couldn't run (e.g. the action depends on resources created earlier in the same plan). ``None`` for non-agent actions or when generation failed.", - "title": "Preview" - } - }, - "required": [ - "action_type", - "params", - "description" - ], - "title": "ProposedActionResponse", - "type": "object" - }, - "ProposedPolicyActionResponse": { - "description": "A single proposed governance policy action.", - "properties": { - "action_type": { - "description": "Type of action: create, update, delete, enable, or disable.", - "title": "Action Type", + "error": { + "const": "insufficient_credits", + "description": "Stable machine-readable error code.", + "title": "Error", "type": "string" }, - "description": { - "description": "Human-readable description of what this action will do.", - "title": "Description", + "message": { + "description": "Human-readable explanation.", + "title": "Message", "type": "string" - }, - "params": { - "additionalProperties": true, - "description": "Parameters for the action (e.g. policy_document_id, thresholds).", - "title": "Params", - "type": "object" - } - }, - "required": [ - "action_type", - "description", - "params" - ], - "title": "ProposedPolicyActionResponse", - "type": "object" - }, - "RemoveEmailDomainResponse": { - "properties": { - "cleanup_note": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Cleanup Note" - }, - "removed": { - "default": true, - "title": "Removed", - "type": "boolean" - } - }, - "title": "RemoveEmailDomainResponse", - "type": "object" - }, - "ResumeInboundResponse": { - "properties": { - "resumed": { - "title": "Resumed", - "type": "boolean" } }, "required": [ - "resumed" + "error", + "message", + "account_id" ], - "title": "ResumeInboundResponse", - "type": "object" - }, - "SendTestEmailResponse": { - "properties": { - "sent": { - "default": true, - "title": "Sent", - "type": "boolean" - } - }, - "title": "SendTestEmailResponse", + "title": "InsufficientCreditsDetail", "type": "object" }, - "SetAutoBlockModeRequest": { - "description": "Set the account's governance auto-block mode (shared REST request).", + "InsufficientCreditsResponse": { + "description": "402 envelope returned when the account has exhausted its credits.", "properties": { - "mode": { - "title": "Mode", - "type": "string" + "detail": { + "$ref": "#/components/schemas/InsufficientCreditsDetail" } }, "required": [ - "mode" + "detail" ], - "title": "SetAutoBlockModeRequest", + "title": "InsufficientCreditsResponse", "type": "object" }, - "SolutionSourceConnectionResponse": { + "JsonValue": {}, + "KnowledgeBaseListResponseModel": { + "description": "Paginated list of knowledge bases.", "properties": { - "id": { - "format": "uuid", - "title": "Id", - "type": "string" + "knowledge_bases": { + "description": "List of knowledge bases on this page.", + "items": { + "$ref": "#/components/schemas/KnowledgeBaseResponseModel" + }, + "title": "Knowledge Bases", + "type": "array" }, - "name": { - "title": "Name", - "type": "string" + "limit": { + "description": "Items per page.", + "title": "Limit", + "type": "integer" + }, + "page": { + "description": "Current page number (1-based).", + "title": "Page", + "type": "integer" + }, + "total": { + "description": "Total number of knowledge bases.", + "title": "Total", + "type": "integer" } }, "required": [ - "id", - "name" + "knowledge_bases", + "page", + "limit", + "total" ], - "title": "SolutionSourceConnectionResponse", + "title": "KnowledgeBaseListResponseModel", "type": "object" }, - "SolutionSummaryResponse": { - "description": "Response model for solution summary.", + "KnowledgeBaseResponseModel": { + "description": "Response model for a single knowledge base.", "properties": { - "agent_count": { - "description": "Number of linked agents.", - "title": "Agent Count", - "type": "integer" - }, "created_at": { - "description": "Timestamp when the solution was created.", + "description": "ISO-8601 creation timestamp.", "title": "Created At", "type": "string" }, - "description": { - "description": "Description of the solution.", - "title": "Description", - "type": "string" + "default_score_threshold": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Editor default for a new retrieval step's Minimum Rerank Score.", + "title": "Default Score Threshold" }, - "id": { - "description": "Unique identifier for the solution.", - "format": "uuid", - "title": "Id", - "type": "string" + "default_top_k": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Editor default for a new retrieval step's Top K.", + "title": "Default Top K" }, - "knowledge_base_count": { - "description": "Number of linked knowledge bases.", - "title": "Knowledge Base Count", - "type": "integer" + "default_top_n": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Editor default for a new retrieval step's Top N.", + "title": "Default Top N" }, - "memory_bank_count": { - "description": "Number of linked memory banks.", - "title": "Memory Bank Count", - "type": "integer" + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional description.", + "title": "Description" + }, + "id": { + "description": "Unique knowledge base identifier.", + "title": "Id", + "type": "string" }, "name": { - "description": "Name of the solution.", + "description": "Human-readable name.", "title": "Name", "type": "string" }, - "source_connection_count": { - "description": "Number of linked source connections.", - "title": "Source Connection Count", - "type": "integer" + "readonly": { + "default": false, + "description": "Whether the knowledge base is read-only.", + "title": "Readonly", + "type": "boolean" + }, + "reranker_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Reranker model in use.", + "title": "Reranker Model" + }, + "sources": { + "description": "Linked source connections.", + "items": { + "$ref": "#/components/schemas/SourceConnectionResponseModel" + }, + "title": "Sources", + "type": "array" }, "updated_at": { - "description": "Timestamp when the solution was last updated.", + "description": "ISO-8601 last-update timestamp.", "title": "Updated At", "type": "string" } @@ -6450,66 +6301,143 @@ "required": [ "id", "name", - "description", - "agent_count", - "knowledge_base_count", - "source_connection_count", - "memory_bank_count", "created_at", "updated_at" ], - "title": "SolutionSummaryResponse", + "title": "KnowledgeBase", "type": "object" }, - "SourceConnectionResponseModel": { - "description": "Nested source connection summary within a knowledge base response.", + "LinkResourcesRequest": { "properties": { - "id": { - "description": "Source connection identifier.", - "title": "Id", - "type": "string" - }, - "name": { - "description": "Source connection name.", - "title": "Name", + "ids": { + "description": "Resource IDs to link", + "items": { + "format": "uuid", + "type": "string" + }, + "minItems": 1, + "title": "Ids", + "type": "array" + } + }, + "required": [ + "ids" + ], + "title": "LinkResourcesRequest", + "type": "object" + }, + "MarkAiSuggestionRequest": { + "properties": { + "accepted": { + "description": "True to accept the suggestion, false to decline it.", + "title": "Accepted", + "type": "boolean" + } + }, + "required": [ + "accepted" + ], + "title": "MarkAiSuggestionRequest", + "type": "object" + }, + "MarkConversationTurnRequest": { + "properties": { + "accepted": { + "description": "Whether the suggestion was accepted", + "title": "Accepted", + "type": "boolean" + } + }, + "required": [ + "accepted" + ], + "title": "MarkConversationTurnRequest", + "type": "object" + }, + "MeResponse": { + "properties": { + "account_id": { + "format": "uuid", + "title": "Account Id", "type": "string" }, - "polling": { + "organizations": { + "items": { + "$ref": "#/components/schemas/OrganizationInfoResponse" + }, + "title": "Organizations", + "type": "array" + } + }, + "required": [ + "account_id", + "organizations" + ], + "title": "MeResponse", + "type": "object" + }, + "MemoryBankAiAssistantResponse": { + "description": "Response from the memory bank AI assistant.", + "properties": { + "config": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/MemoryBankConfigResponse" }, { "type": "null" } ], - "description": "Polling configuration.", - "title": "Polling" + "description": "Proposed configuration, or null." }, - "source_type": { - "description": "Type of source (rss, website, etc.).", - "title": "Source Type", + "conversation_id": { + "description": "Conversation ID for follow-up.", + "title": "Conversation Id", "type": "string" }, - "url": { - "description": "Source URL.", - "title": "Url", + "example_prompts": { + "description": "Example natural-language prompts that demonstrate the capabilities of the memory bank AI assistant.", + "items": { + "$ref": "#/components/schemas/ExamplePrompt" + }, + "title": "Example Prompts", + "type": "array" + }, + "note": { + "description": "AI-generated explanation.", + "title": "Note", "type": "string" + }, + "prompt_call_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Prompt call ID for credit tracking.", + "title": "Prompt Call Id" + }, + "success": { + "default": false, + "description": "Whether generation succeeded.", + "title": "Success", + "type": "boolean" } }, "required": [ - "id", - "name", - "url", - "source_type" + "conversation_id", + "note" ], - "title": "SourceConnectionResponseModel", + "title": "MemoryBankAiAssistantResponse", "type": "object" }, - "SourceEmbeddingMigrationResponse": { - "description": "Response model for source embedding migration status.", + "MemoryBankConfigResponse": { + "description": "Suggested memory bank configuration from the AI assistant.", "properties": { - "completed_at": { + "compaction_prompt": { "anyOf": [ { "type": "string" @@ -6518,13 +6446,10 @@ "type": "null" } ], - "title": "Completed At" - }, - "created_at": { - "title": "Created At", - "type": "string" + "description": "Suggested compaction prompt.", + "title": "Compaction Prompt" }, - "failure_message": { + "description": { "anyOf": [ { "type": "string" @@ -6533,156 +6458,133 @@ "type": "null" } ], - "title": "Failure Message" - }, - "id": { - "title": "Id", - "type": "string" + "description": "Suggested description.", + "title": "Description" }, - "notification_recipients": { + "max_age_days": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "type": "integer" }, { "type": "null" } ], - "title": "Notification Recipients" - }, - "phase": { - "title": "Phase", - "type": "string" + "description": "Always null. Age-based compaction is retired \u2014 the assistant never suggests it. Kept so an SDK generated before the change still validates this response.", + "title": "Max Age Days" }, - "progress_current": { - "title": "Progress Current", - "type": "integer" - }, - "progress_message": { + "max_size_tokens": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Progress Message" - }, - "progress_total": { - "title": "Progress Total", - "type": "integer" - }, - "source_connection_id": { - "title": "Source Connection Id", - "type": "string" - }, - "source_id_new": { - "title": "Source Id New", - "type": "string" - }, - "source_id_old": { - "title": "Source Id Old", - "type": "string" + "description": "Max size in tokens.", + "title": "Max Size Tokens" }, - "started_at": { + "max_turns": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Started At" + "description": "Max conversation turns.", + "title": "Max Turns" }, - "status": { - "title": "Status", + "mode": { + "description": "Memory bank mode.", + "title": "Mode", "type": "string" }, - "target_dimensions": { - "title": "Target Dimensions", - "type": "integer" - }, - "target_embedding_model": { - "title": "Target Embedding Model", + "name": { + "description": "Suggested name.", + "title": "Name", "type": "string" }, - "task_execution_id": { + "retention_days": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Task Execution Id" + "description": "Retention in days.", + "title": "Retention Days" }, - "updated_at": { - "title": "Updated At", + "type": { + "description": "Memory bank type: conversation or general.", + "title": "Type", "type": "string" } }, "required": [ - "id", - "source_connection_id", - "source_id_old", - "source_id_new", - "target_embedding_model", - "target_dimensions", - "status", - "phase", - "progress_current", - "progress_total", - "progress_message", - "failure_message", - "notification_recipients", - "task_execution_id", - "started_at", - "completed_at", - "created_at", - "updated_at" + "name", + "type", + "mode" ], - "title": "SourceEmbeddingMigrationResponse", + "title": "MemoryBankConfigResponse", "type": "object" }, - "SourceIndexMode": { - "description": "Embedding quality / cost trade-off preset for custom_index sources.\n\nEach preset controls the default embedding dimensions, chunk size, and\nchunk overlap. The embedding model is always the account-level default\n(currently ``AWS_BEDROCK_AMAZON_NOVA_2_MULTIMODAL``).\n\nPresets:\n FAST_AND_CHEAP: 256 dimensions, 3 000 char chunks, 500 char overlap.\n BALANCED: 384 dimensions, 1 500 char chunks, 300 char overlap.\n SLOW_AND_THOROUGH: 1 024 dimensions, 1 000 char chunks, 200 char overlap.\n CUSTOM: Caller supplies embedding model, dimensions, and chunk config.", - "enum": [ - "fast_and_cheap", - "balanced", - "slow_and_thorough", - "custom" + "MemoryBankListResponseModel": { + "description": "Paginated list of memory banks.", + "properties": { + "limit": { + "description": "Items per page.", + "title": "Limit", + "type": "integer" + }, + "memory_banks": { + "description": "List of memory banks on this page.", + "items": { + "$ref": "#/components/schemas/MemoryBankResponseModel" + }, + "title": "Memory Banks", + "type": "array" + }, + "page": { + "description": "Current page number (1-based).", + "title": "Page", + "type": "integer" + }, + "total": { + "description": "Total number of memory banks.", + "title": "Total", + "type": "integer" + } + }, + "required": [ + "memory_banks", + "page", + "limit", + "total" ], - "title": "SourceIndexMode", - "type": "string" + "title": "MemoryBankListResponseModel", + "type": "object" }, - "SourceResponse": { - "description": "Response model for source data.", + "MemoryBankResponseModel": { + "description": "Response model for a single memory bank.", "properties": { - "account_id": { - "description": "Account ID associated with the source.", - "format": "uuid", - "title": "Account Id", - "type": "string" - }, - "avg_episodes_per_month": { + "chunk_overlap": { "anyOf": [ { - "type": "number" + "type": "integer" }, { "type": "null" } ], - "description": "Average number of episodes per month.", - "title": "Avg Episodes Per Month" + "description": "Character overlap between chunks.", + "title": "Chunk Overlap" }, - "avg_words_per_episode": { + "chunk_size": { "anyOf": [ { "type": "integer" @@ -6691,10 +6593,10 @@ "type": "null" } ], - "description": "Average number of words per episode.", - "title": "Avg Words Per Episode" + "description": "Characters per chunk.", + "title": "Chunk Size" }, - "chunk_language": { + "compaction_prompt": { "anyOf": [ { "type": "string" @@ -6703,34 +6605,39 @@ "type": "null" } ], - "description": "Language used for chunking content.", - "title": "Chunk Language" + "description": "Custom prompt used when compacting older entries. When set, entries that exceed a threshold are summarized into a new entry before being soft-deleted.", + "title": "Compaction Prompt" }, - "chunk_overlap": { + "created_at": { + "description": "ISO-8601 creation timestamp.", + "title": "Created At", + "type": "string" + }, + "description": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Chunk overlap for content processing.", - "title": "Chunk Overlap" + "description": "Optional description of the memory bank's purpose.", + "title": "Description" }, - "chunk_regex_separators": { + "dimensions": { "anyOf": [ { - "type": "boolean" + "type": "integer" }, { "type": "null" } ], - "description": "Indicates if chunk separators are regex patterns.", - "title": "Chunk Regex Separators" + "description": "Vector embedding dimensions.", + "title": "Dimensions" }, - "chunk_separators": { + "embedding_model": { "anyOf": [ { "type": "string" @@ -6739,10 +6646,15 @@ "type": "null" } ], - "description": "Chunk separators used for content processing.", - "title": "Chunk Separators" + "description": "Embedding model identifier.", + "title": "Embedding Model" }, - "chunk_size": { + "id": { + "description": "Unique memory bank identifier.", + "title": "Id", + "type": "string" + }, + "max_age_days": { "anyOf": [ { "type": "integer" @@ -6751,26 +6663,10 @@ "type": "null" } ], - "description": "Chunk size for content processing.", - "title": "Chunk Size" - }, - "content_count": { - "default": 0, - "description": "Number of content items associated with the source connection.", - "title": "Content Count", - "type": "integer" - }, - "content_filter": { - "description": "Content filter for the source connection.", - "title": "Content Filter", - "type": "string" - }, - "created_at": { - "description": "Timestamp when the source connection was created.", - "title": "Created At", - "type": "string" + "description": "DEPRECATED and no longer applied. Age now belongs solely to retention_days, which deletes; compaction triggers on max_size_tokens and max_turns. Always null for clients sending Seclai-Version 2026-08-03 or later; older clients keep reading whatever value was stored.", + "title": "Max Age Days" }, - "dimensions": { + "max_size_tokens": { "anyOf": [ { "type": "integer" @@ -6779,129 +6675,289 @@ "type": "null" } ], - "description": "Dimensions of the embedding model.", - "title": "Dimensions" + "description": "Max total tokens (per partition) before compaction. Checked both inline after each write and by the hourly background sweep.", + "title": "Max Size Tokens" }, - "embedding_model": { + "max_turns": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "description": "Embedding model used for the source connection.", - "title": "Embedding Model" + "description": "Max conversation turns (per partition) before compaction. Checked both inline after each write and by the hourly background sweep.", + "title": "Max Turns" }, - "embedding_model_type": { + "mode": { + "description": "Embedding mode: fast_and_cheap, balanced, slow_and_thorough, or custom.", + "title": "Mode", + "type": "string" + }, + "name": { + "description": "Human-readable name.", + "title": "Name", + "type": "string" + }, + "retention_days": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "description": "Type of the embedding model.", - "title": "Embedding Model Type" + "description": "Content retention period in days (null = indefinite).", + "title": "Retention Days" }, - "free_retention_days": { + "source_connection_id": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Number of days content is stored for free before billing applies.", - "title": "Free Retention Days" + "description": "Linked content source ID (null if not yet provisioned).", + "title": "Source Connection Id" }, - "has_historical_data": { + "strip_quoted_reply_chains": { "default": false, - "description": "Indicates if the source connection has historical data.", - "title": "Has Historical Data", + "description": "Conversation banks only. When true, a conversation turn written to this bank has the quoted reply chain an email client prepends to a reply dropped from it. Only inbound (user) turns are affected, and only words in a run of at least ~40 matching a recent turn word for word are dropped (line wrapping and punctuation at a word's edge are ignored). A word the sender changed is kept, including a one-character change inside a link, address or amount, unless the change is only to that edge punctuation.", + "title": "Strip Quoted Reply Chains", "type": "boolean" }, - "id": { - "description": "Unique identifier for the source connection.", - "title": "Id", + "type": { + "description": "Bank type: conversation (chat-turn with speaker) or general (flat entries).", + "title": "Type", "type": "string" }, - "index_mode": { + "updated_at": { + "description": "ISO-8601 last-update timestamp.", + "title": "Updated At", + "type": "string" + } + }, + "required": [ + "id", + "name", + "type", + "mode", + "created_at", + "updated_at" + ], + "title": "MemoryBank", + "type": "object" + }, + "ModalityRateResponse": { + "description": "Per-modality rate for an LLM that prices image/audio/video output\n(or input) at a rate distinct from the default text rate.\n\nExample: Gemini 3.1 Flash Image charges $3/1M output tokens for\ntext but $60/1M output tokens for generated images. The image rate\nsurfaces here with ``modality=\"image\"`` and ``output_credits_per_1000_tokens``\nset; the default text rate stays on the parent model fields.", + "properties": { + "input_credits_per_1000_tokens": { "anyOf": [ { - "$ref": "#/components/schemas/SourceIndexMode" + "type": "number" }, { "type": "null" } ], - "description": "Index mode for custom_index sources: fast_and_cheap, balanced, slow_and_thorough, or custom." - }, - "media_types": { - "description": "Media kinds extracted from indexed content and embedded as multi-modal KB chunks (subset of ['images', 'video']). Empty = text-only.", - "items": { - "type": "string" - }, - "title": "Media Types", - "type": "array" + "title": "Input Credits Per 1000 Tokens" }, - "name": { - "description": "Name of the source connection.", - "title": "Name", + "modality": { + "title": "Modality", "type": "string" }, - "next_poll_at": { + "output_credits_per_1000_tokens": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "description": "Timestamp for the next scheduled poll.", - "title": "Next Poll At" + "title": "Output Credits Per 1000 Tokens" + } + }, + "required": [ + "modality" + ], + "title": "ModalityRateResponse", + "type": "object" + }, + "OkResponse": { + "description": "A minimal ``{\"ok\": true}`` acknowledgement for state-mutating actions\nthat have no richer resource to return (e.g. accept/decline a suggestion).", + "properties": { + "ok": { + "title": "Ok", + "type": "boolean" + } + }, + "required": [ + "ok" + ], + "title": "OkResponse", + "type": "object" + }, + "OrganizationAlertPreferenceListResponse": { + "properties": { + "preferences": { + "items": { + "$ref": "#/components/schemas/routers__api__alerts__OrganizationAlertPreferenceResponse" + }, + "title": "Preferences", + "type": "array" }, - "polling": { + "total": { + "title": "Total", + "type": "integer" + } + }, + "required": [ + "preferences", + "total" + ], + "title": "OrganizationAlertPreferenceListResponse", + "type": "object" + }, + "OrganizationInfoResponse": { + "properties": { + "account_id": { + "format": "uuid", + "title": "Account Id", + "type": "string" + }, + "id": { + "format": "uuid", + "title": "Id", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + } + }, + "required": [ + "id", + "name", + "account_id" + ], + "title": "OrganizationInfoResponse", + "type": "object" + }, + "PaginationResponse": { + "description": "Pagination information.", + "properties": { + "has_next": { + "title": "Has Next", + "type": "boolean" + }, + "has_prev": { + "title": "Has Prev", + "type": "boolean" + }, + "limit": { + "title": "Limit", + "type": "integer" + }, + "page": { + "title": "Page", + "type": "integer" + }, + "pages": { + "title": "Pages", + "type": "integer" + }, + "total": { + "title": "Total", + "type": "integer" + } + }, + "required": [ + "page", + "limit", + "total", + "pages", + "has_next", + "has_prev" + ], + "title": "PaginationResponse", + "type": "object" + }, + "PendingProcessingCompletedFailedStatus": { + "enum": [ + "pending", + "processing", + "completed", + "failed", + "queued", + "waiting_human", + "waiting_scheduled" + ], + "title": "PendingProcessingCompletedFailedStatus", + "type": "string" + }, + "PlaygroundCreateRequest": { + "description": "Create a model playground experiment via the public API.", + "properties": { + "effort": { "anyOf": [ { - "type": "string" + "additionalProperties": { + "type": "string" + }, + "type": "object" }, { "type": "null" } ], - "description": "Polling configuration for the source connection.", - "title": "Polling" + "description": "Reasoning effort per model id, each one of that model's `effort_options` values. Not combinable with `json_template`.", + "title": "Effort" }, - "polling_action": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } + "evaluation_complexity": { + "default": "medium", + "description": "simple, medium, or complex", + "enum": [ + "simple", + "medium", + "complex" ], - "description": "Polling action for the source connection.", - "title": "Polling Action" + "title": "Evaluation Complexity", + "type": "string" }, - "polling_max_items": { + "evaluation_mode": { + "default": "manual", + "description": "manual or prompt", + "enum": [ + "manual", + "prompt" + ], + "title": "Evaluation Mode", + "type": "string" + }, + "evaluator_model_id": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Maximum items to poll for the source connection.", - "title": "Polling Max Items" + "description": "Evaluator model ID when evaluation_mode is prompt.", + "title": "Evaluator Model Id" }, - "pulled_at": { + "include_step_output_in_evaluation": { + "default": false, + "description": "Whether to include selected step output as evaluator context.", + "title": "Include Step Output In Evaluation", + "type": "boolean" + }, + "json_template": { "anyOf": [ { "type": "string" @@ -6910,139 +6966,86 @@ "type": "null" } ], - "description": "Timestamp when content was last pulled.", - "title": "Pulled At" + "description": "Optional JSON template for advanced mode.", + "title": "Json Template" }, - "readonly": { - "default": false, - "description": "Indicates if the source connection is read-only.", - "title": "Readonly", - "type": "boolean" + "model_ids": { + "description": "Selected model IDs (1-10).", + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "title": "Model Ids", + "type": "array" }, - "retention": { + "prompt": { + "description": "Prompt text for the experiment.", + "title": "Prompt", + "type": "string" + }, + "selected_step_output": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Retention period for the source connection.", - "title": "Retention" + "description": "Optional step output text for evaluator context.", + "title": "Selected Step Output" }, - "source_type": { - "description": "Type of the source connection.", - "title": "Source Type", - "type": "string" - }, - "system_managed": { - "default": false, - "description": "Indicates if this source is automatically managed by the system (e.g., agent traces).", - "title": "System Managed", - "type": "boolean" - }, - "updated_at": { - "description": "Timestamp when the source connection was last updated.", - "title": "Updated At", + "system_prompt": { + "default": "", + "description": "Optional system prompt.", + "title": "System Prompt", "type": "string" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "URL of the source connection.", - "title": "Url" } }, "required": [ - "id", - "account_id", - "name", - "url", - "source_type", - "polling", - "polling_action", - "polling_max_items", - "content_filter", - "retention", - "pulled_at", - "next_poll_at", - "created_at", - "updated_at" + "model_ids", + "prompt" ], - "title": "SourceResponse", + "title": "PlaygroundCreateRequest", "type": "object" }, - "StandaloneTestCompactionRequest": { - "description": "Request body for testing a compaction prompt *without* an existing bank.\n\nUsed on the create-memory-bank page where no bank ID exists yet.\n``compaction_prompt`` is required (no bank to fall back to).\nContent must come from ``sample_entries`` or ``generate_direction``\n(no existing entries to fetch).", + "PromptModelAutoUpgradeStrategy": { + "enum": [ + "none", + "early_adopter", + "middle_of_road", + "cautious_adopter" + ], + "title": "PromptModelAutoUpgradeStrategy", + "type": "string" + }, + "PromptToolResponse": { + "description": "Response model for a prompt tool.", "properties": { - "bank_type": { - "default": "conversation", - "description": "Memory bank type ('conversation' or 'general') \u2014 controls the style of generated entries.", - "title": "Bank Type", - "type": "string" - }, - "compaction_prompt": { - "description": "Compaction prompt to test.", - "minLength": 1, - "title": "Compaction Prompt", - "type": "string" - }, - "entry_count": { - "default": 5, - "description": "Number of entries to generate when using generate_direction.", - "maximum": 20.0, - "minimum": 2.0, - "title": "Entry Count", - "type": "integer" - }, - "generate_direction": { + "description": { "anyOf": [ { - "maxLength": 2000, "type": "string" }, { "type": "null" } ], - "description": "Direction for the LLM to generate sample entries.", - "title": "Generate Direction" + "title": "Description" }, - "sample_entries": { + "documentation_url": { "anyOf": [ { - "items": { - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" + "type": "string" }, { "type": "null" } ], - "description": "Explicit sample entries to compact.", - "title": "Sample Entries" - } - }, - "required": [ - "compaction_prompt" - ], - "title": "StandaloneTestCompactionRequest", - "type": "object" - }, - "StartSourceEmbeddingMigrationRequest": { - "description": "Request payload to start a source embedding migration.", - "properties": { - "chunk_language": { + "title": "Documentation Url" + }, + "example": { "anyOf": [ { "type": "string" @@ -7051,35 +7054,42 @@ "type": "null" } ], - "description": "Language-specific chunking language code", - "title": "Chunk Language" + "title": "Example" }, - "chunk_overlap": { + "headers": { "anyOf": [ { - "minimum": 0.0, - "type": "integer" + "additionalProperties": { + "type": "string" + }, + "type": "object" }, { "type": "null" } ], - "description": "Override chunk overlap (characters)", - "title": "Chunk Overlap" + "title": "Headers" }, - "chunk_regex_separators": { + "id": { + "title": "Id", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "notes": { "anyOf": [ { - "type": "boolean" + "type": "string" }, { "type": "null" } ], - "description": "Whether chunk separators are regex patterns", - "title": "Chunk Regex Separators" + "title": "Notes" }, - "chunk_separators": { + "tool_name": { "anyOf": [ { "type": "string" @@ -7088,60 +7098,110 @@ "type": "null" } ], - "description": "Custom chunk separators (JSON-encoded list)", - "title": "Chunk Separators" + "title": "Tool Name" }, - "chunk_size": { + "tool_type": { + "title": "Tool Type", + "type": "string" + }, + "tool_type_pattern": { "anyOf": [ { - "exclusiveMinimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Override chunk size (characters per chunk)", - "title": "Chunk Size" + "title": "Tool Type Pattern" + } + }, + "required": [ + "id", + "tool_type", + "name" + ], + "title": "PromptToolResponse", + "type": "object" + }, + "ProposedActionResponse": { + "description": "A single proposed action.", + "properties": { + "action_type": { + "description": "Type of the proposed action.", + "title": "Action Type", + "type": "string" }, - "notification_recipients": { + "description": { + "description": "Human-readable description of the action.", + "title": "Description", + "type": "string" + }, + "is_destructive": { + "default": false, + "description": "Whether the action is destructive.", + "title": "Is Destructive", + "type": "boolean" + }, + "params": { + "additionalProperties": true, + "description": "Parameters for the action.", + "title": "Params", + "type": "object" + }, + "preview": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Optional notification recipient emails", - "title": "Notification Recipients" - }, - "target_dimensions": { - "description": "Target embedding dimensions", - "exclusiveMinimum": 0.0, - "title": "Target Dimensions", - "type": "integer" + "description": "Planning-time dry-run preview attached by the solution AI assistant for create_agent / update_agent actions. Contains ``steps`` (the generated step tree), ``step_count``, ``warnings`` (a mix of heuristic structural issues \u2014 e.g. brittle JSONPath, pass-through ``regex_replace``, ``prompt_call`` missing a model \u2014 and deterministic resource-usage issues: every pre-bound knowledge base / memory bank must be referenced by at least one step, and no step may reference an unknown id), and ``skipped`` / ``skipped_reason`` when preview couldn't run (e.g. the action depends on resources created earlier in the same plan). ``None`` for non-agent actions or when generation failed.", + "title": "Preview" + } + }, + "required": [ + "action_type", + "params", + "description" + ], + "title": "ProposedActionResponse", + "type": "object" + }, + "ProposedPolicyActionResponse": { + "description": "A single proposed governance policy action.", + "properties": { + "action_type": { + "description": "Type of action: create, update, delete, enable, or disable.", + "title": "Action Type", + "type": "string" }, - "target_embedding_model": { - "description": "Target embedding model enum", - "title": "Target Embedding Model", + "description": { + "description": "Human-readable description of what this action will do.", + "title": "Description", "type": "string" + }, + "params": { + "additionalProperties": true, + "description": "Parameters for the action (e.g. policy_document_id, thresholds).", + "title": "Params", + "type": "object" } }, "required": [ - "target_embedding_model", - "target_dimensions" + "action_type", + "description", + "params" ], - "title": "StartSourceEmbeddingMigrationRequest", + "title": "ProposedPolicyActionResponse", "type": "object" }, - "TestCompactionRequest": { - "description": "Request body for testing a compaction prompt against an existing bank.\n\nThe user may supply a ``compaction_prompt`` to override (or provide when\nthe bank has none). Content can come from three sources:\n\n1. Existing entries in the bank (default when neither field is set).\n2. ``sample_entries`` \u2013 caller-provided list of strings.\n3. ``generate_direction`` \u2013 an instruction to the LLM to generate sample\n memory entries. Useful for trying a prompt before any real data\n exists.\n\nAt most one of ``sample_entries`` / ``generate_direction`` may be given.", + "RemoveEmailDomainResponse": { "properties": { - "compaction_prompt": { + "cleanup_note": { "anyOf": [ { "type": "string" @@ -7150,55 +7210,56 @@ "type": "null" } ], - "description": "Compaction prompt to test. Falls back to the bank's current prompt when omitted.", - "title": "Compaction Prompt" + "title": "Cleanup Note" }, - "entry_count": { - "default": 5, - "description": "Number of entries to generate when using generate_direction.", - "maximum": 20.0, - "minimum": 2.0, - "title": "Entry Count", - "type": "integer" + "removed": { + "default": true, + "title": "Removed", + "type": "boolean" + } + }, + "title": "RemoveEmailDomainResponse", + "type": "object" + }, + "RerankerModelListResponse": { + "description": "Legacy (header-less) response shape for the reranker catalog.", + "properties": { + "default_model_type": { + "description": "Reranker used when a knowledge base does not choose one", + "title": "Default Model Type", + "type": "string" }, - "generate_direction": { - "anyOf": [ - { - "maxLength": 2000, - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Direction for the LLM to generate sample entries (e.g. 'Generate 5 entries about a customer support interaction').", - "title": "Generate Direction" + "models": { + "description": "Available reranker models", + "items": { + "$ref": "#/components/schemas/RerankerModelResponse" + }, + "title": "Models", + "type": "array" }, - "sample_entries": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - }, - { - "type": "null" - } - ], - "description": "Explicit sample entries to compact.", - "title": "Sample Entries" + "search_processing_credits": { + "description": "Credits charged for processing a search request", + "title": "Search Processing Credits", + "type": "number" } }, - "title": "TestCompactionRequest", + "required": [ + "models", + "default_model_type", + "search_processing_credits" + ], + "title": "RerankerModelListResponse", "type": "object" }, - "TestDraftEvaluationRequest": { - "description": "Request body for ephemeral (non-persisted) evaluation testing.\n\nProvide either ``step_output`` (raw text) **or** ``agent_step_run_id``\n(to load output from storage). Exactly one must be supplied.", + "RerankerModelResponse": { + "description": "Information about a reranker model.", "properties": { - "agent_input": { + "credits_per_action": { + "description": "Credits charged per rerank action", + "title": "Credits Per Action", + "type": "number" + }, + "description": { "anyOf": [ { "type": "string" @@ -7207,23 +7268,43 @@ "type": "null" } ], - "description": "The original agent run input for context. When agent_step_run_id is supplied this is loaded automatically from the parent run if omitted.", - "title": "Agent Input" + "description": "Model description", + "title": "Description" }, - "agent_step_run_id": { + "is_default": { + "description": "Whether this is the platform default reranker", + "title": "Is Default", + "type": "boolean" + }, + "is_new": { + "default": false, + "description": "Whether the model is newly released", + "title": "Is New", + "type": "boolean" + }, + "max_input_tokens": { "anyOf": [ { - "format": "uuid", - "type": "string" + "type": "integer" }, { "type": "null" } ], - "description": "Load step output from this completed step run instead of supplying text.", - "title": "Agent Step Run Id" + "description": "Max input tokens per request", + "title": "Max Input Tokens" }, - "evaluation_prompt": { + "model_type": { + "description": "Full model type identifier. This is the value to send as reranker_model on a knowledge base; send \"none\" or an empty string to disable reranking.", + "title": "Model Type", + "type": "string" + }, + "name": { + "description": "Human-readable model name", + "title": "Name", + "type": "string" + }, + "provider": { "anyOf": [ { "type": "string" @@ -7232,211 +7313,209 @@ "type": "null" } ], - "title": "Evaluation Prompt" - }, - "evaluation_tier": { - "anyOf": [ - { - "$ref": "#/components/schemas/AgentEvaluationTier" - }, - { - "type": "null" - } - ] + "description": "Model provider identifier", + "title": "Provider" }, - "expectation_config": { + "supported_languages": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "title": "Expectation Config" - }, - "pass_threshold": { - "default": 0.5, - "maximum": 1.0, - "minimum": 0.0, - "title": "Pass Threshold", - "type": "number" + "description": "Supported languages", + "title": "Supported Languages" }, - "step_output": { + "url": { "anyOf": [ { - "minLength": 1, "type": "string" }, { "type": "null" } ], - "description": "The step output text to evaluate. Omit if agent_step_run_id is supplied.", - "title": "Step Output" + "description": "Model documentation URL", + "title": "Url" } }, - "title": "TestDraftEvaluationRequest", + "required": [ + "model_type", + "name", + "credits_per_action", + "is_default" + ], + "title": "RerankerModelResponse", "type": "object" }, - "TestDraftEvaluationResponse": { - "description": "Response for an ephemeral evaluation test.", + "ResumeInboundResponse": { "properties": { - "explanation": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Explanation" - }, - "passed": { - "title": "Passed", + "resumed": { + "title": "Resumed", "type": "boolean" - }, - "score": { - "title": "Score", - "type": "number" } }, "required": [ - "score", - "passed", - "explanation" + "resumed" ], - "title": "TestDraftEvaluationResponse", + "title": "ResumeInboundResponse", "type": "object" }, - "UnlinkResourcesRequest": { + "SendTestEmailResponse": { "properties": { - "ids": { - "description": "Resource IDs to unlink", - "items": { - "format": "uuid", - "type": "string" + "sent": { + "default": true, + "title": "Sent", + "type": "boolean" + } + }, + "title": "SendTestEmailResponse", + "type": "object" + }, + "ServiceUnavailableError": { + "properties": { + "error": { + "properties": { + "code": { + "enum": [ + "database_unavailable", + "vector_store_unavailable" + ], + "type": "string" + }, + "message": { + "type": "string" + } }, - "minItems": 1, - "title": "Ids", - "type": "array" + "required": [ + "code", + "message" + ], + "type": "object" } }, "required": [ - "ids" + "error" ], - "title": "UnlinkResourcesRequest", + "title": "ServiceUnavailableError", "type": "object" }, - "UnreadCountResponse": { + "SetAutoBlockModeRequest": { + "description": "Set the account's governance auto-block mode (shared REST request).", "properties": { - "count": { - "title": "Count", - "type": "integer" + "mode": { + "title": "Mode", + "type": "string" } }, "required": [ - "count" + "mode" ], - "title": "UnreadCountResponse", + "title": "SetAutoBlockModeRequest", "type": "object" }, - "UpdateAgentDefinitionRequest": { + "SolutionSourceConnectionResponse": { "properties": { - "definition": { - "additionalProperties": true, - "description": "The full agent definition (name, description, tags, steps). Steps form a tree workflow. Each step has a `step_type`, `id`, `name`, and type-specific config. Content enrichment steps (write_metadata, write_content_attachment, load_content_attachment, load_content) require content-triggered agents.", - "title": "Definition", - "type": "object" + "id": { + "format": "uuid", + "title": "Id", + "type": "string" }, - "expected_change_id": { - "description": "The change_id from the last GET, for optimistic locking.", - "title": "Expected Change Id", + "name": { + "title": "Name", "type": "string" } }, "required": [ - "expected_change_id", - "definition" + "id", + "name" ], - "title": "UpdateAgentDefinitionRequest", + "title": "SolutionSourceConnectionResponse", "type": "object" }, - "UpdateAlertConfigRequest": { + "SolutionSummaryResponse": { + "description": "Response model for solution summary.", "properties": { - "cooldown_minutes": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Cooldown period in minutes", - "title": "Cooldown Minutes" - }, - "distribution_type": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Distribution type", - "title": "Distribution Type" + "agent_count": { + "description": "Number of linked agents.", + "title": "Agent Count", + "type": "integer" }, - "enabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Whether the alert config is enabled", - "title": "Enabled" + "created_at": { + "description": "Timestamp when the solution was created.", + "title": "Created At", + "type": "string" }, - "recipient_user_ids": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "description": "User IDs for selected_members distribution", - "title": "Recipient User Ids" + "description": { + "description": "Description of the solution.", + "title": "Description", + "type": "string" }, - "threshold": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Threshold configuration", - "title": "Threshold" + "id": { + "description": "Unique identifier for the solution.", + "format": "uuid", + "title": "Id", + "type": "string" + }, + "knowledge_base_count": { + "description": "Number of linked knowledge bases.", + "title": "Knowledge Base Count", + "type": "integer" + }, + "memory_bank_count": { + "description": "Number of linked memory banks.", + "title": "Memory Bank Count", + "type": "integer" + }, + "name": { + "description": "Name of the solution.", + "title": "Name", + "type": "string" + }, + "source_connection_count": { + "description": "Number of linked source connections.", + "title": "Source Connection Count", + "type": "integer" + }, + "updated_at": { + "description": "Timestamp when the solution was last updated.", + "title": "Updated At", + "type": "string" } }, - "title": "UpdateAlertConfigRequest", + "required": [ + "id", + "name", + "description", + "agent_count", + "knowledge_base_count", + "source_connection_count", + "memory_bank_count", + "created_at", + "updated_at" + ], + "title": "SolutionSummaryResponse", "type": "object" }, - "UpdateApiVersionRequest": { + "SourceConnectionResponseModel": { + "description": "Nested source connection summary within a knowledge base response.", "properties": { - "version": { + "id": { + "description": "Source connection identifier.", + "title": "Id", + "type": "string" + }, + "name": { + "description": "Source connection name.", + "title": "Name", + "type": "string" + }, + "polling": { "anyOf": [ { "type": "string" @@ -7445,85 +7524,153 @@ "type": "null" } ], - "description": "A YYYY-MM-DD date to pin the account to, or null to clear the pin (revert to the default baseline).", - "title": "Version" + "description": "Polling configuration.", + "title": "Polling" + }, + "source_type": { + "description": "Type of source (rss, website, etc.).", + "title": "Source Type", + "type": "string" + }, + "url": { + "description": "Source URL.", + "title": "Url", + "type": "string" } }, - "title": "UpdateApiVersionRequest", + "required": [ + "id", + "name", + "url", + "source_type" + ], + "title": "SourceConnectionResponseModel", "type": "object" }, - "UpdateEvaluationCriteriaRequest": { - "description": "Request body for updating an evaluation criteria.\n\nRetry settings and sample frequency are set at the agent level.", + "SourceContentStatusListResponse": { + "description": "Response model for a paginated per-item indexing status list.", "properties": { - "description": { + "data": { + "items": { + "$ref": "#/components/schemas/SourceContentStatusResponse" + }, + "title": "Data", + "type": "array" + }, + "pagination": { + "$ref": "#/components/schemas/PaginationResponse" + } + }, + "required": [ + "data", + "pagination" + ], + "title": "SourceContentStatusListResponse", + "type": "object" + }, + "SourceContentStatusResponse": { + "description": "Response model for one content item's indexing status.", + "properties": { + "awaiting_reindex": { + "default": false, + "description": "True when the item is linked and reports completed but its content is not yet embedded under the index the source connection currently uses, because it still sits under the index that connection used before an embedding migration switched it. Anything ingested while a migration ran can land in this state. Semantic and content search will not match it until it is re-embedded; a title keyword match can still return it, so the item may appear in results while its body is unsearchable. It clears on its own \u2014 a reconciliation pass re-embeds the item under the current index, typically within minutes of the migration finishing, and a daily sweep retries whatever is still outstanding, so a large backlog can take more than one sweep to drain. The re-embedding is not charged to your account: nothing you did caused it, so Seclai absorbs the cost. Never true for an item that is simply still indexing; content_status covers that.", + "title": "Awaiting Reindex", + "type": "boolean" + }, + "content_status": { + "description": "Indexing status: pending, fetching, transcribing, scanning, indexing, completed, or failed.", + "title": "Content Status", + "type": "string" + }, + "content_token_count": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Description" + "description": "Extracted token count.", + "title": "Content Token Count" }, - "enabled": { + "content_type": { + "description": "Content type group: text, audio, video, image, or document.", + "title": "Content Type", + "type": "string" + }, + "content_url": { "anyOf": [ { - "type": "boolean" + "type": "string" }, { "type": "null" } ], - "title": "Enabled" + "description": "Internal URL identifying the item. Uploaded files use a `file-upload://` URL.", + "title": "Content Url" }, - "evaluation_prompt": { + "content_version_id": { + "description": "ID of the content version. This is the `content_version_id` returned by the upload endpoints, so it is what you match an upload against.", + "title": "Content Version Id", + "type": "string" + }, + "content_word_count": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Evaluation Prompt" + "description": "Extracted word count.", + "title": "Content Word Count" }, - "evaluation_tier": { + "error": { "anyOf": [ { - "$ref": "#/components/schemas/AgentEvaluationTier" + "type": "string" }, { "type": "null" } - ] + ], + "description": "Why the item failed, when `content_status` is `failed`.", + "title": "Error" }, - "expectation_config": { + "extracted_media_capped": { + "default": false, + "description": "True when extraction stopped with media still unread, so the item references more media than was indexed and media search will not match anything past the cut. Two causes: a web page that ran out of the budget for fetching remote assets, or a container that could not be read to the end (a truncated or hostile archive). An uploaded document that reads cleanly is never capped, however much media it holds \u2014 there is no limit on that.", + "title": "Extracted Media Capped", + "type": "boolean" + }, + "extracted_media_count": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "integer" }, { "type": "null" } ], - "title": "Expectation Config" + "description": "Number of embedded images / videos extracted from inside this item and indexed as their own chunks. There is no limit on this \u2014 a document contributes as many as it holds. Null when there is no media record for the item: the extraction pass has not run, does not apply to this container, or found nothing. Treat null as 'unknown', never as zero.", + "title": "Extracted Media Count" }, - "pass_threshold": { + "extracted_media_limit": { "anyOf": [ { - "maximum": 1.0, - "minimum": 0.0, - "type": "number" + "type": "integer" }, { "type": "null" } ], - "title": "Pass Threshold" + "description": "The bound that was reached, when extracted_media_capped is true and the stop was a bound \u2014 a number of fetch attempts, or a number of seconds. Null when extraction was not capped, or when it stopped because the container could not be read rather than because a bound fired.", + "title": "Extracted Media Limit" }, - "step_id": { + "indexed_at": { "anyOf": [ { "type": "string" @@ -7532,85 +7679,100 @@ "type": "null" } ], - "title": "Step Id" - } - }, - "title": "UpdateEvaluationCriteriaRequest", - "type": "object" - }, - "UpdateKnowledgeBaseBody": { - "description": "Request body for updating a knowledge base.", - "properties": { - "default_score_threshold": { + "description": "Timestamp when the item finished indexing and became retrievable. `null` until then.", + "title": "Indexed At" + }, + "mime_type": { "anyOf": [ { - "maximum": 1.0, - "minimum": -1.0, - "type": "number" + "type": "string" }, { "type": "null" } ], - "description": "Default score threshold (-1 to clear).", - "title": "Default Score Threshold" + "description": "MIME type the item was ingested as, when known.", + "title": "Mime Type" }, - "default_top_k": { + "published_at": { "anyOf": [ { - "maximum": 200.0, - "minimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Default reranked results (0 to clear).", - "title": "Default Top K" + "description": "Publication timestamp of the item, when known.", + "title": "Published At" }, - "default_top_n": { + "pulled_at": { + "description": "Timestamp when the item was uploaded or pulled.", + "title": "Pulled At", + "type": "string" + }, + "source_connection_content_version_id": { "anyOf": [ { - "maximum": 200.0, - "minimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Default results (0 to clear).", - "title": "Default Top N" + "description": "ID to pass to `GET /contents/{id}`. `null` until the item has finished indexing \u2014 an item that is still processing, or that failed, has no retrievable content and keeps this `null`.", + "title": "Source Connection Content Version Id" }, - "description": { + "title": { "anyOf": [ { - "maxLength": 1000, "type": "string" }, { "type": "null" } ], - "description": "New description.", - "title": "Description" - }, - "name": { + "description": "Title of the content item.", + "title": "Title" + } + }, + "required": [ + "content_version_id", + "source_connection_content_version_id", + "title", + "content_url", + "content_type", + "mime_type", + "content_status", + "error", + "content_word_count", + "content_token_count", + "pulled_at", + "published_at", + "indexed_at" + ], + "title": "SourceContentStatusResponse", + "type": "object" + }, + "SourceEmbeddingMigrationResponse": { + "description": "Response model for source embedding migration status.", + "properties": { + "completed_at": { "anyOf": [ { - "maxLength": 255, - "minLength": 1, "type": "string" }, { "type": "null" } ], - "description": "New name.", - "title": "Name" + "title": "Completed At" }, - "reranker_model": { + "created_at": { + "title": "Created At", + "type": "string" + }, + "failure_message": { "anyOf": [ { "type": "string" @@ -7619,10 +7781,13 @@ "type": "null" } ], - "description": "Reranker model (empty string for no reranking).", - "title": "Reranker Model" + "title": "Failure Message" }, - "source_ids": { + "id": { + "title": "Id", + "type": "string" + }, + "notification_recipients": { "anyOf": [ { "items": { @@ -7634,17 +7799,17 @@ "type": "null" } ], - "description": "New list of source connection IDs.", - "title": "Source Ids" - } - }, - "title": "UpdateKnowledgeBaseBody", - "type": "object" - }, - "UpdateMemoryBankBody": { - "description": "Request body for updating a memory bank.\n\nOmitted fields are left unchanged. To **clear** a field back to null,\nsend a zero-value sentinel: ``0`` for integers, ``\"\"`` for strings.", - "properties": { - "compaction_prompt": { + "title": "Notification Recipients" + }, + "phase": { + "title": "Phase", + "type": "string" + }, + "progress_current": { + "title": "Progress Current", + "type": "integer" + }, + "progress_message": { "anyOf": [ { "type": "string" @@ -7653,108 +7818,167 @@ "type": "null" } ], - "description": "Custom prompt used when compacting older entries. When set, entries that exceed a threshold are summarized into a new entry before being soft-deleted. Send empty string \"\" to clear and disable summarisation.", - "title": "Compaction Prompt" + "title": "Progress Message" }, - "description": { + "progress_total": { + "title": "Progress Total", + "type": "integer" + }, + "source_connection_id": { + "title": "Source Connection Id", + "type": "string" + }, + "source_id_new": { + "title": "Source Id New", + "type": "string" + }, + "source_id_old": { + "title": "Source Id Old", + "type": "string" + }, + "started_at": { "anyOf": [ { - "maxLength": 1000, "type": "string" }, { "type": "null" } ], - "description": "Optional description. Send empty string \"\" to clear.", - "title": "Description" + "title": "Started At" }, - "max_age_days": { + "status": { + "title": "Status", + "type": "string" + }, + "target_dimensions": { + "title": "Target Dimensions", + "type": "integer" + }, + "target_embedding_model": { + "title": "Target Embedding Model", + "type": "string" + }, + "task_execution_id": { "anyOf": [ { - "minimum": 0.0, - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Max entry age in days before compaction. Checked inline after each write and by the hourly background sweep. Send 0 to disable.", - "title": "Max Age Days" + "title": "Task Execution Id" }, - "max_size_tokens": { + "updated_at": { + "title": "Updated At", + "type": "string" + } + }, + "required": [ + "id", + "source_connection_id", + "source_id_old", + "source_id_new", + "target_embedding_model", + "target_dimensions", + "status", + "phase", + "progress_current", + "progress_total", + "progress_message", + "failure_message", + "notification_recipients", + "task_execution_id", + "started_at", + "completed_at", + "created_at", + "updated_at" + ], + "title": "SourceEmbeddingMigrationResponse", + "type": "object" + }, + "SourceIndexMode": { + "description": "Embedding quality / cost trade-off preset for custom_index sources.\n\nEach preset controls the default embedding dimensions, chunk size, and\nchunk overlap. The embedding model is always the account-level default\n(currently ``AWS_BEDROCK_AMAZON_NOVA_2_MULTIMODAL``).\n\nPresets:\n FAST_AND_CHEAP: 256 dimensions, 3 000 char chunks, 500 char overlap.\n BALANCED: 384 dimensions, 1 500 char chunks, 300 char overlap.\n SLOW_AND_THOROUGH: 1 024 dimensions, 1 000 char chunks, 200 char overlap.\n CUSTOM: Caller supplies embedding model, dimensions, and chunk config.", + "enum": [ + "fast_and_cheap", + "balanced", + "slow_and_thorough", + "custom" + ], + "title": "SourceIndexMode", + "type": "string" + }, + "SourceResponse": { + "description": "Response model for source data.", + "properties": { + "account_id": { + "description": "Account ID associated with the source.", + "format": "uuid", + "title": "Account Id", + "type": "string" + }, + "avg_episodes_per_month": { "anyOf": [ { - "minimum": 0.0, - "type": "integer" + "type": "number" }, { "type": "null" } ], - "description": "Max total tokens (per partition) before compaction. Checked inline after each write and by the hourly background sweep. Send 0 to disable.", - "title": "Max Size Tokens" + "description": "Average number of episodes per month.", + "title": "Avg Episodes Per Month" }, - "max_turns": { + "avg_words_per_episode": { "anyOf": [ { - "minimum": 0.0, "type": "integer" }, { "type": "null" } ], - "description": "Max conversation turns (per partition) before compaction. Checked inline after each write and by the hourly background sweep. Send 0 to disable.", - "title": "Max Turns" + "description": "Average number of words per episode.", + "title": "Avg Words Per Episode" }, - "name": { + "chunk_language": { "anyOf": [ { - "maxLength": 255, - "minLength": 1, "type": "string" }, { "type": "null" } ], - "description": "New name.", - "title": "Name" + "description": "Language used for chunking content.", + "title": "Chunk Language" }, - "retention_days": { + "chunk_overlap": { "anyOf": [ { - "minimum": 0.0, "type": "integer" }, { "type": "null" } ], - "description": "Content source retention in days. Send 0 to clear (indefinite).", - "title": "Retention Days" - } - }, - "title": "UpdateMemoryBankBody", - "type": "object" - }, - "UpdateSolutionRequest": { - "description": "Request model for updating a solution", - "properties": { - "description": { + "description": "Chunk overlap for content processing.", + "title": "Chunk Overlap" + }, + "chunk_regex_separators": { "anyOf": [ { - "type": "string" + "type": "boolean" }, { "type": "null" } ], - "description": "Description of the solution", - "title": "Description" + "description": "Indicates if chunk separators are regex patterns.", + "title": "Chunk Regex Separators" }, - "name": { + "chunk_separators": { "anyOf": [ { "type": "string" @@ -7763,46 +7987,50 @@ "type": "null" } ], - "description": "Name of the solution", - "title": "Name" - } - }, - "title": "UpdateSolutionRequest", - "type": "object" - }, - "UpdateSourceBody": { - "description": "Request body for updating a content source.", - "properties": { - "media_types": { + "description": "Chunk separators used for content processing.", + "title": "Chunk Separators" + }, + "chunk_size": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "type": "integer" }, { "type": "null" } ], - "description": "Media kinds to extract from indexed content and embed as multi-modal KB chunks. Subset of ['images', 'video']. Only kinds the source's embedder can index are honored; unsupported values are dropped. [] disables media extraction (text-only).", - "title": "Media Types" + "description": "Chunk size for content processing.", + "title": "Chunk Size" }, - "name": { + "content_count": { + "default": 0, + "description": "Number of content items associated with the source connection.", + "title": "Content Count", + "type": "integer" + }, + "content_filter": { + "description": "Content filter for the source connection.", + "title": "Content Filter", + "type": "string" + }, + "created_at": { + "description": "Timestamp when the source connection was created.", + "title": "Created At", + "type": "string" + }, + "dimensions": { "anyOf": [ { - "maxLength": 255, - "minLength": 1, - "type": "string" + "type": "integer" }, { "type": "null" } ], - "description": "New name.", - "title": "Name" + "description": "Dimensions of the embedding model.", + "title": "Dimensions" }, - "polling": { + "embedding_model": { "anyOf": [ { "type": "string" @@ -7811,154 +8039,69 @@ "type": "null" } ], - "description": "New polling interval.", - "title": "Polling" + "description": "Embedding model used for the source connection.", + "title": "Embedding Model" }, - "retention_days": { + "embedding_model_type": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "default": -1, - "description": "New retention period in days (null for unlimited).", - "title": "Retention Days" - } - }, - "title": "UpdateSourceBody", - "type": "object" - }, - "UploadAgentInputApiResponse": { - "properties": { - "content_type": { - "description": "Resolved MIME type.", - "title": "Content Type", - "type": "string" + "description": "Type of the embedding model.", + "title": "Embedding Model Type" }, - "error": { + "free_retention_days": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "description": "Error message if status is failed.", - "title": "Error" + "description": "Number of days content is stored for free before billing applies.", + "title": "Free Retention Days" }, - "file_size": { - "description": "Size in bytes.", - "title": "File Size", - "type": "integer" - }, - "filename": { - "description": "Original filename.", - "title": "Filename", - "type": "string" + "has_historical_data": { + "default": false, + "description": "Indicates if the source connection has historical data.", + "title": "Has Historical Data", + "type": "boolean" }, "id": { - "description": "Unique identifier for the upload.", + "description": "Unique identifier for the source connection.", "title": "Id", "type": "string" }, - "status": { - "description": "processing, ready, or failed.", - "title": "Status", - "type": "string" - } - }, - "required": [ - "id", - "status", - "filename", - "content_type", - "file_size" - ], - "title": "UploadAgentInputApiResponse", - "type": "object" - }, - "ValidationError": { - "properties": { - "loc": { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "title": "Location", - "type": "array" - }, - "msg": { - "title": "Message", - "type": "string" - }, - "type": { - "title": "Error Type", - "type": "string" - } - }, - "required": [ - "loc", - "msg", - "type" - ], - "title": "ValidationError", - "type": "object" - }, - "VariantCategoryResponse": { - "description": "Response model for a variant category", - "properties": { - "category": { - "title": "Category", - "type": "string" - }, - "configurable": { - "title": "Configurable", - "type": "boolean" - }, - "description": { - "title": "Description", - "type": "string" + "index_mode": { + "anyOf": [ + { + "$ref": "#/components/schemas/SourceIndexMode" + }, + { + "type": "null" + } + ], + "description": "Index mode for custom_index sources: fast_and_cheap, balanced, slow_and_thorough, or custom." }, - "options": { + "media_types": { + "description": "Media kinds extracted from indexed content and embedded as multi-modal KB chunks (subset of ['images', 'video']). Empty = text-only.", "items": { - "$ref": "#/components/schemas/VariantOptionResponse" + "type": "string" }, - "title": "Options", + "title": "Media Types", "type": "array" }, - "title": { - "title": "Title", + "name": { + "description": "Name of the source connection.", + "title": "Name", "type": "string" - } - }, - "required": [ - "category", - "title", - "description", - "configurable", - "options" - ], - "title": "VariantCategoryResponse", - "type": "object" - }, - "VariantOptionResponse": { - "description": "Response model for a variant option", - "properties": { - "default": { - "title": "Default", - "type": "boolean" }, - "description": { + "next_poll_at": { "anyOf": [ { "type": "string" @@ -7967,144 +8110,187 @@ "type": "null" } ], - "title": "Description" + "description": "Timestamp for the next scheduled poll.", + "title": "Next Poll At" }, - "input_1h_cache_write_credits_per_1000_tokens": { + "polling": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Input 1H Cache Write Credits Per 1000 Tokens" + "description": "Polling configuration for the source connection.", + "title": "Polling" }, - "input_5m_cache_write_credits_per_1000_tokens": { + "polling_action": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Input 5M Cache Write Credits Per 1000 Tokens" + "description": "Polling action for the source connection.", + "title": "Polling Action" }, - "input_cache_hit_credits_per_1000_tokens": { + "polling_max_items": { "anyOf": [ { - "type": "number" + "type": "integer" }, { "type": "null" } ], - "title": "Input Cache Hit Credits Per 1000 Tokens" + "description": "Maximum items to poll for the source connection.", + "title": "Polling Max Items" }, - "input_credits_per_1000_tokens": { + "pulled_at": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Input Credits Per 1000 Tokens" + "description": "Timestamp when content was last pulled.", + "title": "Pulled At" }, - "long_context_input_cache_hit_credits_per_1000_tokens": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "title": "Long Context Input Cache Hit Credits Per 1000 Tokens" + "readonly": { + "default": false, + "description": "Indicates if the source connection is read-only.", + "title": "Readonly", + "type": "boolean" }, - "long_context_input_credits_per_1000_tokens": { + "retention": { "anyOf": [ { - "type": "number" + "type": "integer" }, { "type": "null" } ], - "title": "Long Context Input Credits Per 1000 Tokens" + "description": "Retention period for the source connection.", + "title": "Retention" }, - "long_context_output_credits_per_1000_tokens": { + "source_type": { + "description": "Type of the source connection.", + "title": "Source Type", + "type": "string" + }, + "system_managed": { + "default": false, + "description": "Indicates if this source is automatically managed by the system (e.g., agent traces).", + "title": "System Managed", + "type": "boolean" + }, + "updated_at": { + "description": "Timestamp when the source connection was last updated.", + "title": "Updated At", + "type": "string" + }, + "url": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Long Context Output Credits Per 1000 Tokens" + "description": "URL of the source connection.", + "title": "Url" + } + }, + "required": [ + "id", + "account_id", + "name", + "url", + "source_type", + "polling", + "polling_action", + "polling_max_items", + "content_filter", + "retention", + "pulled_at", + "next_poll_at", + "created_at", + "updated_at" + ], + "title": "SourceResponse", + "type": "object" + }, + "StandaloneTestCompactionRequest": { + "description": "Request body for testing a compaction prompt *without* an existing bank.\n\nUsed on the create-memory-bank page where no bank ID exists yet.\n``compaction_prompt`` is required (no bank to fall back to).\nContent must come from ``sample_entries`` or ``generate_direction``\n(no existing entries to fetch).", + "properties": { + "bank_type": { + "default": "conversation", + "description": "Memory bank type ('conversation' or 'general') \u2014 controls the style of generated entries.", + "title": "Bank Type", + "type": "string" }, - "long_context_threshold": { + "compaction_prompt": { + "description": "Compaction prompt to test.", + "minLength": 1, + "title": "Compaction Prompt", + "type": "string" + }, + "entry_count": { + "default": 5, + "description": "Number of entries to generate when using generate_direction.", + "maximum": 20.0, + "minimum": 2.0, + "title": "Entry Count", + "type": "integer" + }, + "generate_direction": { "anyOf": [ { - "type": "integer" + "maxLength": 2000, + "type": "string" }, { "type": "null" } ], - "title": "Long Context Threshold" + "description": "Direction for the LLM to generate sample entries.", + "title": "Generate Direction" }, - "output_credits_per_1000_tokens": { + "sample_entries": { "anyOf": [ { - "type": "number" + "items": { + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" }, { "type": "null" } ], - "title": "Output Credits Per 1000 Tokens" - }, - "title": { - "title": "Title", - "type": "string" - }, - "value": { - "title": "Value", - "type": "string" - } - }, - "required": [ - "value", - "title", - "default" - ], - "title": "VariantOptionResponse", - "type": "object" - }, - "routers__api__agents__AgentImportPreviewRequest": { - "description": "Dry-run import request \u2014 same payload shape as the export endpoint.", - "properties": { - "agent_definition": { - "additionalProperties": true, - "description": "Payload in the same shape as GET /agents/{agent_id}/export.", - "title": "Agent Definition", - "type": "object" + "description": "Explicit sample entries to compact.", + "title": "Sample Entries" } }, "required": [ - "agent_definition" + "compaction_prompt" ], - "title": "AgentImportPreviewRequest", + "title": "StandaloneTestCompactionRequest", "type": "object" }, - "routers__api__agents__AgentImportPreviewResponse": { - "description": "Summary of a successfully validated import payload (no DB writes).\n\nCounts are derived from the validated payload as supplied \u2014 they\nreflect what was requested, not what would eventually be persisted\n(cross-account skips for recipients and KB names happen later, only\non commit).", + "StartSourceEmbeddingMigrationRequest": { + "description": "Request payload to start a source embedding migration.", "properties": { - "agent_name": { + "chunk_language": { "anyOf": [ { "type": "string" @@ -8113,143 +8299,35 @@ "type": "null" } ], - "description": "Imported agent name, if any.", - "title": "Agent Name" - }, - "alert_configs": { - "description": "Number of alert configs in the payload.", - "title": "Alert Configs", - "type": "integer" + "description": "Language-specific chunking language code", + "title": "Chunk Language" }, - "description": { + "chunk_overlap": { "anyOf": [ { - "type": "string" + "minimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "description": "Imported agent description, if any.", - "title": "Description" - }, - "evaluation_criteria": { - "description": "Number of evaluation criteria in the payload.", - "title": "Evaluation Criteria", - "type": "integer" - }, - "governance_policies": { - "description": "Number of agent-scoped governance policies in the payload.", - "title": "Governance Policies", - "type": "integer" - }, - "ok": { - "description": "Always true on a 200 response; failures use HTTP 422.", - "title": "Ok", - "type": "boolean" + "description": "Override chunk overlap (characters)", + "title": "Chunk Overlap" }, - "payload_export_version": { + "chunk_regex_separators": { "anyOf": [ { - "type": "string" + "type": "boolean" }, { "type": "null" } ], - "description": "Export-format version the payload claims (or ``null`` for legacy payloads). When this differs from ``supported_export_version``, fields may have been silently dropped or defaulted on import.", - "title": "Payload Export Version" - }, - "schedules": { - "description": "Number of trigger schedules in the payload.", - "title": "Schedules", - "type": "integer" - }, - "solutions": { - "default": 0, - "description": "Number of solutions the source agent belonged to. On import these are matched by name in the target account; unmatched names are silently skipped.", - "title": "Solutions", - "type": "integer" - }, - "step_count": { - "description": "Total number of steps in the workflow tree (recursive).", - "title": "Step Count", - "type": "integer" - }, - "supported_export_version": { - "default": "2", - "description": "Export-format version this server understands. Compare against ``payload_export_version`` to detect cross-version imports.", - "title": "Supported Export Version", - "type": "string" - }, - "unresolved_refs": { - "description": "Entity references in the imported workflow that don't exist in the target account. Each entry: {category, ref_id, ref_name?, locations:[step:], alternatives:[{id, name, description?}]}. Pass {source_uuid: target_uuid} as ``entity_remap`` on the create/update call to substitute these references before save.", - "items": { - "additionalProperties": true, - "type": "object" - }, - "title": "Unresolved Refs", - "type": "array" - } - }, - "required": [ - "ok", - "agent_name", - "description", - "step_count", - "schedules", - "alert_configs", - "evaluation_criteria", - "governance_policies" - ], - "title": "AgentImportPreviewResponse", - "type": "object" - }, - "routers__api__agents__AgentListResponse": { - "properties": { - "data": { - "description": "List of agents.", - "items": { - "$ref": "#/components/schemas/AgentSummaryResponse" - }, - "title": "Data", - "type": "array" - }, - "pagination": { - "$ref": "#/components/schemas/PaginationResponse" - } - }, - "required": [ - "data", - "pagination" - ], - "title": "AgentListResponse", - "type": "object" - }, - "routers__api__agents__AgentRunListResponse": { - "properties": { - "data": { - "description": "List of agent runs.", - "items": { - "$ref": "#/components/schemas/AgentRunResponse" - }, - "title": "Data", - "type": "array" + "description": "Whether chunk separators are regex patterns", + "title": "Chunk Regex Separators" }, - "pagination": { - "$ref": "#/components/schemas/PaginationResponse" - } - }, - "required": [ - "data", - "pagination" - ], - "title": "AgentRunListResponse", - "type": "object" - }, - "routers__api__agents__AgentTraceSearchRequest": { - "properties": { - "agent_id": { + "chunk_separators": { "anyOf": [ { "type": "string" @@ -8258,134 +8336,117 @@ "type": "null" } ], - "description": "Filter by agent ID.", - "title": "Agent Id" - }, - "query": { - "description": "Search query text.", - "title": "Query", - "type": "string" + "description": "Custom chunk separators (JSON-encoded list)", + "title": "Chunk Separators" }, - "run_status": { + "chunk_size": { "anyOf": [ { - "type": "string" + "exclusiveMinimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "description": "Filter by run status.", - "title": "Run Status" + "description": "Override chunk size (characters per chunk)", + "title": "Chunk Size" }, - "step_type": { + "notification_recipients": { "anyOf": [ { - "type": "string" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "description": "Filter by step type.", - "title": "Step Type" + "description": "Optional notification recipient emails", + "title": "Notification Recipients" }, - "top_n": { - "default": 10, - "description": "Maximum number of results.", - "maximum": 100.0, - "minimum": 1.0, - "title": "Top N", + "target_dimensions": { + "description": "Target embedding dimensions", + "exclusiveMinimum": 0.0, + "title": "Target Dimensions", "type": "integer" + }, + "target_embedding_model": { + "description": "Target embedding model \u2014 a `model_type` from `GET /models/embedders`, which also reports the `dimensions` each embedder supports and the modalities it can index.", + "title": "Target Embedding Model", + "type": "string" } }, "required": [ - "query" + "target_embedding_model", + "target_dimensions" ], - "title": "AgentTraceSearchRequest", + "title": "StartSourceEmbeddingMigrationRequest", "type": "object" }, - "routers__api__agents__CreateAgentRequest": { + "TestCompactionRequest": { + "description": "Request body for testing a compaction prompt against an existing bank.\n\nThe user may supply a ``compaction_prompt`` to override (or provide when\nthe bank has none). Content can come from three sources:\n\n1. Existing entries in the bank (default when neither field is set).\n2. ``sample_entries`` \u2013 caller-provided list of strings.\n3. ``generate_direction`` \u2013 an instruction to the LLM to generate sample\n memory entries. Useful for trying a prompt before any real data\n exists.\n\nAt most one of ``sample_entries`` / ``generate_direction`` may be given.", "properties": { - "agent_definition": { + "compaction_prompt": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "Optional payload in the same format produced by GET /agents/{id}/export. When provided, replaces any template-derived workflow and pre-fills metadata/trigger fields the request does not specify explicitly. Validation errors include line/column references against a canonical pretty-printed echo of the supplied payload.", - "title": "Agent Definition" + "description": "Compaction prompt to test. Falls back to the bank's current prompt when omitted.", + "title": "Compaction Prompt" }, - "agent_template": { + "entry_count": { + "default": 5, + "description": "Number of entries to generate when using generate_direction.", + "maximum": 20.0, + "minimum": 2.0, + "title": "Entry Count", + "type": "integer" + }, + "generate_direction": { "anyOf": [ { + "maxLength": 2000, "type": "string" }, { "type": "null" } ], - "description": "Template to initialize the agent from. Values: blank, retrieval_example, simple_qa, summarizer, json_extractor, content_change_notifier, scheduled_report, webhook_pipeline.", - "title": "Agent Template" + "description": "Direction for the LLM to generate sample entries (e.g. 'Generate 5 entries about a customer support interaction').", + "title": "Generate Direction" }, - "description": { + "sample_entries": { "anyOf": [ { - "type": "string" + "items": { + "type": "string" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" }, { "type": "null" } ], - "description": "Optional description.", - "title": "Description" - }, - "entity_remap": { - "anyOf": [ - { - "additionalProperties": { - "type": "string" - }, - "type": "object" - }, - { - "type": "null" - } - ], - "description": "Optional UUID-substitution map applied to the imported workflow before save. Each key is a source-account UUID (as returned by /agents/preview-import's ``unresolved_refs``); each value is the target-account UUID to substitute. Used to relink knowledge bases, memory banks, source connections, and sub-agents on cross-account imports.", - "title": "Entity Remap" - }, - "name": { - "description": "Name for the new agent.", - "title": "Name", - "type": "string" - }, - "trigger_type": { - "default": "dynamic_input", - "description": "Trigger type: dynamic_input, template_input, schedule, new_content, email_received.", - "title": "Trigger Type", - "type": "string" + "description": "Explicit sample entries to compact.", + "title": "Sample Entries" } }, - "required": [ - "name" - ], - "title": "CreateAgentRequest", + "title": "TestCompactionRequest", "type": "object" }, - "routers__api__agents__GovernancePolicyRefResponse": { - "description": "Reference to a governance policy by id and name.", + "TestDraftEvaluationRequest": { + "description": "Request body for ephemeral (non-persisted) evaluation testing.\n\nProvide either ``step_output`` (raw text) **or** ``agent_step_run_id``\n(to load output from storage). Exactly one must be supplied.", "properties": { - "policy_id": { - "description": "Governance policy identifier.", - "title": "Policy Id", - "type": "string" - }, - "policy_name": { + "agent_input": { "anyOf": [ { "type": "string" @@ -8394,115 +8455,178 @@ "type": "null" } ], - "description": "Display name of the policy at evaluation time. May be null when the policy has been deleted.", - "title": "Policy Name" - } - }, - "required": [ - "policy_id" - ], - "title": "GovernancePolicyRefResponse", - "type": "object" - }, - "routers__api__agents__SetEmailTriggerConfigRequest": { - "description": "Alias and/or sender allowlist for an EMAIL_RECEIVED trigger.\n\nA field omitted is left unchanged; passing ``null`` (or ``\"\"`` for\n``alias``) clears it.", - "properties": { - "alias": { + "description": "The original agent run input for context. When agent_step_run_id is supplied this is loaded automatically from the parent run if omitted.", + "title": "Agent Input" + }, + "agent_step_run_id": { "anyOf": [ { - "maxLength": 32, + "format": "uuid", "type": "string" }, { "type": "null" } ], - "description": "Custom alias for the address `.@agent.seclai.com` (alphanumeric plus '+', '.', '-'; 1\u201332 chars; not starting/ending with '+', '.', '-'; not UUID-shaped). Pass null/empty to clear.", - "title": "Alias" + "description": "Load step output from this completed step run instead of supplying text.", + "title": "Agent Step Run Id" }, - "allowed_senders": { + "evaluation_prompt": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "type": "string" }, { "type": "null" } ], - "description": "Allowlist of full sender addresses and/or bare domains (a bare domain also matches sub-domains). Empty/null accepts any sender.", - "title": "Allowed Senders" + "title": "Evaluation Prompt" }, - "ignore_auto_generated": { + "evaluation_tier": { "anyOf": [ { - "type": "boolean" + "$ref": "#/components/schemas/AgentEvaluationTier" }, { "type": "null" } - ], - "description": "When true (default for new triggers), machine-generated inbound mail (auto-replies, bulk/list mail, bounces) is dropped before a run to prevent auto-reply loops. Set false to process automated mail.", - "title": "Ignore Auto Generated" + ] }, - "queue_on_quota": { + "expectation_config": { "anyOf": [ { - "type": "boolean" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "When true (default false), inbound mail that exceeds the account's hourly email-trigger rate is parked in a QUEUED run and drained later by the catch-up sweep instead of being failed; when false, over-rate mail fails immediately.", - "title": "Queue On Quota" + "title": "Expectation Config" }, - "require_sender_auth": { + "pass_threshold": { + "default": 0.5, + "maximum": 1.0, + "minimum": 0.0, + "title": "Pass Threshold", + "type": "number" + }, + "step_output": { "anyOf": [ { - "type": "boolean" + "minLength": 1, + "type": "string" }, { "type": "null" } ], - "description": "When true (default for new triggers), the envelope sender must pass SPF or DMARC even on an open inbox (no allowlist); unauthenticated, spoofable mail is rejected. Set false to accept fully unauthenticated mail on an open inbox.", - "title": "Require Sender Auth" + "description": "The step output text to evaluate. Omit if agent_step_run_id is supplied.", + "title": "Step Output" } }, - "title": "SetEmailTriggerConfigRequest", + "title": "TestDraftEvaluationRequest", "type": "object" }, - "routers__api__agents__UpdateAgentRequest": { + "TestDraftEvaluationResponse": { + "description": "Response for an ephemeral evaluation test.", "properties": { - "agent_definition": { + "explanation": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "Optional payload in the same format produced by GET /agents/{id}/export. When provided, agent metadata fields the request does not set explicitly are taken from the payload, and the agent's workflow is replaced from `agent.definition`. The previous version is preserved in history. Validation errors include line/column references against a canonical pretty-printed echo of the supplied payload.", - "title": "Agent Definition" + "title": "Explanation" }, - "default_evaluation_tier": { + "passed": { + "title": "Passed", + "type": "boolean" + }, + "score": { + "title": "Score", + "type": "number" + } + }, + "required": [ + "score", + "passed", + "explanation" + ], + "title": "TestDraftEvaluationResponse", + "type": "object" + }, + "UnlinkResourcesRequest": { + "properties": { + "ids": { + "description": "Resource IDs to unlink", + "items": { + "format": "uuid", + "type": "string" + }, + "minItems": 1, + "title": "Ids", + "type": "array" + } + }, + "required": [ + "ids" + ], + "title": "UnlinkResourcesRequest", + "type": "object" + }, + "UnreadCountResponse": { + "properties": { + "count": { + "title": "Count", + "type": "integer" + } + }, + "required": [ + "count" + ], + "title": "UnreadCountResponse", + "type": "object" + }, + "UpdateAgentDefinitionRequest": { + "properties": { + "definition": { + "additionalProperties": true, + "description": "The full agent definition (name, description, tags, steps). Steps form a tree workflow. Each step has a `step_type`, `id`, `name`, and type-specific config. Content enrichment steps (write_metadata, write_content_attachment, load_content_attachment, load_content) require content-triggered agents.", + "title": "Definition", + "type": "object" + }, + "expected_change_id": { + "description": "The change_id from the last GET, for optimistic locking.", + "title": "Expected Change Id", + "type": "string" + } + }, + "required": [ + "expected_change_id", + "definition" + ], + "title": "UpdateAgentDefinitionRequest", + "type": "object" + }, + "UpdateAlertConfigRequest": { + "properties": { + "cooldown_minutes": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "description": "Default evaluation tier: 'fast', 'balanced', or 'thorough'.", - "title": "Default Evaluation Tier" + "description": "Cooldown period in minutes", + "title": "Cooldown Minutes" }, - "description": { + "distribution_type": { "anyOf": [ { "type": "string" @@ -8511,49 +8635,56 @@ "type": "null" } ], - "description": "New description for the agent.", - "title": "Description" + "description": "Distribution type", + "title": "Distribution Type" }, - "entity_remap": { + "enabled": { "anyOf": [ { - "additionalProperties": { - "type": "string" - }, - "type": "object" + "type": "boolean" }, { "type": "null" } ], - "description": "Optional UUID-substitution map applied to the imported workflow before save (same shape as on POST /agents).", - "title": "Entity Remap" + "description": "Whether the alert config is enabled", + "title": "Enabled" }, - "evaluation_mode": { + "recipient_user_ids": { "anyOf": [ { - "type": "string" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "description": "Evaluation mode: 'output_expectation', 'eval_and_retry', or 'sample_and_flag'.", - "title": "Evaluation Mode" + "description": "User IDs for selected_members distribution", + "title": "Recipient User Ids" }, - "max_retries": { + "threshold": { "anyOf": [ { - "type": "integer" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Max retries for eval_and_retry mode (1-10).", - "title": "Max Retries" - }, - "name": { + "description": "Threshold configuration", + "title": "Threshold" + } + }, + "title": "UpdateAlertConfigRequest", + "type": "object" + }, + "UpdateApiVersionRequest": { + "properties": { + "version": { "anyOf": [ { "type": "string" @@ -8562,60 +8693,60 @@ "type": "null" } ], - "description": "New name for the agent.", - "title": "Name" - }, - "prompt_model_auto_rollback_enabled": { - "anyOf": [ - { - "type": "boolean" - }, - { + "description": "A YYYY-MM-DD date to pin the account to, or null to clear the pin (revert to the default baseline).", + "title": "Version" + } + }, + "title": "UpdateApiVersionRequest", + "type": "object" + }, + "UpdateEvaluationCriteriaRequest": { + "description": "Request body for updating an evaluation criteria.\n\nRetry settings and sample frequency are set at the agent level.", + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { "type": "null" } ], - "description": "Enable or disable automatic rollback for upgraded models.", - "title": "Prompt Model Auto Rollback Enabled" + "title": "Description" }, - "prompt_model_auto_rollback_triggers": { + "enabled": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "type": "boolean" }, { "type": "null" } ], - "description": "Failure signals that trigger rollback: agent_eval_fail, governance_flag, governance_block, agent_run_failed.", - "title": "Prompt Model Auto Rollback Triggers" + "title": "Enabled" }, - "prompt_model_auto_upgrade_strategy": { + "evaluation_prompt": { "anyOf": [ { - "$ref": "#/components/schemas/PromptModelAutoUpgradeStrategy" + "type": "string" }, { "type": "null" } ], - "description": "Auto-upgrade strategy: none, early_adopter, middle_of_road, cautious_adopter." + "title": "Evaluation Prompt" }, - "retry_on_failure": { + "evaluation_tier": { "anyOf": [ { - "type": "boolean" + "$ref": "#/components/schemas/AgentEvaluationTier" }, { "type": "null" } - ], - "description": "Whether to retry on evaluation failure.", - "title": "Retry On Failure" + ] }, - "sampling_config": { + "expectation_config": { "anyOf": [ { "additionalProperties": true, @@ -8625,137 +8756,143 @@ "type": "null" } ], - "description": "Sampling configuration for sample_and_flag mode. Format: {combinator: 'and'|'or', rules: [...]}.", - "title": "Sampling Config" - }, - "set_default_evaluation_tier": { - "default": false, - "description": "When true and default_evaluation_tier is omitted, clears the tier to null (system default).", - "title": "Set Default Evaluation Tier", - "type": "boolean" + "title": "Expectation Config" }, - "set_prompt_model_auto_rollback_triggers": { - "default": false, - "description": "When true and prompt_model_auto_rollback_triggers is omitted, clears the list to null (revert to system defaults).", - "title": "Set Prompt Model Auto Rollback Triggers", - "type": "boolean" + "pass_threshold": { + "anyOf": [ + { + "maximum": 1.0, + "minimum": 0.0, + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Pass Threshold" }, - "set_sampling_config": { - "default": false, - "description": "When true and sampling_config is omitted, clears the config to null.", - "title": "Set Sampling Config", - "type": "boolean" + "step_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Step Id" } }, - "title": "UpdateAgentRequest", + "title": "UpdateEvaluationCriteriaRequest", "type": "object" }, - "routers__api__ai_assistant__AiAssistantFeedbackRequest": { - "description": "Request body for submitting AI assistant feedback.", + "UpdateKnowledgeBaseBody": { + "description": "Request body for updating a knowledge base.", "properties": { - "agent_conversation_id": { + "default_score_threshold": { "anyOf": [ { - "format": "uuid", - "type": "string" + "maximum": 1.0, + "minimum": -1.0, + "type": "number" }, { "type": "null" } ], - "description": "Agent conversation ID, if applicable.", - "title": "Agent Conversation Id" + "description": "Prefilled into Minimum Rerank Score on a new retrieval step (-1 to clear).", + "title": "Default Score Threshold" }, - "comment": { + "default_top_k": { "anyOf": [ { - "type": "string" + "maximum": 200.0, + "minimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "description": "Optional comment.", - "title": "Comment" + "description": "Prefilled into Top K on a new retrieval step (0 to clear).", + "title": "Default Top K" }, - "context": { + "default_top_n": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "maximum": 200.0, + "minimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "description": "Additional context.", - "title": "Context" + "description": "Prefilled into Top N on a new retrieval step (0 to clear).", + "title": "Default Top N" }, - "conversation_id": { + "description": { "anyOf": [ { - "format": "uuid", + "maxLength": 1000, "type": "string" }, { "type": "null" } ], - "description": "Conversation ID for the interaction.", - "title": "Conversation Id" + "description": "New description.", + "title": "Description" }, - "feature": { - "description": "Feature name (e.g. 'source', 'solution').", - "title": "Feature", - "type": "string" + "name": { + "anyOf": [ + { + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "New name.", + "title": "Name" }, - "prompt_call_id": { + "reranker_model": { "anyOf": [ { - "format": "uuid", "type": "string" }, { "type": "null" } ], - "description": "Prompt call ID for credit tracking.", - "title": "Prompt Call Id" + "description": "New reranker model \u2014 a `model_type` from `GET /models/rerankers`. Pass \"none\" to turn reranking off (not a value from that list). Omitting the field (or sending null) leaves the current reranker in place \u2014 it does NOT turn it off. \"\" is accepted as a synonym for \"none\", but prefer \"none\": an empty string does not survive every client's serialization.", + "title": "Reranker Model" }, - "rating": { - "description": "Rating: 'thumbs_up' or 'thumbs_down'.", - "title": "Rating", - "type": "string" - } - }, - "required": [ - "feature", - "rating" - ], - "title": "AiAssistantFeedbackRequest", - "type": "object" - }, - "routers__api__alerts__AddCommentRequest": { - "properties": { - "body": { - "description": "Comment text", - "title": "Body", - "type": "string" + "source_ids": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "New list of source connection IDs.", + "title": "Source Ids" } }, - "required": [ - "body" - ], - "title": "AddCommentRequest", + "title": "UpdateKnowledgeBaseBody", "type": "object" }, - "routers__api__alerts__AlertCommentResponse": { + "UpdateMemoryBankBody": { + "description": "Request body for updating a memory bank.\n\nOmitted fields are left unchanged. To **clear** a field back to null,\nsend a zero-value sentinel: ``0`` for integers, ``\"\"`` for strings.", "properties": { - "body": { - "title": "Body", - "type": "string" - }, - "created_at": { + "compaction_prompt": { "anyOf": [ { "type": "string" @@ -8764,153 +8901,107 @@ "type": "null" } ], - "title": "Created At" - }, - "id": { - "title": "Id", - "type": "string" - }, - "user_id": { - "title": "User Id", - "type": "string" + "description": "Custom prompt used when compacting older entries. When set, entries that exceed a threshold are summarized into a new entry before being soft-deleted. Send empty string \"\" to clear and disable summarisation.", + "title": "Compaction Prompt" }, - "user_name": { + "description": { "anyOf": [ { + "maxLength": 1000, "type": "string" }, { "type": "null" } ], - "title": "User Name" - } - }, - "required": [ - "id", - "user_id", - "user_name", - "body", - "created_at" - ], - "title": "AlertCommentResponse", - "type": "object" - }, - "routers__api__alerts__AlertDetailResponse": { - "properties": { - "alert": { - "$ref": "#/components/schemas/routers__api__alerts__AlertResponse" - }, - "comments": { - "items": { - "$ref": "#/components/schemas/routers__api__alerts__AlertCommentResponse" - }, - "title": "Comments", - "type": "array" + "description": "Optional description. Send empty string \"\" to clear.", + "title": "Description" }, - "history": { - "items": { - "$ref": "#/components/schemas/AlertHistoryEntryResponse" - }, - "title": "History", - "type": "array" + "max_age_days": { + "anyOf": [ + { + "minimum": 0.0, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "DEPRECATED and no longer applied. Age now belongs solely to retention_days, which deletes; compaction triggers on max_size_tokens and max_turns. Rejected with 400 for clients sending Seclai-Version 2026-08-03 or later, except 0, which clears a value stored earlier. Accepted and stored but inert for older clients.", + "title": "Max Age Days" }, - "subscribers": { - "items": { - "$ref": "#/components/schemas/routers__api__alerts__AlertSubscriberResponse" - }, - "title": "Subscribers", - "type": "array" - } - }, - "required": [ - "alert", - "history", - "comments", - "subscribers" - ], - "title": "AlertDetailResponse", - "type": "object" - }, - "routers__api__alerts__AlertListResponse": { - "description": "``GET /alerts`` \u2014 always the canonical ``{data, pagination}`` envelope.", - "properties": { - "data": { - "items": { - "$ref": "#/components/schemas/routers__api__alerts__AlertResponse" - }, - "title": "Data", - "type": "array" - }, - "pagination": { - "$ref": "#/components/schemas/PaginationResponse" - } - }, - "required": [ - "data", - "pagination" - ], - "title": "AlertListResponse", - "type": "object" - }, - "routers__api__alerts__AlertResponse": { - "properties": { - "account_id": { - "title": "Account Id", - "type": "string" - }, - "agent_id": { + "max_size_tokens": { "anyOf": [ { - "type": "string" + "minimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "title": "Agent Id" + "description": "Max total tokens (per partition) before compaction. Checked inline after each write and by the hourly background sweep. Send 0 to disable.", + "title": "Max Size Tokens" }, - "agent_run_id": { + "max_turns": { "anyOf": [ { - "type": "string" + "minimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "title": "Agent Run Id" + "description": "Max conversation turns (per partition) before compaction. Checked inline after each write and by the hourly background sweep. Send 0 to disable.", + "title": "Max Turns" }, - "alert_config_id": { + "name": { "anyOf": [ { + "maxLength": 255, + "minLength": 1, "type": "string" }, { "type": "null" } ], - "title": "Alert Config Id" - }, - "alert_type": { - "title": "Alert Type", - "type": "string" - }, - "comment_count": { - "title": "Comment Count", - "type": "integer" + "description": "New name.", + "title": "Name" }, - "created_at": { + "retention_days": { "anyOf": [ { - "type": "string" + "minimum": 0.0, + "type": "integer" }, { "type": "null" } ], - "title": "Created At" + "description": "Content source retention in days. Send 0 to clear (indefinite).", + "title": "Retention Days" }, + "strip_quoted_reply_chains": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Conversation banks only. When true, a conversation turn written to this bank has the quoted reply chain an email client prepends to a reply dropped from it. Only inbound (user) turns are affected, and only words in a run of at least ~40 matching a recent turn word for word are dropped (line wrapping and punctuation at a word's edge are ignored). A word the sender changed is kept, including a one-character change inside a link, address or amount, unless the change is only to that edge punctuation.", + "title": "Strip Quoted Reply Chains" + } + }, + "title": "UpdateMemoryBankBody", + "type": "object" + }, + "UpdateSolutionRequest": { + "description": "Request model for updating a solution", + "properties": { "description": { "anyOf": [ { @@ -8920,20 +9011,10 @@ "type": "null" } ], + "description": "Description of the solution", "title": "Description" }, - "details": { - "title": "Details" - }, - "id": { - "title": "Id", - "type": "string" - }, - "is_subscribed": { - "title": "Is Subscribed", - "type": "boolean" - }, - "mcp_client_id": { + "name": { "anyOf": [ { "type": "string" @@ -8942,20 +9023,46 @@ "type": "null" } ], - "title": "Mcp Client Id" + "description": "Name of the solution", + "title": "Name" + } + }, + "title": "UpdateSolutionRequest", + "type": "object" + }, + "UpdateSourceBody": { + "description": "Request body for updating a content source.", + "properties": { + "media_types": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Media kinds to extract from indexed content and embed as multi-modal KB chunks. Subset of ['images', 'video']. Only kinds the source's embedder can index are honored (see `supported_input_media` on GET /models/embedders); unsupported values are dropped. [] disables media extraction (text-only).", + "title": "Media Types" }, - "source_connection_id": { + "name": { "anyOf": [ { + "maxLength": 255, + "minLength": 1, "type": "string" }, { "type": "null" } ], - "title": "Source Connection Id" + "description": "New name.", + "title": "Name" }, - "source_connection_pull_id": { + "polling": { "anyOf": [ { "type": "string" @@ -8964,57 +9071,33 @@ "type": "null" } ], - "title": "Source Connection Pull Id" - }, - "status": { - "title": "Status", - "type": "string" - }, - "subscriber_count": { - "title": "Subscriber Count", - "type": "integer" - }, - "title": { - "title": "Title", - "type": "string" + "description": "New polling interval.", + "title": "Polling" }, - "updated_at": { + "retention_days": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "Updated At" + "description": "New retention period in days \u2014 content older than this is deleted permanently. Send null to clear the window: content is then kept indefinitely. Omit the field to leave it unchanged.", + "title": "Retention Days" } }, - "required": [ - "id", - "account_id", - "alert_config_id", - "alert_type", - "title", - "description", - "status", - "agent_id", - "agent_run_id", - "source_connection_id", - "source_connection_pull_id", - "mcp_client_id", - "subscriber_count", - "comment_count", - "is_subscribed", - "created_at", - "updated_at" - ], - "title": "AlertResponse", + "title": "UpdateSourceBody", "type": "object" }, - "routers__api__alerts__AlertSubscriberResponse": { + "UploadAgentInputApiResponse": { "properties": { - "created_at": { + "content_type": { + "description": "Resolved MIME type.", + "title": "Content Type", + "type": "string" + }, + "error": { "anyOf": [ { "type": "string" @@ -9023,314 +9106,280 @@ "type": "null" } ], - "title": "Created At" + "description": "Error message if status is failed.", + "title": "Error" + }, + "file_size": { + "description": "Size in bytes.", + "title": "File Size", + "type": "integer" + }, + "filename": { + "description": "Original filename.", + "title": "Filename", + "type": "string" }, "id": { + "description": "Unique identifier for the upload.", "title": "Id", "type": "string" }, - "user_id": { - "title": "User Id", + "status": { + "description": "processing, ready, or failed.", + "title": "Status", "type": "string" - }, - "user_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "User Name" } }, "required": [ "id", - "user_id", - "user_name", - "created_at" + "status", + "filename", + "content_type", + "file_size" ], - "title": "AlertSubscriberResponse", + "title": "UploadAgentInputApiResponse", "type": "object" }, - "routers__api__alerts__OrganizationAlertPreferenceResponse": { + "ValidationError": { "properties": { - "alert_type": { - "title": "Alert Type", + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "title": "Location", + "type": "array" + }, + "msg": { + "title": "Message", "type": "string" }, - "is_override": { - "title": "Is Override", - "type": "boolean" - }, - "organization_id": { - "title": "Organization Id", + "type": { + "title": "Error Type", "type": "string" - }, - "subscribed": { - "title": "Subscribed", - "type": "boolean" } }, "required": [ - "organization_id", - "alert_type", - "subscribed", - "is_override" + "loc", + "msg", + "type" ], - "title": "OrganizationAlertPreferenceResponse", + "title": "ValidationError", "type": "object" }, - "routers__api__alerts__UpdateOrganizationAlertPreferenceRequest": { + "VariantCategoryResponse": { + "description": "Response model for a variant category", "properties": { - "subscribed": { - "description": "Whether the user should receive this alert for the organization", - "title": "Subscribed", + "category": { + "title": "Category", + "type": "string" + }, + "configurable": { + "title": "Configurable", "type": "boolean" + }, + "description": { + "title": "Description", + "type": "string" + }, + "options": { + "items": { + "$ref": "#/components/schemas/VariantOptionResponse" + }, + "title": "Options", + "type": "array" + }, + "title": { + "title": "Title", + "type": "string" } }, "required": [ - "subscribed" + "category", + "title", + "description", + "configurable", + "options" ], - "title": "UpdateOrganizationAlertPreferenceRequest", + "title": "VariantCategoryResponse", "type": "object" }, - "routers__api__contents__ContentDetailResponse": { - "description": "Response model for content detail.", + "VariantOptionResponse": { + "description": "Response model for a variant option", "properties": { - "content_duration": { + "default": { + "title": "Default", + "type": "boolean" + }, + "description": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Duration of the content in seconds.", - "title": "Content Duration" + "title": "Description" }, - "content_duration_display": { + "input_1h_cache_write_credits_per_1000_tokens": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "description": "Display string for content duration.", - "title": "Content Duration Display" - }, - "content_status": { - "description": "Status of the content.", - "title": "Content Status", - "type": "string" - }, - "content_type": { - "description": "Type of the content.", - "title": "Content Type", - "type": "string" - }, - "content_type_display": { - "description": "Display name of the content type.", - "title": "Content Type Display", - "type": "string" - }, - "content_url": { - "description": "URL of the content.", - "title": "Content Url", - "type": "string" + "description": "Credits per 1,000 input tokens written to a 1-hour prompt cache.", + "title": "Input 1H Cache Write Credits Per 1000 Tokens" }, - "content_word_count": { + "input_30m_cache_write_credits_per_1000_tokens": { "anyOf": [ { - "type": "integer" + "type": "number" }, { "type": "null" } ], - "description": "Word count of the content.", - "title": "Content Word Count" + "description": "Credits per 1,000 input tokens written to a 30-minute prompt cache.", + "title": "Input 30M Cache Write Credits Per 1000 Tokens" }, - "description": { + "input_5m_cache_write_credits_per_1000_tokens": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "description": "Description of the content.", - "title": "Description" + "description": "Credits per 1,000 input tokens written to a 5-minute prompt cache.", + "title": "Input 5M Cache Write Credits Per 1000 Tokens" }, - "error": { + "input_cache_hit_credits_per_1000_tokens": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "description": "Error message, if any.", - "title": "Error" - }, - "id": { - "description": "Unique identifier for the content version.", - "title": "Id", - "type": "string" + "description": "Credits per 1,000 input tokens read from a prompt cache.", + "title": "Input Cache Hit Credits Per 1000 Tokens" }, - "metadata": { + "input_credits_per_1000_tokens": { "anyOf": [ { - "items": { - "additionalProperties": { - "type": "string" - }, - "type": "object" - }, - "type": "array" + "type": "number" }, { "type": "null" } ], - "description": "Metadata associated with the content.", - "title": "Metadata" + "title": "Input Credits Per 1000 Tokens" }, - "published_at": { + "long_context_input_cache_hit_credits_per_1000_tokens": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "description": "Timestamp when the content was published.", - "title": "Published At" - }, - "pulled_at": { - "description": "Timestamp when the content was pulled.", - "title": "Pulled At", - "type": "string" - }, - "source_connection_content_version_id": { - "description": "ID of the source connection content version.", - "title": "Source Connection Content Version Id", - "type": "string" - }, - "source_connection_id": { - "description": "ID of the source connection.", - "title": "Source Connection Id", - "type": "string" - }, - "source_name": { - "description": "Name of the source.", - "title": "Source Name", - "type": "string" - }, - "source_type": { - "description": "Type of the source.", - "title": "Source Type", - "type": "string" + "description": "Credits per 1,000 input tokens read from a prompt cache, on a call whose input exceeds `long_context_threshold` tokens.", + "title": "Long Context Input Cache Hit Credits Per 1000 Tokens" }, - "text_content": { + "long_context_input_credits_per_1000_tokens": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "description": "Text content.", - "title": "Text Content" - }, - "text_content_end": { - "description": "End position of the text content.", - "title": "Text Content End", - "type": "integer" + "title": "Long Context Input Credits Per 1000 Tokens" }, - "text_content_start": { - "description": "Start position of the text content.", - "title": "Text Content Start", - "type": "integer" + "long_context_output_credits_per_1000_tokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Long Context Output Credits Per 1000 Tokens" }, - "text_content_total_length": { - "description": "Total length of the text content.", - "title": "Text Content Total Length", - "type": "integer" + "long_context_threshold": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Long Context Threshold" }, - "title": { + "output_credits_per_1000_tokens": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "description": "Title of the content.", - "title": "Title" + "title": "Output Credits Per 1000 Tokens" + }, + "title": { + "title": "Title", + "type": "string" + }, + "value": { + "title": "Value", + "type": "string" } }, "required": [ - "id", - "source_connection_content_version_id", - "source_connection_id", - "source_name", - "source_type", + "value", "title", - "content_url", - "content_type", - "content_type_display", - "content_status", - "content_word_count", - "content_duration", - "content_duration_display", - "pulled_at", - "published_at", - "description", - "text_content", - "text_content_start", - "text_content_end", - "text_content_total_length", - "metadata", - "error" + "default" ], - "title": "ContentDetailResponse", + "title": "VariantOptionResponse", "type": "object" }, - "routers__api__contents__ContentEmbeddingsListResponse": { - "description": "Response model for paginated content embeddings.", + "routers__api__agents__AgentImportPreviewRequest": { + "description": "Dry-run import request \u2014 same payload shape as the export endpoint.", "properties": { - "data": { - "items": { - "$ref": "#/components/schemas/ContentEmbeddingResponse" - }, - "title": "Data", - "type": "array" - }, - "pagination": { - "$ref": "#/components/schemas/PaginationResponse" + "agent_definition": { + "additionalProperties": true, + "description": "Payload in the same shape as GET /agents/{agent_id}/export.", + "title": "Agent Definition", + "type": "object" } }, "required": [ - "data", - "pagination" + "agent_definition" ], - "title": "ContentEmbeddingsListResponse", + "title": "AgentImportPreviewRequest", "type": "object" }, - "routers__api__contents__FileUploadResponse": { - "description": "Response model for content file replacement upload.", + "routers__api__agents__AgentImportPreviewResponse": { + "description": "Summary of a successfully validated import payload (no DB writes).\n\nCounts are derived from the validated payload as supplied \u2014 they\nreflect what was requested, not what would eventually be persisted\n(cross-account skips for recipients and KB names happen later, only\non commit).", "properties": { - "content_version_id": { + "agent_name": { "anyOf": [ { "type": "string" @@ -9339,15 +9388,15 @@ "type": "null" } ], - "description": "ID of the content version being replaced", - "title": "Content Version Id" + "description": "Imported agent name, if any.", + "title": "Agent Name" }, - "filename": { - "description": "Original filename", - "title": "Filename", - "type": "string" + "alert_configs": { + "description": "Number of alert configs in the payload.", + "title": "Alert Configs", + "type": "integer" }, - "source_connection_content_version_id": { + "description": { "anyOf": [ { "type": "string" @@ -9356,72 +9405,143 @@ "type": "null" } ], - "description": "ID of the source connection content version", - "title": "Source Connection Content Version Id" + "description": "Imported agent description, if any.", + "title": "Description" }, - "status": { - "description": "Processing status", - "title": "Status", + "evaluation_criteria": { + "description": "Number of evaluation criteria in the payload.", + "title": "Evaluation Criteria", + "type": "integer" + }, + "governance_policies": { + "description": "Number of agent-scoped governance policies in the payload.", + "title": "Governance Policies", + "type": "integer" + }, + "ok": { + "description": "Always true on a 200 response; failures use HTTP 422.", + "title": "Ok", + "type": "boolean" + }, + "payload_export_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Export-format version the payload claims (or ``null`` for legacy payloads). When this differs from ``supported_export_version``, fields may have been silently dropped or defaulted on import.", + "title": "Payload Export Version" + }, + "schedules": { + "description": "Number of trigger schedules in the payload.", + "title": "Schedules", + "type": "integer" + }, + "solutions": { + "default": 0, + "description": "Number of solutions the source agent belonged to. On import these are matched by name in the target account; unmatched names are silently skipped.", + "title": "Solutions", + "type": "integer" + }, + "step_count": { + "description": "Total number of steps in the workflow tree (recursive).", + "title": "Step Count", + "type": "integer" + }, + "supported_export_version": { + "default": "2", + "description": "Export-format version this server understands. Compare against ``payload_export_version`` to detect cross-version imports.", + "title": "Supported Export Version", "type": "string" + }, + "unresolved_refs": { + "description": "Entity references in the imported workflow that don't exist in the target account. Each entry: {category, ref_id, ref_name?, locations:[step:], alternatives:[{id, name, description?}]}. Pass {source_uuid: target_uuid} as ``entity_remap`` on the create/update call to substitute these references before save.", + "items": { + "additionalProperties": true, + "type": "object" + }, + "title": "Unresolved Refs", + "type": "array" } }, "required": [ - "content_version_id", - "source_connection_content_version_id", - "filename", - "status" + "ok", + "agent_name", + "description", + "step_count", + "schedules", + "alert_configs", + "evaluation_criteria", + "governance_policies" ], - "title": "FileUploadResponse", + "title": "AgentImportPreviewResponse", "type": "object" }, - "routers__api__docs_search__DocsSearchResponse": { - "description": "Ranked results, NOT a paginated collection \u2014 the ``{results}`` shape is a\ndeliberate carve-out matching the MCP ``search_docs`` tool.", + "routers__api__agents__AgentListResponse": { "properties": { - "results": { + "data": { + "description": "List of agents.", "items": { - "$ref": "#/components/schemas/DocsSearchResultResponse" + "$ref": "#/components/schemas/AgentSummaryResponse" }, - "title": "Results", + "title": "Data", "type": "array" + }, + "pagination": { + "$ref": "#/components/schemas/PaginationResponse" } }, "required": [ - "results" + "data", + "pagination" ], - "title": "DocsSearchResponse", + "title": "AgentListResponse", "type": "object" }, - "routers__api__governance__GovernanceAiAssistantRequest": { - "description": "Request body for the governance AI assistant.", + "routers__api__agents__AgentRunListResponse": { "properties": { - "user_input": { - "description": "Natural-language request for the governance AI assistant.", - "title": "User Input", - "type": "string" + "data": { + "description": "List of agent runs.", + "items": { + "$ref": "#/components/schemas/AgentRunResponse" + }, + "title": "Data", + "type": "array" + }, + "pagination": { + "$ref": "#/components/schemas/PaginationResponse" } }, "required": [ - "user_input" + "data", + "pagination" ], - "title": "GovernanceAiAssistantRequest", + "title": "AgentRunListResponse", "type": "object" }, - "routers__api__governance__GovernanceConversationResponse": { - "description": "A governance AI assistant conversation entry.", + "routers__api__agents__AgentTraceSearchRequest": { "properties": { - "accepted": { + "agent_id": { "anyOf": [ { - "type": "boolean" + "type": "string" }, { "type": "null" } ], - "description": "True if accepted, false if declined, null if pending.", - "title": "Accepted" + "description": "Filter by agent ID.", + "title": "Agent Id" }, - "ai_response": { + "query": { + "description": "Search query text.", + "title": "Query", + "type": "string" + }, + "run_status": { "anyOf": [ { "type": "string" @@ -9430,68 +9550,39 @@ "type": "null" } ], - "description": "The AI assistant's response note, or null.", - "title": "Ai Response" - }, - "created_at": { - "description": "ISO 8601 creation timestamp.", - "title": "Created At", - "type": "string" - }, - "id": { - "description": "Conversation ID.", - "title": "Id", - "type": "string" + "description": "Filter by run status.", + "title": "Run Status" }, - "proposed_actions": { + "step_type": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "JSON of proposed actions, or null.", - "title": "Proposed Actions" + "description": "Filter by step type.", + "title": "Step Type" }, - "user_input": { - "description": "The original user request.", - "title": "User Input", - "type": "string" - } - }, - "required": [ - "id", - "user_input", - "ai_response", - "proposed_actions", - "accepted", - "created_at" - ], - "title": "GovernanceConversationResponse", - "type": "object" - }, - "routers__api__memory_banks__MemoryBankAcceptRequest": { - "description": "Accept or decline a memory bank AI suggestion.", - "properties": { - "accepted": { - "description": "Whether the user accepted the proposed configuration.", - "title": "Accepted", - "type": "boolean" + "top_n": { + "default": 10, + "description": "Maximum number of results.", + "maximum": 100.0, + "minimum": 1.0, + "title": "Top N", + "type": "integer" } }, "required": [ - "accepted" + "query" ], - "title": "MemoryBankAcceptRequest", + "title": "AgentTraceSearchRequest", "type": "object" }, - "routers__api__memory_banks__MemoryBankAiAssistantRequest": { - "description": "Request body for the memory bank AI assistant.", + "routers__api__agents__CreateAgentRequest": { "properties": { - "current_config": { + "agent_definition": { "anyOf": [ { "additionalProperties": true, @@ -9501,213 +9592,180 @@ "type": "null" } ], - "description": "Current configuration to refine, if any.", - "title": "Current Config" + "description": "Optional payload in the same format produced by GET /agents/{id}/export. When provided, replaces any template-derived workflow and pre-fills metadata/trigger fields the request does not specify explicitly. Validation errors include line/column references against a canonical pretty-printed echo of the supplied payload.", + "title": "Agent Definition" }, - "history_since": { + "agent_template": { "anyOf": [ { - "format": "date-time", "type": "string" }, { "type": "null" } ], - "description": "Optional ISO 8601 timestamp. When set, only conversation turns created at or after this timestamp are loaded as context, scoping history to the current session so the assistant remembers earlier turns in a multi-turn refinement.", - "title": "History Since" + "description": "Template to initialize the agent from. Values: blank, retrieval_example, simple_qa, summarizer, json_extractor, content_change_notifier, scheduled_report, webhook_pipeline.", + "title": "Agent Template" }, - "user_input": { - "description": "Natural-language description of the memory bank.", - "title": "User Input", - "type": "string" - } - }, - "required": [ - "user_input" - ], - "title": "MemoryBankAiAssistantRequest", - "type": "object" - }, - "routers__api__memory_banks__MemoryBankConversationTurnResponse": { - "description": "A single turn of memory bank AI assistant conversation.", - "properties": { - "accepted": { + "description": { "anyOf": [ { - "type": "boolean" + "type": "string" }, { "type": "null" } ], - "description": "Whether the user accepted this proposal.", - "title": "Accepted" + "description": "Optional description.", + "title": "Description" }, - "ai_note": { + "entity_remap": { "anyOf": [ { - "type": "string" + "additionalProperties": { + "type": "string" + }, + "type": "object" }, { "type": "null" } ], - "description": "AI note from this turn.", - "title": "Ai Note" + "description": "Optional UUID-substitution map applied to the imported workflow before save. Each key is a source-account UUID (as returned by /agents/preview-import's ``unresolved_refs``); each value is the target-account UUID to substitute. Used to relink knowledge bases, memory banks, source connections, and sub-agents on cross-account imports.", + "title": "Entity Remap" }, - "conversation_id": { - "description": "Unique ID for this conversation turn.", - "title": "Conversation Id", + "name": { + "description": "Name for the new agent.", + "title": "Name", "type": "string" }, - "resulting_config": { + "trigger_type": { + "default": "dynamic_input", + "description": "Trigger type: dynamic_input, template_input, schedule, new_content, email_received.", + "title": "Trigger Type", + "type": "string" + } + }, + "required": [ + "name" + ], + "title": "CreateAgentRequest", + "type": "object" + }, + "routers__api__agents__GovernancePolicyRefResponse": { + "description": "Reference to a governance policy by id and name.", + "properties": { + "policy_id": { + "description": "Governance policy identifier.", + "title": "Policy Id", + "type": "string" + }, + "policy_name": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "The proposed configuration from this turn.", - "title": "Resulting Config" - }, - "user_input": { - "description": "User input for this turn.", - "title": "User Input", - "type": "string" + "description": "Display name of the policy at evaluation time. May be null when the policy has been deleted.", + "title": "Policy Name" } }, "required": [ - "user_input", - "conversation_id" + "policy_id" ], - "title": "MemoryBankConversationTurnResponse", + "title": "GovernancePolicyRefResponse", "type": "object" }, - "routers__api__memory_banks__MemoryBankLastConversationResponse": { - "description": "Response for fetching memory bank conversation history.", + "routers__api__agents__SetEmailTriggerConfigRequest": { + "description": "Alias and/or sender allowlist for an EMAIL_RECEIVED trigger.\n\nA field omitted is left unchanged; passing ``null`` (or ``\"\"`` for\n``alias``) clears it.", "properties": { - "accepted": { + "alias": { "anyOf": [ { - "type": "boolean" + "maxLength": 32, + "type": "string" }, { "type": "null" } ], - "description": "Whether the user accepted the last proposal.", - "title": "Accepted" + "description": "Custom alias, unique per account, answering as `.@agent.seclai.com` and as `@` on each verified account email domain (alphanumeric plus '+', '.', '-'; 1\u201332 chars; not starting/ending with '+', '.', '-'; not UUID-shaped). Pass null/empty to clear.", + "title": "Alias" }, - "ai_note": { + "allowed_senders": { "anyOf": [ { - "type": "string" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "description": "AI note from the most recent turn.", - "title": "Ai Note" - }, - "total": { - "default": 0, - "description": "Total conversation turns.", - "title": "Total", - "type": "integer" + "description": "Allowlist of full sender addresses and/or bare domains (a bare domain also matches sub-domains). Empty/null accepts any sender.", + "title": "Allowed Senders" }, - "turns": { - "description": "Recent conversation turns (oldest first).", - "items": { - "$ref": "#/components/schemas/routers__api__memory_banks__MemoryBankConversationTurnResponse" - }, - "title": "Turns", - "type": "array" + "ignore_auto_generated": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "When true (default for new triggers), machine-generated inbound mail (auto-replies, bulk/list mail, bounces) is dropped before a run to prevent auto-reply loops. Set false to process automated mail.", + "title": "Ignore Auto Generated" }, - "user_input": { + "queue_on_quota": { "anyOf": [ { - "type": "string" + "type": "boolean" }, { "type": "null" } ], - "description": "Most recent user input.", - "title": "User Input" - } - }, - "title": "MemoryBankLastConversationResponse", - "type": "object" - }, - "routers__api__model_lifecycle__ModelAlertListResponse": { - "description": "``GET /models/alerts`` legacy/default shape; 2026-07-27+ clients get the\ncanonical ``{data, pagination}`` envelope (bypasses this ``response_model``).", - "properties": { - "alerts": { - "items": { - "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelAlertResponse" - }, - "title": "Alerts", - "type": "array" + "description": "When true (default false), inbound mail that exceeds the account's hourly email-trigger rate is parked in a QUEUED run and drained later by the catch-up sweep instead of being failed; when false, over-rate mail fails immediately.", + "title": "Queue On Quota" }, - "total": { - "title": "Total", - "type": "integer" + "require_sender_auth": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "When true (default for new triggers), the envelope sender must pass SPF or DMARC even on an open inbox (no allowlist); unauthenticated, spoofable mail is rejected. Set false to accept fully unauthenticated mail on an open inbox.", + "title": "Require Sender Auth" } }, - "required": [ - "alerts", - "total" - ], - "title": "ModelAlertListResponse", + "title": "SetEmailTriggerConfigRequest", "type": "object" }, - "routers__api__model_lifecycle__ModelAlertResponse": { + "routers__api__agents__UpdateAgentRequest": { "properties": { - "account_id": { - "title": "Account Id", - "type": "string" - }, - "agent_id": { + "agent_definition": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Agent Id" - }, - "alert_type": { - "title": "Alert Type", - "type": "string" - }, - "created_at": { - "title": "Created At", - "type": "string" - }, - "id": { - "title": "Id", - "type": "string" - }, - "message": { - "title": "Message", - "type": "string" - }, - "model_name": { - "title": "Model Name", - "type": "string" - }, - "prompt_model_id": { - "title": "Prompt Model Id", - "type": "string" + "description": "Optional payload in the same format produced by GET /agents/{id}/export. When provided, agent metadata fields the request does not set explicitly are taken from the payload, and the agent's workflow is replaced from `agent.definition`. The previous version is preserved in history. Validation errors include line/column references against a canonical pretty-printed echo of the supplied payload.", + "title": "Agent Definition" }, - "read_at": { + "default_evaluation_tier": { "anyOf": [ { "type": "string" @@ -9716,9 +9774,10 @@ "type": "null" } ], - "title": "Read At" + "description": "Default evaluation tier: 'fast', 'balanced', or 'thorough'.", + "title": "Default Evaluation Tier" }, - "successor_model_name": { + "description": { "anyOf": [ { "type": "string" @@ -9727,42 +9786,25 @@ "type": "null" } ], - "title": "Successor Model Name" - } - }, - "required": [ - "id", - "account_id", - "agent_id", - "prompt_model_id", - "model_name", - "alert_type", - "message", - "read_at", - "successor_model_name", - "created_at" - ], - "title": "ModelAlertResponse", - "type": "object" - }, - "routers__api__model_lifecycle__ModelRecommendationResponse": { - "properties": { - "deprecated_at": { + "description": "New description for the agent.", + "title": "Description" + }, + "entity_remap": { "anyOf": [ { - "type": "string" + "additionalProperties": { + "type": "string" + }, + "type": "object" }, { "type": "null" } ], - "title": "Deprecated At" - }, - "description": { - "title": "Description", - "type": "string" + "description": "Optional UUID-substitution map applied to the imported workflow before save (same shape as on POST /agents).", + "title": "Entity Remap" }, - "family": { + "evaluation_mode": { "anyOf": [ { "type": "string" @@ -9771,52 +9813,22 @@ "type": "null" } ], - "title": "Family" + "description": "Evaluation mode: 'output_expectation', 'eval_and_retry', or 'sample_and_flag'.", + "title": "Evaluation Mode" }, - "family_generation": { + "max_retries": { "anyOf": [ { - "type": "number" + "type": "integer" }, { "type": "null" } ], - "title": "Family Generation" - }, - "id": { - "title": "Id", - "type": "string" - }, - "max_context_tokens": { - "title": "Max Context Tokens", - "type": "integer" - }, - "max_output_tokens": { - "title": "Max Output Tokens", - "type": "integer" - }, - "model_id": { - "title": "Model Id", - "type": "string" + "description": "Max retries for eval_and_retry mode (1-10).", + "title": "Max Retries" }, "name": { - "title": "Name", - "type": "string" - }, - "provider": { - "title": "Provider", - "type": "string" - }, - "reason": { - "title": "Reason", - "type": "string" - }, - "recommendation_type": { - "title": "Recommendation Type", - "type": "string" - }, - "released_at": { "anyOf": [ { "type": "string" @@ -9825,185 +9837,111 @@ "type": "null" } ], - "title": "Released At" + "description": "New name for the agent.", + "title": "Name" }, - "sunset_at": { + "prompt_model_auto_rollback_enabled": { "anyOf": [ { - "type": "string" + "type": "boolean" }, { "type": "null" } ], - "title": "Sunset At" - }, - "supports_openai_arguments": { - "title": "Supports Openai Arguments", - "type": "boolean" - }, - "supports_streaming": { - "title": "Supports Streaming", - "type": "boolean" - }, - "supports_structured_output": { - "title": "Supports Structured Output", - "type": "boolean" - }, - "supports_thinking": { - "title": "Supports Thinking", - "type": "boolean" - }, - "supports_tool_use": { - "title": "Supports Tool Use", - "type": "boolean" - } - }, - "required": [ - "id", - "model_id", - "name", - "provider", - "description", - "max_context_tokens", - "max_output_tokens", - "supports_tool_use", - "supports_structured_output", - "supports_thinking", - "supports_openai_arguments", - "supports_streaming", - "recommendation_type", - "reason" - ], - "title": "ModelRecommendationResponse", - "type": "object" - }, - "routers__api__model_lifecycle__ModelRecommendationsResponse": { - "properties": { - "alternatives": { - "items": { - "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelRecommendationResponse" - }, - "title": "Alternatives", - "type": "array" - }, - "current_model_id": { - "title": "Current Model Id", - "type": "string" + "description": "Enable or disable automatic rollback for upgraded models.", + "title": "Prompt Model Auto Rollback Enabled" }, - "current_model_name": { - "title": "Current Model Name", - "type": "string" + "prompt_model_auto_rollback_triggers": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Failure signals that trigger rollback: agent_eval_fail, governance_flag, governance_block, agent_run_failed.", + "title": "Prompt Model Auto Rollback Triggers" }, - "same_provider": { - "items": { - "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelRecommendationResponse" - }, - "title": "Same Provider", - "type": "array" + "prompt_model_auto_upgrade_strategy": { + "anyOf": [ + { + "$ref": "#/components/schemas/PromptModelAutoUpgradeStrategy" + }, + { + "type": "null" + } + ], + "description": "Auto-upgrade strategy: none, early_adopter, middle_of_road, cautious_adopter." }, - "successor": { + "retry_on_failure": { "anyOf": [ { - "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelRecommendationResponse" + "type": "boolean" }, { "type": "null" } - ] + ], + "description": "Whether to retry on evaluation failure.", + "title": "Retry On Failure" }, - "upgrades": { - "items": { - "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelRecommendationResponse" - }, - "title": "Upgrades", - "type": "array" - } - }, - "required": [ - "current_model_id", - "current_model_name", - "upgrades", - "same_provider", - "alternatives" - ], - "title": "ModelRecommendationsResponse", - "type": "object" - }, - "routers__api__search__SearchResponse": { - "description": "Ranked results, NOT a paginated collection \u2014 the ``{results}`` shape is a\ndeliberate carve-out matching the MCP ``search_resources`` tool.", - "properties": { - "results": { - "items": { - "$ref": "#/components/schemas/routers__api__search__SearchResultResponse" - }, - "title": "Results", - "type": "array" - } - }, - "required": [ - "results" - ], - "title": "SearchResponse", - "type": "object" - }, - "routers__api__search__SearchResultResponse": { - "properties": { - "description": { + "sampling_config": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Description" + "description": "Sampling configuration for sample_and_flag mode. Format: {combinator: 'and'|'or', rules: [...]}.", + "title": "Sampling Config" }, - "entity_type": { - "title": "Entity Type", - "type": "string" + "set_default_evaluation_tier": { + "default": false, + "description": "When true and default_evaluation_tier is omitted, clears the tier to null (system default).", + "title": "Set Default Evaluation Tier", + "type": "boolean" }, - "id": { - "title": "Id", - "type": "string" + "set_prompt_model_auto_rollback_triggers": { + "default": false, + "description": "When true and prompt_model_auto_rollback_triggers is omitted, clears the list to null (revert to system defaults).", + "title": "Set Prompt Model Auto Rollback Triggers", + "type": "boolean" }, - "name": { - "title": "Name", - "type": "string" + "set_sampling_config": { + "default": false, + "description": "When true and sampling_config is omitted, clears the config to null.", + "title": "Set Sampling Config", + "type": "boolean" } }, - "required": [ - "id", - "entity_type", - "name", - "description" - ], - "title": "SearchResultResponse", + "title": "UpdateAgentRequest", "type": "object" }, - "routers__api__solutions__AiAssistantAcceptRequest": { - "description": "Request body for accepting a proposed plan.", + "routers__api__ai_assistant__AiAssistantFeedbackRequest": { + "description": "Request body for submitting AI assistant feedback.", "properties": { - "confirm_deletions": { - "default": false, - "description": "Must be true when the plan contains destructive actions", - "title": "Confirm Deletions", - "type": "boolean" - }, - "solution_description": { + "agent_conversation_id": { "anyOf": [ { + "format": "uuid", "type": "string" }, { "type": "null" } ], - "description": "When running in standalone mode (no pre-existing solution), provide a description for the auto-created solution.", - "title": "Solution Description" + "description": "Agent conversation ID, if applicable.", + "title": "Agent Conversation Id" }, - "solution_name": { + "comment": { "anyOf": [ { "type": "string" @@ -10012,171 +9950,182 @@ "type": "null" } ], - "description": "When running in standalone mode (no pre-existing solution), provide a name to auto-create a solution and link resources.", - "title": "Solution Name" - } - }, - "title": "AiAssistantAcceptRequest", - "type": "object" - }, - "routers__api__solutions__AiAssistantGenerateRequest": { - "description": "Request body for AI assistant generate endpoints.", - "properties": { - "history_since": { + "description": "Optional comment.", + "title": "Comment" + }, + "context": { "anyOf": [ { - "format": "date-time", - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Optional ISO 8601 timestamp. When set, only conversation turns created at or after this timestamp are loaded as context, scoping history to the current session so the assistant remembers earlier turns in a create flow.", - "title": "History Since" + "description": "Additional context.", + "title": "Context" }, - "user_input": { - "description": "User input describing what to do", - "title": "User Input", - "type": "string" - } - }, - "required": [ - "user_input" - ], - "title": "AiAssistantGenerateRequest", - "type": "object" - }, - "routers__api__solutions__SolutionAgentResponse": { - "properties": { - "id": { - "format": "uuid", - "title": "Id", - "type": "string" - }, - "knowledge_base_ids": { - "description": "Knowledge base IDs connected to this agent via triggers.", - "items": { - "format": "uuid", - "type": "string" - }, - "title": "Knowledge Base Ids", - "type": "array" - }, - "name": { - "title": "Name", - "type": "string" - } - }, - "required": [ - "id", - "name" - ], - "title": "SolutionAgentResponse", - "type": "object" - }, - "routers__api__solutions__SolutionConversationResponse": { - "description": "Response model for a conversation turn.", - "properties": { - "accepted": { + "conversation_id": { "anyOf": [ { - "type": "boolean" + "format": "uuid", + "type": "string" }, { "type": "null" } ], - "description": "Whether the suggestion was accepted or declined.", - "title": "Accepted" + "description": "Conversation ID for the interaction.", + "title": "Conversation Id" }, - "actions_taken": { + "feature": { + "description": "Feature name (e.g. 'source', 'solution').", + "title": "Feature", + "type": "string" + }, + "governance_conversation_id": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "format": "uuid", + "type": "string" }, { "type": "null" } ], - "description": "Actions taken by the AI.", - "title": "Actions Taken" + "description": "Governance conversation ID, if applicable.", + "title": "Governance Conversation Id" }, - "ai_response": { + "prompt_call_id": { "anyOf": [ { + "format": "uuid", "type": "string" }, { "type": "null" } ], - "description": "AI response text.", - "title": "Ai Response" + "description": "Prompt call ID for credit tracking.", + "title": "Prompt Call Id" }, - "created_at": { - "description": "Timestamp when the conversation was created.", - "title": "Created At", + "rating": { + "description": "Rating: 'thumbs_up' or 'thumbs_down'.", + "title": "Rating", + "type": "string" + } + }, + "required": [ + "feature", + "rating" + ], + "title": "AiAssistantFeedbackRequest", + "type": "object" + }, + "routers__api__alerts__AddCommentRequest": { + "properties": { + "body": { + "description": "Comment text", + "title": "Body", + "type": "string" + } + }, + "required": [ + "body" + ], + "title": "AddCommentRequest", + "type": "object" + }, + "routers__api__alerts__AlertCommentResponse": { + "properties": { + "body": { + "title": "Body", "type": "string" }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created At" + }, "id": { - "description": "Unique identifier for the conversation turn.", - "format": "uuid", "title": "Id", "type": "string" }, - "user_input": { - "description": "User input text.", - "title": "User Input", + "user_id": { + "title": "User Id", "type": "string" + }, + "user_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "User Name" } }, "required": [ "id", - "user_input", - "ai_response", - "actions_taken", - "accepted", + "user_id", + "user_name", + "body", "created_at" ], - "title": "SolutionConversationResponse", + "title": "AlertCommentResponse", "type": "object" }, - "routers__api__solutions__SolutionKnowledgeBaseResponse": { + "routers__api__alerts__AlertDetailResponse": { "properties": { - "id": { - "format": "uuid", - "title": "Id", - "type": "string" + "alert": { + "$ref": "#/components/schemas/routers__api__alerts__AlertResponse" }, - "name": { - "title": "Name", - "type": "string" + "comments": { + "items": { + "$ref": "#/components/schemas/routers__api__alerts__AlertCommentResponse" + }, + "title": "Comments", + "type": "array" }, - "source_connection_ids": { - "description": "Source connection IDs linked to this knowledge base.", + "history": { "items": { - "format": "uuid", - "type": "string" + "$ref": "#/components/schemas/AlertHistoryEntryResponse" }, - "title": "Source Connection Ids", + "title": "History", + "type": "array" + }, + "subscribers": { + "items": { + "$ref": "#/components/schemas/routers__api__alerts__AlertSubscriberResponse" + }, + "title": "Subscribers", "type": "array" } }, "required": [ - "id", - "name" + "alert", + "history", + "comments", + "subscribers" ], - "title": "SolutionKnowledgeBaseResponse", + "title": "AlertDetailResponse", "type": "object" }, - "routers__api__solutions__SolutionListResponse": { - "description": "Response model for paginated solution list.", + "routers__api__alerts__AlertListResponse": { + "description": "``GET /alerts`` \u2014 always the canonical ``{data, pagination}`` envelope.", "properties": { "data": { "items": { - "$ref": "#/components/schemas/SolutionSummaryResponse" + "$ref": "#/components/schemas/routers__api__alerts__AlertResponse" }, "title": "Data", "type": "array" @@ -10189,123 +10138,57 @@ "data", "pagination" ], - "title": "SolutionListResponse", + "title": "AlertListResponse", "type": "object" }, - "routers__api__solutions__SolutionResponse": { - "description": "Response model for solution data.", + "routers__api__alerts__AlertResponse": { "properties": { - "agents": { - "description": "Agents linked to the solution.", - "items": { - "$ref": "#/components/schemas/routers__api__solutions__SolutionAgentResponse" - }, - "title": "Agents", - "type": "array" - }, - "created_at": { - "description": "Timestamp when the solution was created.", - "title": "Created At", - "type": "string" - }, - "description": { - "description": "Description of the solution.", - "title": "Description", - "type": "string" - }, - "id": { - "description": "Unique identifier for the solution.", - "format": "uuid", - "title": "Id", - "type": "string" - }, - "knowledge_bases": { - "description": "Knowledge bases linked to the solution.", - "items": { - "$ref": "#/components/schemas/routers__api__solutions__SolutionKnowledgeBaseResponse" - }, - "title": "Knowledge Bases", - "type": "array" - }, - "name": { - "description": "Name of the solution.", - "title": "Name", + "account_id": { + "title": "Account Id", "type": "string" }, - "source_connections": { - "description": "Source connections linked to the solution.", - "items": { - "$ref": "#/components/schemas/SolutionSourceConnectionResponse" - }, - "title": "Source Connections", - "type": "array" - }, - "updated_at": { - "description": "Timestamp when the solution was last updated.", - "title": "Updated At", - "type": "string" - } - }, - "required": [ - "id", - "name", - "description", - "agents", - "knowledge_bases", - "source_connections", - "created_at", - "updated_at" - ], - "title": "SolutionResponse", - "type": "object" - }, - "routers__api__source_exports__CreateExportRequest": { - "description": "Parameters for creating a new export job.", - "properties": { - "date_from": { + "agent_id": { "anyOf": [ { - "format": "date-time", "type": "string" }, { "type": "null" } ], - "description": "Only include content created on or after this timestamp.", - "title": "Date From" + "title": "Agent Id" }, - "date_to": { + "agent_run_id": { "anyOf": [ { - "format": "date-time", "type": "string" }, { "type": "null" } ], - "description": "Only include content created on or before this timestamp.", - "title": "Date To" - }, - "format": { - "$ref": "#/components/schemas/ExportFormat", - "description": "Output file format (jsonl, csv, parquet, zip)." + "title": "Agent Run Id" }, - "metadata_filter": { + "alert_config_id": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "JSONB containment filter applied to content metadata.", - "title": "Metadata Filter" + "title": "Alert Config Id" }, - "query_filter": { + "alert_type": { + "title": "Alert Type", + "type": "string" + }, + "comment_count": { + "title": "Comment Count", + "type": "integer" + }, + "created_at": { "anyOf": [ { "type": "string" @@ -10314,63 +10197,53 @@ "type": "null" } ], - "description": "Title substring filter (case-insensitive ILIKE).", - "title": "Query Filter" - } - }, - "required": [ - "format" - ], - "title": "CreateExportRequest", - "type": "object" - }, - "routers__api__source_exports__EstimateExportRequest": { - "description": "Parameters for estimating export size.", - "properties": { - "date_from": { + "title": "Created At" + }, + "description": { "anyOf": [ { - "format": "date-time", "type": "string" }, { "type": "null" } ], - "description": "Only include content created on or after this timestamp.", - "title": "Date From" + "title": "Description" }, - "date_to": { + "details": { + "title": "Details" + }, + "id": { + "title": "Id", + "type": "string" + }, + "is_subscribed": { + "title": "Is Subscribed", + "type": "boolean" + }, + "mcp_client_id": { "anyOf": [ { - "format": "date-time", "type": "string" }, { "type": "null" } ], - "description": "Only include content created on or before this timestamp.", - "title": "Date To" - }, - "format": { - "$ref": "#/components/schemas/ExportFormat", - "description": "Output file format." + "title": "Mcp Client Id" }, - "metadata_filter": { + "source_connection_id": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "JSONB containment filter applied to content metadata.", - "title": "Metadata Filter" + "title": "Source Connection Id" }, - "query_filter": { + "source_connection_pull_id": { "anyOf": [ { "type": "string" @@ -10379,63 +10252,21 @@ "type": "null" } ], - "description": "Title substring filter (case-insensitive ILIKE).", - "title": "Query Filter" - } - }, - "required": [ - "format" - ], - "title": "EstimateExportRequest", - "type": "object" - }, - "routers__api__source_exports__EstimateExportResponse": { - "description": "Rough size estimate for a potential export.", - "properties": { - "estimated_size_bytes": { - "description": "Estimated export file size in bytes.", - "title": "Estimated Size Bytes", - "type": "integer" + "title": "Source Connection Pull Id" }, - "source_connection_id": { - "description": "Source connection ID.", - "title": "Source Connection Id", - "type": "string" - } - }, - "required": [ - "estimated_size_bytes", - "source_connection_id" - ], - "title": "EstimateExportResponse", - "type": "object" - }, - "routers__api__source_exports__ExportResponse": { - "description": "Status and metadata for a content source export job.", - "properties": { - "account_id": { - "description": "Owning account ID.", - "title": "Account Id", + "status": { + "title": "Status", "type": "string" }, - "completed_at": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Completion time.", - "title": "Completed At" + "subscriber_count": { + "title": "Subscriber Count", + "type": "integer" }, - "created_at": { - "description": "Creation time.", - "title": "Created At", + "title": { + "title": "Title", "type": "string" }, - "date_from": { + "updated_at": { "anyOf": [ { "type": "string" @@ -10444,10 +10275,34 @@ "type": "null" } ], - "description": "Date-from filter applied to this export.", - "title": "Date From" - }, - "date_to": { + "title": "Updated At" + } + }, + "required": [ + "id", + "account_id", + "alert_config_id", + "alert_type", + "title", + "description", + "status", + "agent_id", + "agent_run_id", + "source_connection_id", + "source_connection_pull_id", + "mcp_client_id", + "subscriber_count", + "comment_count", + "is_subscribed", + "created_at", + "updated_at" + ], + "title": "AlertResponse", + "type": "object" + }, + "routers__api__alerts__AlertSubscriberResponse": { + "properties": { + "created_at": { "anyOf": [ { "type": "string" @@ -10456,15 +10311,17 @@ "type": "null" } ], - "description": "Date-to filter applied to this export.", - "title": "Date To" + "title": "Created At" }, - "destination": { - "description": "Storage destination.", - "title": "Destination", + "id": { + "title": "Id", "type": "string" }, - "error": { + "user_id": { + "title": "User Id", + "type": "string" + }, + "user_name": { "anyOf": [ { "type": "string" @@ -10473,10 +10330,64 @@ "type": "null" } ], - "description": "Error message if failed.", - "title": "Error" + "title": "User Name" + } + }, + "required": [ + "id", + "user_id", + "user_name", + "created_at" + ], + "title": "AlertSubscriberResponse", + "type": "object" + }, + "routers__api__alerts__OrganizationAlertPreferenceResponse": { + "properties": { + "alert_type": { + "title": "Alert Type", + "type": "string" }, - "estimated_size_bytes": { + "is_override": { + "title": "Is Override", + "type": "boolean" + }, + "organization_id": { + "title": "Organization Id", + "type": "string" + }, + "subscribed": { + "title": "Subscribed", + "type": "boolean" + } + }, + "required": [ + "organization_id", + "alert_type", + "subscribed", + "is_override" + ], + "title": "OrganizationAlertPreferenceResponse", + "type": "object" + }, + "routers__api__alerts__UpdateOrganizationAlertPreferenceRequest": { + "properties": { + "subscribed": { + "description": "Whether the user should receive this alert for the organization", + "title": "Subscribed", + "type": "boolean" + } + }, + "required": [ + "subscribed" + ], + "title": "UpdateOrganizationAlertPreferenceRequest", + "type": "object" + }, + "routers__api__contents__ContentDetailResponse": { + "description": "Response model for content detail.", + "properties": { + "content_duration": { "anyOf": [ { "type": "integer" @@ -10485,10 +10396,10 @@ "type": "null" } ], - "description": "Pre-run size estimate.", - "title": "Estimated Size Bytes" + "description": "Duration of the content in seconds.", + "title": "Content Duration" }, - "expires_at": { + "content_duration_display": { "anyOf": [ { "type": "string" @@ -10497,32 +10408,30 @@ "type": "null" } ], - "description": "Download expiry time.", - "title": "Expires At" - }, - "file_size_bytes": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "File size in bytes.", - "title": "File Size Bytes" + "description": "Display string for content duration.", + "title": "Content Duration Display" }, - "format": { - "description": "Output format.", - "title": "Format", + "content_status": { + "description": "Status of the content.", + "title": "Content Status", "type": "string" }, - "id": { - "description": "Export job ID.", - "title": "Id", + "content_type": { + "description": "Type of the content.", + "title": "Content Type", "type": "string" }, - "item_count": { + "content_type_display": { + "description": "Display name of the content type.", + "title": "Content Type Display", + "type": "string" + }, + "content_url": { + "description": "URL of the content.", + "title": "Content Url", + "type": "string" + }, + "content_word_count": { "anyOf": [ { "type": "integer" @@ -10531,35 +10440,40 @@ "type": "null" } ], - "description": "Items exported.", - "title": "Item Count" + "description": "Word count of the content.", + "title": "Content Word Count" }, - "metadata_filter": { + "description": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "Metadata filter applied to this export.", - "title": "Metadata Filter" + "description": "Description of the content.", + "title": "Description" }, - "progress_current": { + "error": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "description": "Items processed so far.", - "title": "Progress Current" + "description": "Error message, if any.", + "title": "Error" }, - "progress_total": { + "extracted_media_capped": { + "default": false, + "description": "True when extraction stopped with media still unread, so the item references more media than was indexed and media search will not match anything past the cut. Two causes: a web page that ran out of the budget for fetching remote assets, or a container that could not be read to the end (a truncated or hostile archive). An uploaded document that reads cleanly is never capped, however much media it holds \u2014 there is no limit on that.", + "title": "Extracted Media Capped", + "type": "boolean" + }, + "extracted_media_count": { "anyOf": [ { "type": "integer" @@ -10568,34 +10482,45 @@ "type": "null" } ], - "description": "Total items to process.", - "title": "Progress Total" + "description": "Number of embedded images / videos extracted from inside this item and indexed as their own chunks. There is no limit on this \u2014 a document contributes as many as it holds. Null when there is no media record for the item: the extraction pass has not run, does not apply to this container, or found nothing. Treat null as 'unknown', never as zero.", + "title": "Extracted Media Count" }, - "query_filter": { + "extracted_media_limit": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "description": "Query filter applied to this export.", - "title": "Query Filter" + "description": "The bound that was reached, when extracted_media_capped is true and the stop was a bound \u2014 a number of fetch attempts, or a number of seconds. Null when extraction was not capped, or when it stopped because the container could not be read rather than because a bound fired.", + "title": "Extracted Media Limit" }, - "requested_by_user_id": { + "id": { + "description": "Unique identifier for the content version.", + "title": "Id", + "type": "string" + }, + "metadata": { "anyOf": [ { - "type": "string" + "items": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "type": "array" }, { "type": "null" } ], - "description": "ID of the user who requested this export.", - "title": "Requested By User Id" + "description": "Metadata associated with the content.", + "title": "Metadata" }, - "requested_by_user_name": { + "published_at": { "anyOf": [ { "type": "string" @@ -10604,15 +10529,35 @@ "type": "null" } ], - "description": "Name of the user who requested this export.", - "title": "Requested By User Name" + "description": "Timestamp when the content was published.", + "title": "Published At" + }, + "pulled_at": { + "description": "Timestamp when the content was pulled.", + "title": "Pulled At", + "type": "string" + }, + "source_connection_content_version_id": { + "description": "ID of the source connection content version.", + "title": "Source Connection Content Version Id", + "type": "string" }, "source_connection_id": { - "description": "Source connection ID.", + "description": "ID of the source connection.", "title": "Source Connection Id", "type": "string" }, - "started_at": { + "source_name": { + "description": "Name of the source.", + "title": "Source Name", + "type": "string" + }, + "source_type": { + "description": "Type of the source.", + "title": "Source Type", + "type": "string" + }, + "text_content": { "anyOf": [ { "type": "string" @@ -10621,15 +10566,25 @@ "type": "null" } ], - "description": "Processing start time.", - "title": "Started At" + "description": "Text content.", + "title": "Text Content" }, - "status": { - "description": "Job status.", - "title": "Status", - "type": "string" + "text_content_end": { + "description": "End position of the text content.", + "title": "Text Content End", + "type": "integer" }, - "storage_key": { + "text_content_start": { + "description": "Start position of the text content.", + "title": "Text Content Start", + "type": "integer" + }, + "text_content_total_length": { + "description": "Total length of the text content.", + "title": "Text Content Total Length", + "type": "integer" + }, + "title": { "anyOf": [ { "type": "string" @@ -10638,30 +10593,60 @@ "type": "null" } ], - "description": "S3 key of exported file.", - "title": "Storage Key" - }, - "updated_at": { - "description": "Last update time.", - "title": "Updated At", - "type": "string" + "description": "Title of the content.", + "title": "Title" } }, "required": [ "id", + "source_connection_content_version_id", "source_connection_id", - "account_id", - "format", - "destination", - "status", - "created_at", - "updated_at" + "source_name", + "source_type", + "title", + "content_url", + "content_type", + "content_type_display", + "content_status", + "content_word_count", + "content_duration", + "content_duration_display", + "pulled_at", + "published_at", + "description", + "text_content", + "text_content_start", + "text_content_end", + "text_content_total_length", + "metadata", + "error" ], - "title": "ExportResponse", + "title": "ContentDetailResponse", "type": "object" }, - "routers__api__sources__FileUploadResponse": { - "description": "Response model for file upload", + "routers__api__contents__ContentEmbeddingsListResponse": { + "description": "Response model for paginated content embeddings.", + "properties": { + "data": { + "items": { + "$ref": "#/components/schemas/ContentEmbeddingResponse" + }, + "title": "Data", + "type": "array" + }, + "pagination": { + "$ref": "#/components/schemas/PaginationResponse" + } + }, + "required": [ + "data", + "pagination" + ], + "title": "ContentEmbeddingsListResponse", + "type": "object" + }, + "routers__api__contents__FileUploadResponse": { + "description": "Response model for content file replacement upload.", "properties": { "content_version_id": { "anyOf": [ @@ -10672,7 +10657,7 @@ "type": "null" } ], - "description": "ID of the created content version", + "description": "ID of the newly created content version. A replacement creates a new version rather than overwriting the previous one.", "title": "Content Version Id" }, "embedder_warning": { @@ -10684,7 +10669,7 @@ "type": "null" } ], - "description": "Set when the file is non-text but the source's embedder is text-only \u2014 indexing will rely on OCR / transcription and may produce a FAILED row if no text can be extracted.", + "description": "Set when the file's type is not embedded directly on this source, so indexing relies on extracted text. Content with none (e.g. a photograph) will be marked FAILED.", "title": "Embedder Warning" }, "filename": { @@ -10701,11 +10686,11 @@ "type": "null" } ], - "description": "ID of the duplicate source connection content version", + "description": "ID of the source connection content version. Unchanged by a replacement, so it stays a stable handle for the content.", "title": "Source Connection Content Version Id" }, "status": { - "description": "Processing status", + "description": "Always `uploaded`. Unlike the create endpoints, a replacement is never rejected as a duplicate of another item.", "title": "Status", "type": "string" } @@ -10719,102 +10704,177 @@ "title": "FileUploadResponse", "type": "object" }, - "routers__api__sources__SourceListResponse": { - "description": "Response model for paginated source list", + "routers__api__docs_search__DocsSearchResponse": { + "description": "Ranked results, NOT a paginated collection \u2014 the ``{results}`` shape is a\ndeliberate carve-out matching the MCP ``search_docs`` tool.", "properties": { - "data": { + "results": { "items": { - "$ref": "#/components/schemas/SourceResponse" + "$ref": "#/components/schemas/DocsSearchResultResponse" }, - "title": "Data", + "title": "Results", "type": "array" - }, - "pagination": { - "$ref": "#/components/schemas/PaginationResponse" } }, "required": [ - "data", - "pagination" + "results" ], - "title": "SourceListResponse", + "title": "DocsSearchResponse", "type": "object" }, - "schemas__model_responses__PromptModelResponse": { - "description": "Response model for prompt model data", + "routers__api__governance__GovernanceAiAssistantRequest": { + "description": "Request body for the governance AI assistant.", "properties": { - "default": { - "title": "Default", - "type": "boolean" - }, - "deprecated_at": { + "user_input": { + "description": "Natural-language request for the governance AI assistant.", + "title": "User Input", + "type": "string" + } + }, + "required": [ + "user_input" + ], + "title": "GovernanceAiAssistantRequest", + "type": "object" + }, + "routers__api__governance__GovernanceConversationResponse": { + "description": "A governance AI assistant conversation entry.", + "properties": { + "accepted": { "anyOf": [ { - "format": "date-time", - "type": "string" + "type": "boolean" }, { "type": "null" } ], - "title": "Deprecated At" + "description": "True if accepted, false if declined, null if pending.", + "title": "Accepted" }, - "description": { - "title": "Description", + "ai_response": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "The AI assistant's response note, or null.", + "title": "Ai Response" + }, + "created_at": { + "description": "ISO 8601 creation timestamp.", + "title": "Created At", "type": "string" }, - "enabled": { - "title": "Enabled", - "type": "boolean" + "id": { + "description": "Conversation ID.", + "title": "Id", + "type": "string" }, - "family": { + "proposed_actions": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Family" + "description": "JSON of proposed actions, or null.", + "title": "Proposed Actions" }, - "family_generation": { + "user_input": { + "description": "The original user request.", + "title": "User Input", + "type": "string" + } + }, + "required": [ + "id", + "user_input", + "ai_response", + "proposed_actions", + "accepted", + "created_at" + ], + "title": "GovernanceConversationResponse", + "type": "object" + }, + "routers__api__memory_banks__MemoryBankAcceptRequest": { + "description": "Accept or decline a memory bank AI suggestion.", + "properties": { + "accepted": { + "description": "Whether the user accepted the proposed configuration.", + "title": "Accepted", + "type": "boolean" + } + }, + "required": [ + "accepted" + ], + "title": "MemoryBankAcceptRequest", + "type": "object" + }, + "routers__api__memory_banks__MemoryBankAiAssistantRequest": { + "description": "Request body for the memory bank AI assistant.", + "properties": { + "current_config": { "anyOf": [ { - "type": "number" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Family Generation" + "description": "Current configuration to refine, if any.", + "title": "Current Config" }, - "generation_credits_per_unit": { + "history_since": { "anyOf": [ { - "type": "number" + "format": "date-time", + "type": "string" }, { "type": "null" } ], - "description": "Per-unit credit cost for a dedicated media-generation model, in the unit named by ``generation_params.pricing_unit`` (per image / per second / per character / per output token). Multiply by the produced unit count (images, seconds, characters) for the run cost. None for token-billed (non-generation) models.", - "title": "Generation Credits Per Unit" + "description": "Optional ISO 8601 timestamp. When set, only conversation turns created at or after this timestamp are loaded as context, scoping history to the current session so the assistant remembers earlier turns in a multi-turn refinement.", + "title": "History Since" }, - "generation_params": { + "user_input": { + "description": "Natural-language description of the memory bank.", + "title": "User Input", + "type": "string" + } + }, + "required": [ + "user_input" + ], + "title": "MemoryBankAiAssistantRequest", + "type": "object" + }, + "routers__api__memory_banks__MemoryBankConversationTurnResponse": { + "description": "A single turn of memory bank AI assistant conversation.", + "properties": { + "accepted": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "boolean" }, { "type": "null" } ], - "description": "Media-generation descriptor (modality, pricing_unit, and modality-specific constraints). NULL for text LLMs; present for image/audio/video generation models. See schemas.generation_params.", - "title": "Generation Params" + "description": "Whether the user accepted this proposal.", + "title": "Accepted" }, - "generation_unit_label": { + "ai_note": { "anyOf": [ { "type": "string" @@ -10823,124 +10883,201 @@ "type": "null" } ], - "description": "Human suffix for the per-unit generation rate (e.g. ``/image``, ``/second``, ``/1k chars``, ``/1k tokens``) \u2014 single-sourced from the pricing unit so clients render cost without re-deriving the mapping. None for non-generation models. Char/token rates are shown per 1,000 (the ``/1k \u2026`` suffix), so scale ``generation_credits_per_unit`` accordingly for those units.", - "title": "Generation Unit Label" + "description": "AI note from this turn.", + "title": "Ai Note" }, - "id": { - "title": "Id", + "conversation_id": { + "description": "Unique ID for this conversation turn.", + "title": "Conversation Id", "type": "string" }, - "image_generation_tool_credits_per_image": { + "resulting_config": { "anyOf": [ { - "type": "number" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Per-image credit cost of using the built-in image_generation tool (it runs gpt-image-1). Set only for models that actually support the tool (tool-use capable); None otherwise.", - "title": "Image Generation Tool Credits Per Image" + "description": "The proposed configuration from this turn.", + "title": "Resulting Config" }, - "input_1h_cache_write_credits_per_1000_tokens": { + "user_input": { + "description": "User input for this turn.", + "title": "User Input", + "type": "string" + } + }, + "required": [ + "user_input", + "conversation_id" + ], + "title": "MemoryBankConversationTurnResponse", + "type": "object" + }, + "routers__api__memory_banks__MemoryBankLastConversationResponse": { + "description": "Response for fetching memory bank conversation history.", + "properties": { + "accepted": { "anyOf": [ { - "type": "number" + "type": "boolean" }, { "type": "null" } ], - "title": "Input 1H Cache Write Credits Per 1000 Tokens" + "description": "Whether the user accepted the last proposal.", + "title": "Accepted" }, - "input_5m_cache_write_credits_per_1000_tokens": { + "ai_note": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Input 5M Cache Write Credits Per 1000 Tokens" + "description": "AI note from the most recent turn.", + "title": "Ai Note" }, - "input_cache_hit_credits_per_1000_tokens": { + "total": { + "default": 0, + "description": "Total conversation turns.", + "title": "Total", + "type": "integer" + }, + "turns": { + "description": "Recent conversation turns (oldest first).", + "items": { + "$ref": "#/components/schemas/routers__api__memory_banks__MemoryBankConversationTurnResponse" + }, + "title": "Turns", + "type": "array" + }, + "user_input": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Input Cache Hit Credits Per 1000 Tokens" + "description": "Most recent user input.", + "title": "User Input" + } + }, + "title": "MemoryBankLastConversationResponse", + "type": "object" + }, + "routers__api__model_lifecycle__ModelAlertListResponse": { + "description": "``GET /models/alerts`` legacy/default shape; 2026-07-27+ clients get the\ncanonical ``{data, pagination}`` envelope (bypasses this ``response_model``).", + "properties": { + "alerts": { + "items": { + "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelAlertResponse" + }, + "title": "Alerts", + "type": "array" }, - "input_credits_per_1000_tokens": { + "total": { + "title": "Total", + "type": "integer" + } + }, + "required": [ + "alerts", + "total" + ], + "title": "ModelAlertListResponse", + "type": "object" + }, + "routers__api__model_lifecycle__ModelAlertResponse": { + "properties": { + "account_id": { + "title": "Account Id", + "type": "string" + }, + "agent_id": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Input Credits Per 1000 Tokens" - }, - "is_new": { - "default": false, - "title": "Is New", - "type": "boolean" + "title": "Agent Id" }, - "last_used": { - "default": false, - "title": "Last Used", - "type": "boolean" + "alert_type": { + "title": "Alert Type", + "type": "string" }, - "max_context_tokens": { - "title": "Max Context Tokens", - "type": "integer" + "created_at": { + "title": "Created At", + "type": "string" }, - "max_conversation_length": { - "title": "Max Conversation Length", - "type": "integer" + "id": { + "title": "Id", + "type": "string" }, - "max_output_tokens": { - "title": "Max Output Tokens", - "type": "integer" + "message": { + "title": "Message", + "type": "string" }, - "model_id": { - "title": "Model Id", + "model_name": { + "title": "Model Name", "type": "string" }, - "name": { - "title": "Name", + "prompt_model_id": { + "title": "Prompt Model Id", "type": "string" }, - "output_credits_per_1000_tokens": { + "read_at": { "anyOf": [ { - "type": "number" + "type": "string" }, { "type": "null" } ], - "title": "Output Credits Per 1000 Tokens" + "title": "Read At" }, - "payload_schema": { + "successor_model_name": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "description": "Model-specific JSON schema for advanced prompt_call json_template payloads.", - "title": "Payload Schema" - }, - "payload_schema_source_url": { + "title": "Successor Model Name" + } + }, + "required": [ + "id", + "account_id", + "agent_id", + "prompt_model_id", + "model_name", + "alert_type", + "message", + "read_at", + "successor_model_name", + "created_at" + ], + "title": "ModelAlertResponse", + "type": "object" + }, + "routers__api__model_lifecycle__ModelRecommendationResponse": { + "properties": { + "deprecated_at": { "anyOf": [ { "type": "string" @@ -10949,33 +11086,23 @@ "type": "null" } ], - "description": "Source URL used to derive payload_schema guidance for this model.", - "title": "Payload Schema Source Url" - }, - "per_modality_rates": { - "items": { - "$ref": "#/components/schemas/ModalityRateResponse" - }, - "title": "Per Modality Rates", - "type": "array" + "title": "Deprecated At" }, - "provider": { - "title": "Provider", + "description": { + "title": "Description", "type": "string" }, - "released_at": { + "effort_options": { "anyOf": [ { - "format": "date-time", - "type": "string" + "$ref": "#/components/schemas/EffortOptionsResponse" }, { "type": "null" } - ], - "title": "Released At" + ] }, - "schema_documentation_url": { + "family": { "anyOf": [ { "type": "string" @@ -10984,22 +11111,52 @@ "type": "null" } ], - "description": "Model documentation URL with request/response payload details.", - "title": "Schema Documentation Url" + "title": "Family" }, - "schema_notes": { + "family_generation": { "anyOf": [ { - "type": "string" + "type": "number" }, { "type": "null" } ], - "description": "Human-readable notes about request payload compatibility.", - "title": "Schema Notes" + "title": "Family Generation" }, - "successor_model_id": { + "id": { + "title": "Id", + "type": "string" + }, + "max_context_tokens": { + "title": "Max Context Tokens", + "type": "integer" + }, + "max_output_tokens": { + "title": "Max Output Tokens", + "type": "integer" + }, + "model_id": { + "title": "Model Id", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "provider": { + "title": "Provider", + "type": "string" + }, + "reason": { + "title": "Reason", + "type": "string" + }, + "recommendation_type": { + "title": "Recommendation Type", + "type": "string" + }, + "released_at": { "anyOf": [ { "type": "string" @@ -11008,12 +11165,11 @@ "type": "null" } ], - "title": "Successor Model Id" + "title": "Released At" }, "sunset_at": { "anyOf": [ { - "format": "date-time", "type": "string" }, { @@ -11022,302 +11178,2491 @@ ], "title": "Sunset At" }, - "supported_input_media": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "title": "Supported Input Media" - }, - "supported_languages": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "title": "Supported Languages" - }, - "supported_output_media": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "title": "Supported Output Media" - }, "supports_openai_arguments": { - "default": false, "title": "Supports Openai Arguments", "type": "boolean" }, "supports_streaming": { - "default": false, "title": "Supports Streaming", "type": "boolean" }, "supports_structured_output": { - "default": true, "title": "Supports Structured Output", "type": "boolean" }, "supports_thinking": { - "default": false, "title": "Supports Thinking", "type": "boolean" }, "supports_tool_use": { - "default": true, "title": "Supports Tool Use", "type": "boolean" - }, - "tools_disabled": { + } + }, + "required": [ + "id", + "model_id", + "name", + "provider", + "description", + "max_context_tokens", + "max_output_tokens", + "supports_tool_use", + "supports_structured_output", + "supports_thinking", + "supports_openai_arguments", + "supports_streaming", + "recommendation_type", + "reason" + ], + "title": "ModelRecommendationResponse", + "type": "object" + }, + "routers__api__model_lifecycle__ModelRecommendationsResponse": { + "properties": { + "alternatives": { "items": { - "$ref": "#/components/schemas/PromptToolResponse" + "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelRecommendationResponse" }, - "title": "Tools Disabled", + "title": "Alternatives", "type": "array" }, - "tools_enabled": { + "current_model_id": { + "title": "Current Model Id", + "type": "string" + }, + "current_model_name": { + "title": "Current Model Name", + "type": "string" + }, + "same_provider": { "items": { - "$ref": "#/components/schemas/PromptToolResponse" + "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelRecommendationResponse" }, - "title": "Tools Enabled", + "title": "Same Provider", "type": "array" }, - "training_cutoff_at": { - "anyOf": [ - { - "format": "date-time", - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Training Cutoff At" - }, - "url": { + "successor": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelRecommendationResponse" }, { "type": "null" } - ], - "title": "Url" + ] }, - "variants": { - "anyOf": [ - { - "items": { - "$ref": "#/components/schemas/VariantCategoryResponse" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "title": "Variants" + "upgrades": { + "items": { + "$ref": "#/components/schemas/routers__api__model_lifecycle__ModelRecommendationResponse" + }, + "title": "Upgrades", + "type": "array" } }, "required": [ - "id", - "model_id", - "name", - "description", - "enabled", - "default", - "provider", - "max_context_tokens", - "max_output_tokens", - "max_conversation_length" + "current_model_id", + "current_model_name", + "upgrades", + "same_provider", + "alternatives" ], - "title": "PromptModelResponse", + "title": "ModelRecommendationsResponse", "type": "object" }, - "schemas__model_responses__ProviderGroupResponse": { - "description": "Response model for provider group with models", + "routers__api__search__SearchResponse": { + "description": "Ranked results, NOT a paginated collection \u2014 the ``{results}`` shape is a\ndeliberate carve-out matching the MCP ``search_resources`` tool.", "properties": { - "models": { + "results": { "items": { - "$ref": "#/components/schemas/schemas__model_responses__PromptModelResponse" + "$ref": "#/components/schemas/routers__api__search__SearchResultResponse" }, - "title": "Models", + "title": "Results", "type": "array" - }, - "provider": { - "title": "Provider", - "type": "string" } }, "required": [ - "provider", - "models" + "results" ], - "title": "ProviderGroupResponse", + "title": "SearchResponse", "type": "object" }, - "schemas__v1__agent_evaluations__NonManualEvaluationModeStatResponse": { - "description": "Per-mode rollup for evaluation activity.", + "routers__api__search__SearchResultResponse": { "properties": { - "failed": { - "title": "Failed", - "type": "integer" + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" }, - "failure_rate": { - "title": "Failure Rate", - "type": "number" + "entity_type": { + "title": "Entity Type", + "type": "string" }, - "flagged": { - "title": "Flagged", - "type": "integer" + "id": { + "title": "Id", + "type": "string" }, - "mode": { - "title": "Mode", + "name": { + "title": "Name", "type": "string" + } + }, + "required": [ + "id", + "entity_type", + "name", + "description" + ], + "title": "SearchResultResponse", + "type": "object" + }, + "routers__api__solutions__AiAssistantAcceptRequest": { + "description": "Request body for accepting a proposed plan.", + "properties": { + "confirm_deletions": { + "default": false, + "description": "Must be true when the plan contains destructive actions", + "title": "Confirm Deletions", + "type": "boolean" }, - "pass_rate": { - "title": "Pass Rate", - "type": "number" + "solution_description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When running in standalone mode (no pre-existing solution), provide a description for the auto-created solution.", + "title": "Solution Description" }, - "passed": { - "title": "Passed", - "type": "integer" + "solution_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When running in standalone mode (no pre-existing solution), provide a name to auto-create a solution and link resources.", + "title": "Solution Name" + } + }, + "title": "AiAssistantAcceptRequest", + "type": "object" + }, + "routers__api__solutions__AiAssistantGenerateRequest": { + "description": "Request body for AI assistant generate endpoints.", + "properties": { + "history_since": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional ISO 8601 timestamp. When set, only conversation turns created at or after this timestamp are loaded as context, scoping history to the current session so the assistant remembers earlier turns in a create flow.", + "title": "History Since" }, - "total": { - "title": "Total", - "type": "integer" + "user_input": { + "description": "User input describing what to do", + "title": "User Input", + "type": "string" } }, "required": [ - "mode", - "total", - "passed", - "failed", - "flagged", - "pass_rate", - "failure_rate" + "user_input" ], - "title": "NonManualEvaluationModeStatResponse", + "title": "AiAssistantGenerateRequest", "type": "object" }, - "schemas__v1__agent_evaluations__NonManualEvaluationSummaryResponse": { - "description": "Account-level summary for evaluations.", + "routers__api__solutions__SolutionAgentResponse": { "properties": { - "by_mode": { + "id": { + "format": "uuid", + "title": "Id", + "type": "string" + }, + "knowledge_base_ids": { + "description": "Knowledge base IDs connected to this agent via triggers.", "items": { - "$ref": "#/components/schemas/schemas__v1__agent_evaluations__NonManualEvaluationModeStatResponse" + "format": "uuid", + "type": "string" }, - "title": "By Mode", + "title": "Knowledge Base Ids", "type": "array" }, - "failed": { - "title": "Failed", - "type": "integer" + "name": { + "title": "Name", + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "title": "SolutionAgentResponse", + "type": "object" + }, + "routers__api__solutions__SolutionConversationResponse": { + "description": "Response model for a conversation turn.", + "properties": { + "accepted": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Whether the suggestion was accepted or declined.", + "title": "Accepted" }, - "failure_rate": { - "title": "Failure Rate", - "type": "number" + "actions_taken": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Actions taken by the AI.", + "title": "Actions Taken" }, - "flagged": { - "title": "Flagged", - "type": "integer" + "ai_response": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "AI response text.", + "title": "Ai Response" }, - "pass_rate": { - "title": "Pass Rate", - "type": "number" + "created_at": { + "description": "Timestamp when the conversation was created.", + "title": "Created At", + "type": "string" }, - "passed": { - "title": "Passed", - "type": "integer" + "id": { + "description": "Unique identifier for the conversation turn.", + "format": "uuid", + "title": "Id", + "type": "string" + }, + "user_input": { + "description": "User input text.", + "title": "User Input", + "type": "string" + } + }, + "required": [ + "id", + "user_input", + "ai_response", + "actions_taken", + "accepted", + "created_at" + ], + "title": "SolutionConversationResponse", + "type": "object" + }, + "routers__api__solutions__SolutionKnowledgeBaseResponse": { + "properties": { + "id": { + "format": "uuid", + "title": "Id", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "source_connection_ids": { + "description": "Source connection IDs linked to this knowledge base.", + "items": { + "format": "uuid", + "type": "string" + }, + "title": "Source Connection Ids", + "type": "array" + } + }, + "required": [ + "id", + "name" + ], + "title": "SolutionKnowledgeBaseResponse", + "type": "object" + }, + "routers__api__solutions__SolutionListResponse": { + "description": "Response model for paginated solution list.", + "properties": { + "data": { + "items": { + "$ref": "#/components/schemas/SolutionSummaryResponse" + }, + "title": "Data", + "type": "array" + }, + "pagination": { + "$ref": "#/components/schemas/PaginationResponse" + } + }, + "required": [ + "data", + "pagination" + ], + "title": "SolutionListResponse", + "type": "object" + }, + "routers__api__solutions__SolutionResponse": { + "description": "Response model for solution data.", + "properties": { + "agents": { + "description": "Agents linked to the solution.", + "items": { + "$ref": "#/components/schemas/routers__api__solutions__SolutionAgentResponse" + }, + "title": "Agents", + "type": "array" + }, + "created_at": { + "description": "Timestamp when the solution was created.", + "title": "Created At", + "type": "string" + }, + "description": { + "description": "Description of the solution.", + "title": "Description", + "type": "string" + }, + "id": { + "description": "Unique identifier for the solution.", + "format": "uuid", + "title": "Id", + "type": "string" + }, + "knowledge_bases": { + "description": "Knowledge bases linked to the solution.", + "items": { + "$ref": "#/components/schemas/routers__api__solutions__SolutionKnowledgeBaseResponse" + }, + "title": "Knowledge Bases", + "type": "array" + }, + "name": { + "description": "Name of the solution.", + "title": "Name", + "type": "string" + }, + "source_connections": { + "description": "Source connections linked to the solution.", + "items": { + "$ref": "#/components/schemas/SolutionSourceConnectionResponse" + }, + "title": "Source Connections", + "type": "array" + }, + "updated_at": { + "description": "Timestamp when the solution was last updated.", + "title": "Updated At", + "type": "string" + } + }, + "required": [ + "id", + "name", + "description", + "agents", + "knowledge_bases", + "source_connections", + "created_at", + "updated_at" + ], + "title": "SolutionResponse", + "type": "object" + }, + "routers__api__source_exports__CreateExportRequest": { + "description": "Parameters for creating a new export job.", + "properties": { + "date_from": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Only include content created on or after this timestamp.", + "title": "Date From" + }, + "date_to": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Only include content created on or before this timestamp.", + "title": "Date To" + }, + "format": { + "$ref": "#/components/schemas/ExportFormat", + "description": "Output file format (jsonl, csv, parquet, zip)." + }, + "metadata_filter": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "JSONB containment filter applied to content metadata.", + "title": "Metadata Filter" + }, + "query_filter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Title substring filter (case-insensitive ILIKE).", + "title": "Query Filter" + } + }, + "required": [ + "format" + ], + "title": "CreateExportRequest", + "type": "object" + }, + "routers__api__source_exports__EstimateExportRequest": { + "description": "Parameters for estimating export size.", + "properties": { + "date_from": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Only include content created on or after this timestamp.", + "title": "Date From" + }, + "date_to": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Only include content created on or before this timestamp.", + "title": "Date To" + }, + "format": { + "$ref": "#/components/schemas/ExportFormat", + "description": "Output file format." + }, + "metadata_filter": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "JSONB containment filter applied to content metadata.", + "title": "Metadata Filter" + }, + "query_filter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Title substring filter (case-insensitive ILIKE).", + "title": "Query Filter" + } + }, + "required": [ + "format" + ], + "title": "EstimateExportRequest", + "type": "object" + }, + "routers__api__source_exports__EstimateExportResponse": { + "description": "Rough size estimate for a potential export.", + "properties": { + "estimated_size_bytes": { + "description": "Estimated export file size in bytes.", + "title": "Estimated Size Bytes", + "type": "integer" + }, + "source_connection_id": { + "description": "Source connection ID.", + "title": "Source Connection Id", + "type": "string" + } + }, + "required": [ + "estimated_size_bytes", + "source_connection_id" + ], + "title": "EstimateExportResponse", + "type": "object" + }, + "routers__api__source_exports__ExportResponse": { + "description": "Status and metadata for a content source export job.", + "properties": { + "account_id": { + "description": "Owning account ID.", + "title": "Account Id", + "type": "string" + }, + "completed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Completion time.", + "title": "Completed At" + }, + "created_at": { + "description": "Creation time.", + "title": "Created At", + "type": "string" + }, + "date_from": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Date-from filter applied to this export.", + "title": "Date From" + }, + "date_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Date-to filter applied to this export.", + "title": "Date To" + }, + "destination": { + "description": "Storage destination.", + "title": "Destination", + "type": "string" + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Error message if failed.", + "title": "Error" + }, + "estimated_size_bytes": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Pre-run size estimate.", + "title": "Estimated Size Bytes" + }, + "expires_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Download expiry time.", + "title": "Expires At" + }, + "file_size_bytes": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "File size in bytes.", + "title": "File Size Bytes" + }, + "format": { + "description": "Output format.", + "title": "Format", + "type": "string" + }, + "id": { + "description": "Export job ID.", + "title": "Id", + "type": "string" + }, + "item_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Items exported.", + "title": "Item Count" + }, + "metadata_filter": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Metadata filter applied to this export.", + "title": "Metadata Filter" + }, + "progress_current": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Items processed so far.", + "title": "Progress Current" + }, + "progress_total": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Total items to process.", + "title": "Progress Total" + }, + "query_filter": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Query filter applied to this export.", + "title": "Query Filter" + }, + "requested_by_user_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ID of the user who requested this export.", + "title": "Requested By User Id" + }, + "requested_by_user_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Name of the user who requested this export.", + "title": "Requested By User Name" + }, + "source_connection_id": { + "description": "Source connection ID.", + "title": "Source Connection Id", + "type": "string" + }, + "started_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Processing start time.", + "title": "Started At" + }, + "status": { + "description": "Job status.", + "title": "Status", + "type": "string" + }, + "storage_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "S3 key of exported file.", + "title": "Storage Key" + }, + "updated_at": { + "description": "Last update time.", + "title": "Updated At", + "type": "string" + } + }, + "required": [ + "id", + "source_connection_id", + "account_id", + "format", + "destination", + "status", + "created_at", + "updated_at" + ], + "title": "ExportResponse", + "type": "object" + }, + "routers__api__sources__FileUploadResponse": { + "description": "Response model for file upload", + "properties": { + "content_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ID of the created content version, and what the source content status endpoints take. Set when `status` is `uploaded`; `null` when `status` is `duplicate`, because no new version was created.", + "title": "Content Version Id" + }, + "embedder_warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set when the file is non-text but the source's embedder is text-only \u2014 indexing will rely on OCR / transcription and may produce a FAILED row if no text can be extracted.", + "title": "Embedder Warning" + }, + "filename": { + "description": "Original filename", + "title": "Filename", + "type": "string" + }, + "source_connection_content_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ID of the existing, already-indexed item this file duplicates, and what `GET /contents/{id}` takes. Set only when `status` is `duplicate`; `null` on a new upload, which has no such id until it finishes indexing.", + "title": "Source Connection Content Version Id" + }, + "status": { + "description": "`uploaded` for a new item, or `duplicate` when this exact file is already on the source.", + "title": "Status", + "type": "string" + } + }, + "required": [ + "content_version_id", + "source_connection_content_version_id", + "filename", + "status" + ], + "title": "FileUploadResponse", + "type": "object" + }, + "routers__api__sources__SourceListResponse": { + "description": "Response model for paginated source list", + "properties": { + "data": { + "items": { + "$ref": "#/components/schemas/SourceResponse" + }, + "title": "Data", + "type": "array" + }, + "pagination": { + "$ref": "#/components/schemas/PaginationResponse" + } + }, + "required": [ + "data", + "pagination" + ], + "title": "SourceListResponse", + "type": "object" + }, + "schemas__model_responses__PromptModelResponse": { + "description": "Response model for prompt model data", + "properties": { + "chat_capable": { + "default": true, + "description": "Whether this model can serve a chat request (`prompt_call`, `extract_data`). True for every plain text LLM, and for a dual-capability model that generates media AND holds a conversation; false for a dedicated generator (Imagen, Veo, a TTS voice), which bills per produced unit and has no chat interface. Authoritative: consumers must read this rather than inferring it from `generation_params` or `supported_output_media`, because the answer also depends on which inference interface serves the model \u2014 something no response field exposes.", + "title": "Chat Capable", + "type": "boolean" + }, + "default": { + "title": "Default", + "type": "boolean" + }, + "deprecated_at": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Deprecated At" + }, + "description": { + "title": "Description", + "type": "string" + }, + "effort_options": { + "anyOf": [ + { + "$ref": "#/components/schemas/EffortOptionsResponse" + }, + { + "type": "null" + } + ], + "description": "The reasoning-effort values a prompt_call or extract_data step may set as `effort` with this model. Null when the model takes none." + }, + "enabled": { + "title": "Enabled", + "type": "boolean" + }, + "family": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Family" + }, + "family_generation": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Family Generation" + }, + "generation_credits_per_unit": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Per-unit credit cost for a dedicated media-generation model, in the unit named by ``generation_params.pricing_unit`` (per image / per second / per character / per output token). Multiply by the produced unit count (images, seconds, characters) for the run cost. None for models with no generation descriptor. This rate applies when the model is used in a generate_image/audio/video step; a model that also serves the chat path is billed per token there instead, using the input/output token rates on this same record. When `generation_params.price_varies_by` is set the model has one rate per value of that option and this is the **highest** of them \u2014 read `generation_credits_per_variant` for the real spread rather than presenting this as the price.", + "title": "Generation Credits Per Unit" + }, + "generation_credits_per_variant": { + "anyOf": [ + { + "additionalProperties": { + "type": "number" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Per-unit credit cost keyed by the value of the option named in `generation_params.price_varies_by` (e.g. `{'720p': 1330, '1080p': 1995}`). None for a model with a single rate, where `generation_credits_per_unit` already describes it exactly.", + "title": "Generation Credits Per Variant" + }, + "generation_params": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Media-generation descriptor (modality, pricing_unit, and modality-specific constraints). NULL for text LLMs; present for image/audio/video generation models. See schemas.generation_params. A present descriptor does NOT imply the model is generation-only: some models serve both paths (they generate media AND hold a chat conversation). Read `chat_capable` to tell whether a model with a descriptor can also be used as a chat model \u2014 do not branch on this field being non-null alone, and do not re-derive the answer from `supported_output_media`.", + "title": "Generation Params" + }, + "generation_unit_label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Human suffix for the per-unit generation rate (e.g. ``/image``, ``/second``, ``/1k chars``, ``/1k tokens``) \u2014 single-sourced from the pricing unit so clients render cost without re-deriving the mapping. None for non-generation models. Char/token rates are shown per 1,000 (the ``/1k \u2026`` suffix), so scale ``generation_credits_per_unit`` accordingly for those units.", + "title": "Generation Unit Label" + }, + "id": { + "title": "Id", + "type": "string" + }, + "image_generation_tool_credits_per_image": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Per-image credit cost of using the built-in image_generation tool (it runs gpt-image-1). Set only for models that actually support the tool (tool-use capable); None otherwise.", + "title": "Image Generation Tool Credits Per Image" + }, + "input_1h_cache_write_credits_per_1000_tokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Credits per 1,000 input tokens written to a 1-hour prompt cache.", + "title": "Input 1H Cache Write Credits Per 1000 Tokens" + }, + "input_30m_cache_write_credits_per_1000_tokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Credits per 1,000 input tokens written to a 30-minute prompt cache.", + "title": "Input 30M Cache Write Credits Per 1000 Tokens" + }, + "input_5m_cache_write_credits_per_1000_tokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Credits per 1,000 input tokens written to a 5-minute prompt cache.", + "title": "Input 5M Cache Write Credits Per 1000 Tokens" + }, + "input_cache_hit_credits_per_1000_tokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Credits per 1,000 input tokens read from a prompt cache.", + "title": "Input Cache Hit Credits Per 1000 Tokens" + }, + "input_credits_per_1000_tokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Input Credits Per 1000 Tokens" + }, + "is_new": { + "default": false, + "title": "Is New", + "type": "boolean" + }, + "last_used": { + "default": false, + "title": "Last Used", + "type": "boolean" + }, + "max_context_tokens": { + "title": "Max Context Tokens", + "type": "integer" + }, + "max_conversation_length": { + "title": "Max Conversation Length", + "type": "integer" + }, + "max_output_tokens": { + "title": "Max Output Tokens", + "type": "integer" + }, + "model_id": { + "title": "Model Id", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "output_credits_per_1000_tokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Output Credits Per 1000 Tokens" + }, + "payload_schema": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Model-specific JSON schema for advanced prompt_call json_template payloads.", + "title": "Payload Schema" + }, + "payload_schema_source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Source URL used to derive payload_schema guidance for this model.", + "title": "Payload Schema Source Url" + }, + "per_modality_rates": { + "items": { + "$ref": "#/components/schemas/ModalityRateResponse" + }, + "title": "Per Modality Rates", + "type": "array" + }, + "provider": { + "title": "Provider", + "type": "string" + }, + "released_at": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Released At" + }, + "schema_documentation_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Model documentation URL with request/response payload details.", + "title": "Schema Documentation Url" + }, + "schema_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Human-readable notes about request payload compatibility.", + "title": "Schema Notes" + }, + "successor_model_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Successor Model Id" + }, + "sunset_at": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sunset At" + }, + "supported_input_media": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Supported Input Media" + }, + "supported_languages": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Supported Languages" + }, + "supported_output_media": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Supported Output Media" + }, + "supports_openai_arguments": { + "default": false, + "title": "Supports Openai Arguments", + "type": "boolean" + }, + "supports_streaming": { + "default": false, + "title": "Supports Streaming", + "type": "boolean" + }, + "supports_structured_output": { + "default": true, + "title": "Supports Structured Output", + "type": "boolean" + }, + "supports_thinking": { + "default": false, + "title": "Supports Thinking", + "type": "boolean" + }, + "supports_tool_use": { + "default": true, + "title": "Supports Tool Use", + "type": "boolean" + }, + "tools_disabled": { + "items": { + "$ref": "#/components/schemas/PromptToolResponse" + }, + "title": "Tools Disabled", + "type": "array" + }, + "tools_enabled": { + "items": { + "$ref": "#/components/schemas/PromptToolResponse" + }, + "title": "Tools Enabled", + "type": "array" + }, + "training_cutoff_at": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Training Cutoff At" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Url" + }, + "variants": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/VariantCategoryResponse" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Variants" + } + }, + "required": [ + "id", + "model_id", + "name", + "description", + "enabled", + "default", + "provider", + "max_context_tokens", + "max_output_tokens", + "max_conversation_length" + ], + "title": "PromptModelResponse", + "type": "object" + }, + "schemas__model_responses__ProviderGroupResponse": { + "description": "Response model for provider group with models", + "properties": { + "models": { + "items": { + "$ref": "#/components/schemas/schemas__model_responses__PromptModelResponse" + }, + "title": "Models", + "type": "array" + }, + "provider": { + "title": "Provider", + "type": "string" + } + }, + "required": [ + "provider", + "models" + ], + "title": "ProviderGroupResponse", + "type": "object" + }, + "schemas__v1__agent_evaluations__NonManualEvaluationModeStatResponse": { + "description": "Per-mode rollup for evaluation activity.", + "properties": { + "failed": { + "title": "Failed", + "type": "integer" + }, + "failure_rate": { + "title": "Failure Rate", + "type": "number" + }, + "flagged": { + "title": "Flagged", + "type": "integer" + }, + "mode": { + "title": "Mode", + "type": "string" + }, + "pass_rate": { + "title": "Pass Rate", + "type": "number" + }, + "passed": { + "title": "Passed", + "type": "integer" + }, + "total": { + "title": "Total", + "type": "integer" + } + }, + "required": [ + "mode", + "total", + "passed", + "failed", + "flagged", + "pass_rate", + "failure_rate" + ], + "title": "NonManualEvaluationModeStatResponse", + "type": "object" + }, + "schemas__v1__agent_evaluations__NonManualEvaluationSummaryResponse": { + "description": "Account-level summary for evaluations.", + "properties": { + "by_mode": { + "items": { + "$ref": "#/components/schemas/schemas__v1__agent_evaluations__NonManualEvaluationModeStatResponse" + }, + "title": "By Mode", + "type": "array" + }, + "failed": { + "title": "Failed", + "type": "integer" + }, + "failure_rate": { + "title": "Failure Rate", + "type": "number" + }, + "flagged": { + "title": "Flagged", + "type": "integer" + }, + "pass_rate": { + "title": "Pass Rate", + "type": "number" + }, + "passed": { + "title": "Passed", + "type": "integer" + }, + "total": { + "title": "Total", + "type": "integer" + } + }, + "required": [ + "total", + "passed", + "failed", + "flagged", + "pass_rate", + "failure_rate", + "by_mode" + ], + "title": "NonManualEvaluationSummaryResponse", + "type": "object" + } + }, + "securitySchemes": { + "ApiKeyAuth": { + "description": "API key issued from the Seclai dashboard.", + "in": "header", + "name": "X-API-Key", + "type": "apiKey" + }, + "BearerAuth": { + "bearerFormat": "JWT", + "description": "OAuth2 access token from AWS Cognito.", + "scheme": "bearer", + "type": "http" + } + } + }, + "info": { + "description": "Main API service for Seclai", + "title": "Seclai API", + "version": "local" + }, + "openapi": "3.1.0", + "paths": { + "/agents": { + "get": { + "description": "List agents for the account with pagination.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", + "operationId": "list_agents_api_agents_get", + "parameters": [ + { + "description": "Page number", + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "description": "Page number", + "minimum": 1, + "title": "Page", + "type": "integer" + } + }, + { + "description": "Items per page", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 20, + "description": "Items per page", + "maximum": 100, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__agents__AgentListResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "List agents", + "tags": [ + "agents" + ] + }, + "post": { + "description": "Create a new agent.\n\nTrigger types:\n- `dynamic_input`: triggered via API with user-provided input\n- `template_input`: triggered via API with a predefined template\n- `schedule`: triggered on a schedule\n- `new_content`: triggered when new content arrives\n- `email_received`: a virtual email inbox; runs when mail arrives at the agent's address. Configure the alias/allowlist with `PUT /agents/{agent_id}/triggers/{trigger_id}/email-config`.\n\nTemplates: `blank`, `retrieval_example`, `simple_qa`, `summarizer`, `json_extractor`, `content_change_notifier`, `scheduled_report`, `webhook_pipeline`\n\nImporting an existing agent:\n- Pass `agent_definition` with the JSON shape produced by `GET /agents/{id}/export`. The full extras suite (alert_configs, evaluation_criteria, governance_policies, schedules, solutions) is applied; items that don't resolve in this account are reported in the response's `import_warnings` array.\n- Use `POST /agents/preview-import` first to surface `unresolved_refs` (workflow refs to KBs, memory banks, source connections, sub-agents that don't exist here). Then pass `entity_remap: {source_uuid: target_uuid}` on this call to substitute them before save.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Agent is created in the caller's account.", + "operationId": "create_agent_api_agents_post", + "parameters": [ + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__agents__CreateAgentRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentSummaryResponse" + } + } + }, + "description": "Successful Response" + }, + "402": { + "description": "Plan limit exceeded \u2014 the account has reached the maximum number of agents allowed by its subscription plan." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentDefinitionImportErrorResponse" + } + } + }, + "description": "The supplied `agent_definition` payload failed validation. The body lists each error with a 1-indexed line/column pointing into the canonical pretty-printed echo of the payload (also returned in `source`)." + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Create an agent", + "tags": [ + "agents" + ] + } + }, + "/agents/agent-email-optouts": { + "get": { + "description": "List recipients who have opted out of this account's agent emails (filter to one agent via `agent_id`; account-wide opt-outs always apply). Paginated via `limit`/`offset`; returns the page plus the `total` count.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; always scoped to the key's account.", + "operationId": "list_agent_email_optouts_api_api_agents_agent_email_optouts_get", + "parameters": [ + { + "description": "Filter to one agent (account-wide opt-outs still apply)", + "in": "query", + "name": "agent_id", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter to one agent (account-wide opt-outs still apply)", + "title": "Agent Id" + } + }, + { + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 50, + "maximum": 200, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "in": "query", + "name": "offset", + "required": false, + "schema": { + "default": 0, + "minimum": 0, + "title": "Offset", + "type": "integer" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentEmailOptOutListResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "List agent-email opt-outs", + "tags": [ + "agents" + ] + } + }, + "/agents/agent-email-optouts/{optout_id}": { + "delete": { + "description": "Revoke an opt-out (opt the recipient back in to agent emails).\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; the opt-out must belong to the key's account.", + "operationId": "remove_agent_email_optout_api_api_agents_agent_email_optouts__optout_id__delete", + "parameters": [ + { + "in": "path", + "name": "optout_id", + "required": true, + "schema": { + "title": "Optout Id", + "type": "string" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Revoke an agent-email opt-out", + "tags": [ + "agents" + ] + } + }, + "/agents/blocked-email-senders": { + "get": { + "description": "List the account's blocked inbound email senders (newest first, paginated via `limit`/`offset`) plus the governance `auto_block_mode`.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; always scoped to the key's account.", + "operationId": "list_blocked_email_senders_api_api_agents_blocked_email_senders_get", + "parameters": [ + { + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 50, + "maximum": 200, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "in": "query", + "name": "offset", + "required": false, + "schema": { + "default": 0, + "minimum": 0, + "title": "Offset", + "type": "integer" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BlockedEmailSenderListResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "List blocked inbound email senders + the auto-block mode", + "tags": [ + "agents" + ] + }, + "post": { + "description": "Add a sender address or a whole domain to the account blocklist (idempotent; `match_type` is `address` (default) or `domain`).\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account.", + "operationId": "block_email_sender_api_api_agents_blocked_email_senders_post", + "parameters": [ + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BlockEmailSenderRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BlockedEmailSenderResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Block an inbound email sender or domain", + "tags": [ + "agents" + ] + } + }, + "/agents/blocked-email-senders/mode": { + "put": { + "description": "Set whether a governance BLOCK on an authenticated inbound email sender auto-adds them to the blocklist (`disabled`, `input`, or `input_and_output`); returns the updated list.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account.", + "operationId": "set_auto_block_mode_api_api_agents_blocked_email_senders_mode_put", + "parameters": [ + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetAutoBlockModeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BlockedEmailSenderListResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Set the governance auto-block mode", + "tags": [ + "agents" + ] + } + }, + "/agents/blocked-email-senders/{blocked_id}": { + "delete": { + "description": "Remove a blocked sender by id.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; the blocked sender must belong to the key's account.", + "operationId": "unblock_email_sender_api_api_agents_blocked_email_senders__blocked_id__delete", + "parameters": [ + { + "in": "path", + "name": "blocked_id", + "required": true, + "schema": { + "title": "Blocked Id", + "type": "string" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Unblock an inbound email sender", + "tags": [ + "agents" + ] + } + }, + "/agents/evaluation-criteria/{criteria_id}": { + "delete": { + "description": "Delete an evaluation criteria and all associated evaluation results.\n\nThis action is permanent and cannot be undone. All historical result\nrecords tied to the criteria are removed as well.", + "operationId": "delete_evaluation_criteria_api_agents_evaluation_criteria__criteria_id__delete", + "parameters": [ + { + "in": "path", + "name": "criteria_id", + "required": true, + "schema": { + "title": "Criteria Id", + "type": "string" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Delete Evaluation Criteria", + "tags": [ + "agent-evaluations" + ] + }, + "get": { + "description": "Get a single evaluation criteria by ID.\n\nReturns the full criteria configuration including type-specific fields,\ncurrent enabled state, and a summary of recent evaluation results.", + "operationId": "get_evaluation_criteria_api_agents_evaluation_criteria__criteria_id__get", + "parameters": [ + { + "in": "path", + "name": "criteria_id", + "required": true, + "schema": { + "title": "Criteria Id", + "type": "string" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluationCriteriaResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Get Evaluation Criteria", + "tags": [ + "agent-evaluations" + ] + }, + "patch": { + "description": "Update an evaluation criteria.\n\nAccepts a partial update \u2013 only the fields included in the request body\nare modified. Use this to toggle enabled/disabled, change the\nevaluation prompt, adjust retries, or rename the criteria.", + "operationId": "update_evaluation_criteria_api_agents_evaluation_criteria__criteria_id__patch", + "parameters": [ + { + "in": "path", + "name": "criteria_id", + "required": true, + "schema": { + "title": "Criteria Id", + "type": "string" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateEvaluationCriteriaRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluationCriteriaResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Update Evaluation Criteria", + "tags": [ + "agent-evaluations" + ] + } + }, + "/agents/evaluation-criteria/{criteria_id}/compatible-runs": { + "get": { + "description": "List agent runs that have a completed step matching the criteria's target step.\n\nReturns runs whose step output can be used for testing or replaying the\nevaluation criteria. Results are ordered newest-first and paginated.", + "operationId": "list_compatible_runs_api_agents_evaluation_criteria__criteria_id__compatible_runs_get", + "parameters": [ + { + "in": "path", + "name": "criteria_id", + "required": true, + "schema": { + "title": "Criteria Id", + "type": "string" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "minimum": 1, + "title": "Page", + "type": "integer" + } + }, + { + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 20, + "maximum": 100, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "in": "query", + "name": "started_after", + "required": false, + "schema": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Started After" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompatibleRunListResponse" + } + } + }, + "description": "Successful Response" }, - "total": { - "title": "Total", - "type": "integer" + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "required": [ - "total", - "passed", - "failed", - "flagged", - "pass_rate", - "failure_rate", - "by_mode" - ], - "title": "NonManualEvaluationSummaryResponse", - "type": "object" + "summary": "List Compatible Runs", + "tags": [ + "agent-evaluations" + ] } }, - "securitySchemes": { - "ApiKeyAuth": { - "description": "API key issued from the Seclai dashboard.", - "in": "header", - "name": "X-API-Key", - "type": "apiKey" - }, - "BearerAuth": { - "bearerFormat": "JWT", - "description": "OAuth2 access token from AWS Cognito.", - "scheme": "bearer", - "type": "http" - } - } - }, - "info": { - "description": "Main API service for Seclai", - "title": "Seclai API", - "version": "local" - }, - "openapi": "3.1.0", - "paths": { - "/agents": { + "/agents/evaluation-criteria/{criteria_id}/results": { "get": { - "description": "List agents for the account with pagination.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", - "operationId": "list_agents_api_agents_get", + "description": "List evaluation results for a criteria with optional filtering.\n\nSupports filtering by status (pending, passed, failed, skipped, error),\nflagged-only mode, and an optional time range. Results are paginated\nwith configurable page size.", + "operationId": "list_evaluation_results_api_agents_evaluation_criteria__criteria_id__results_get", "parameters": [ { - "description": "Page number", + "in": "path", + "name": "criteria_id", + "required": true, + "schema": { + "title": "Criteria Id", + "type": "string" + } + }, + { + "in": "query", + "name": "status", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + { + "in": "query", + "name": "flagged_only", + "required": false, + "schema": { + "default": false, + "title": "Flagged Only", + "type": "boolean" + } + }, + { + "in": "query", + "name": "time_from", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Time From" + } + }, + { + "in": "query", + "name": "time_to", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Time To" + } + }, + { "in": "query", "name": "page", "required": false, "schema": { "default": 1, - "description": "Page number", "minimum": 1, "title": "Page", "type": "integer" } }, { - "description": "Items per page", "in": "query", "name": "limit", "required": false, "schema": { "default": 20, - "description": "Items per page", "maximum": 100, "minimum": 1, "title": "Limit", @@ -11336,7 +13681,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__agents__AgentListResponse" + "$ref": "#/components/schemas/EvaluationResultListResponse" } } }, @@ -11351,17 +13696,44 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "List agents", + "summary": "List Evaluation Results", "tags": [ - "agents" + "agent-evaluations" ] }, "post": { - "description": "Create a new agent.\n\nTrigger types:\n- `dynamic_input`: triggered via API with user-provided input\n- `template_input`: triggered via API with a predefined template\n- `schedule`: triggered on a schedule\n- `new_content`: triggered when new content arrives\n- `email_received`: a virtual email inbox; runs when mail arrives at the agent's address. Configure the alias/allowlist with `PUT /agents/{agent_id}/triggers/{trigger_id}/email-config`.\n\nTemplates: `blank`, `retrieval_example`, `simple_qa`, `summarizer`, `json_extractor`, `content_change_notifier`, `scheduled_report`, `webhook_pipeline`\n\nImporting an existing agent:\n- Pass `agent_definition` with the JSON shape produced by `GET /agents/{id}/export`. The full extras suite (alert_configs, evaluation_criteria, governance_policies, schedules, solutions) is applied; items that don't resolve in this account are reported in the response's `import_warnings` array.\n- Use `POST /agents/preview-import` first to surface `unresolved_refs` (workflow refs to KBs, memory banks, source connections, sub-agents that don't exist here). Then pass `entity_remap: {source_uuid: target_uuid}` on this call to substitute them before save.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Agent is created in the caller's account.", - "operationId": "create_agent_api_agents_post", + "description": "Record an evaluation result for a criteria.\n\nUse this endpoint to push results from external test harnesses, CI/CD\npipelines, or custom evaluation logic. Each result is linked to an\nagent run and optionally a specific step run.", + "operationId": "create_evaluation_result_api_agents_evaluation_criteria__criteria_id__results_post", "parameters": [ + { + "in": "path", + "name": "criteria_id", + "required": true, + "schema": { + "title": "Criteria Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -11373,7 +13745,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__agents__CreateAgentRequest" + "$ref": "#/components/schemas/CreateEvaluationResultRequest" } } }, @@ -11384,39 +13756,121 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentSummaryResponse" + "$ref": "#/components/schemas/EvaluationResultResponse" } } }, "description": "Successful Response" }, - "402": { - "description": "Plan limit exceeded \u2014 the account has reached the maximum number of agents allowed by its subscription plan." + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Create Evaluation Result", + "tags": [ + "agent-evaluations" + ] + } + }, + "/agents/evaluation-criteria/{criteria_id}/summary": { + "get": { + "description": "Get an aggregated summary of evaluation results for a criteria.\n\nReturns total, passed, failed, error, and flagged counts alongside the\naverage score, giving a quick overview of how the criteria is performing.", + "operationId": "get_evaluation_summary_api_agents_evaluation_criteria__criteria_id__summary_get", + "parameters": [ + { + "in": "path", + "name": "criteria_id", + "required": true, + "schema": { + "title": "Criteria Id", + "type": "string" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvaluationResultSummaryResponse" + } + } + }, + "description": "Successful Response" }, "422": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentDefinitionImportErrorResponse" + "$ref": "#/components/schemas/HTTPValidationError" } } }, - "description": "The supplied `agent_definition` payload failed validation. The body lists each error with a 1-indexed line/column pointing into the canonical pretty-printed echo of the payload (also returned in `source`)." + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Create an agent", + "summary": "Get Evaluation Summary", "tags": [ - "agents" + "agent-evaluations" ] } }, - "/agents/agent-email-optouts": { + "/agents/evaluation-results/non-manual-summary": { "get": { - "description": "List recipients who have opted out of this account's agent emails (filter to one agent via `agent_id`; account-wide opt-outs always apply). Paginated via `limit`/`offset`; returns the page plus the `total` count.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; always scoped to the key's account.", - "operationId": "list_agent_email_optouts_api_api_agents_agent_email_optouts_get", + "description": "Get an evaluation summary for API key clients.\n\nReturns aggregated pass/fail/flagged counts and pass rates for each evaluation mode (eval_and_retry, sample_and_flag).\n\nThe ``agent_id`` scoping parameter is part of the ``2026-07-27`` changeset\n(opt in via the ``Seclai-Version`` header). Clients on the legacy baseline\nalways receive the account-wide rollup; ``agent_id`` is ignored for them so\nthe endpoint's behavior is frozen. With ``2026-07-27`` or later, the summary\nis scoped to ``agent_id`` when supplied (and returns 404 if it doesn't exist).", + "operationId": "get_non_manual_evaluation_summary_api_agents_evaluation_results_non_manual_summary_get", "parameters": [ { - "description": "Filter to one agent (account-wide opt-outs still apply)", + "description": "Scope the summary to a single agent. Omit for account-wide.", "in": "query", "name": "agent_id", "required": false, @@ -11429,31 +13883,52 @@ "type": "null" } ], - "description": "Filter to one agent (account-wide opt-outs still apply)", + "description": "Scope the summary to a single agent. Omit for account-wide.", "title": "Agent Id" } }, { "in": "query", - "name": "limit", + "name": "days", "required": false, "schema": { - "default": 50, - "maximum": 200, + "default": 30, + "maximum": 730, "minimum": 1, - "title": "Limit", + "title": "Days", "type": "integer" } }, { "in": "query", - "name": "offset", + "name": "start_date", "required": false, "schema": { - "default": 0, - "minimum": 0, - "title": "Offset", - "type": "integer" + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Start Date" + } + }, + { + "in": "query", + "name": "end_date", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "End Date" } }, { @@ -11468,7 +13943,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentEmailOptOutListResponse" + "$ref": "#/components/schemas/schemas__v1__agent_evaluations__NonManualEvaluationSummaryResponse" } } }, @@ -11483,81 +13958,64 @@ } }, "description": "Validation Error" - } - }, - "summary": "List agent-email opt-outs", - "tags": [ - "agents" - ] - } - }, - "/agents/agent-email-optouts/{optout_id}": { - "delete": { - "description": "Revoke an opt-out (opt the recipient back in to agent emails).\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; the opt-out must belong to the key's account.", - "operationId": "remove_agent_email_optout_api_api_agents_agent_email_optouts__optout_id__delete", - "parameters": [ - { - "in": "path", - "name": "optout_id", - "required": true, - "schema": { - "title": "Optout Id", - "type": "string" - } - }, - { - "$ref": "#/components/parameters/X-Account-Id" - }, - { - "$ref": "#/components/parameters/Seclai-Version" - } - ], - "responses": { - "204": { - "description": "Successful Response" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Revoke an agent-email opt-out", + "summary": "Get Non Manual Evaluation Summary", "tags": [ - "agents" + "agent-evaluations" ] } }, - "/agents/blocked-email-senders": { + "/agents/inbound-email-rejections": { "get": { - "description": "List the account's blocked inbound email senders (newest first, paginated via `limit`/`offset`) plus the governance `auto_block_mode`.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; always scoped to the key's account.", - "operationId": "list_blocked_email_senders_api_api_agents_blocked_email_senders_get", + "description": "List recent inbound emails that were quietly discarded before running an agent (unauthorized sender, unknown alias, spam/virus, flood-shed) for this account's agents.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; always scoped to the key's account.", + "operationId": "list_inbound_email_rejections_api_api_agents_inbound_email_rejections_get", "parameters": [ { + "description": "Filter to a single agent's rejections", "in": "query", - "name": "limit", + "name": "agent_id", "required": false, "schema": { - "default": 50, - "maximum": 200, - "minimum": 1, - "title": "Limit", - "type": "integer" + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter to a single agent's rejections", + "title": "Agent Id" } }, { "in": "query", - "name": "offset", + "name": "limit", "required": false, "schema": { - "default": 0, - "minimum": 0, - "title": "Offset", + "default": 50, + "maximum": 200, + "minimum": 1, + "title": "Limit", "type": "integer" } }, @@ -11573,7 +14031,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BlockedEmailSenderListResponse" + "items": { + "$ref": "#/components/schemas/InboundEmailRejectionResponse" + }, + "title": "Response List Inbound Email Rejections Api Api Agents Inbound Email Rejections Get", + "type": "array" } } }, @@ -11588,66 +14050,36 @@ } }, "description": "Validation Error" - } - }, - "summary": "List blocked inbound email senders + the auto-block mode", - "tags": [ - "agents" - ] - }, - "post": { - "description": "Add a sender address or a whole domain to the account blocklist (idempotent; `match_type` is `address` (default) or `domain`).\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account.", - "operationId": "block_email_sender_api_api_agents_blocked_email_senders_post", - "parameters": [ - { - "$ref": "#/components/parameters/X-Account-Id" - }, - { - "$ref": "#/components/parameters/Seclai-Version" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BlockEmailSenderRequest" - } - } }, - "required": true - }, - "responses": { - "201": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BlockedEmailSenderResponse" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "type": "integer" } } - }, - "description": "Validation Error" + } } }, - "summary": "Block an inbound email sender or domain", + "summary": "List discarded inbound emails", "tags": [ "agents" ] } }, - "/agents/blocked-email-senders/mode": { - "put": { - "description": "Set whether a governance BLOCK on an authenticated inbound email sender auto-adds them to the blocklist (`disabled`, `input`, or `input_and_output`); returns the updated list.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account.", - "operationId": "set_auto_block_mode_api_api_agents_blocked_email_senders_mode_put", + "/agents/inbound-email-status": { + "get": { + "description": "Whether the account-wide overload circuit breaker has currently paused new inbound email (all inbound turned away until the queued backlog drains), plus the size of the QUEUED (over-quota parked) run backlog.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; always scoped to the key's account.", + "operationId": "get_inbound_email_status_api_api_agents_inbound_email_status_get", "parameters": [ { "$ref": "#/components/parameters/X-Account-Id" @@ -11656,58 +14088,47 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SetAutoBlockModeRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BlockedEmailSenderListResponse" + "$ref": "#/components/schemas/InboundEmailStatusResponse" } } }, "description": "Successful Response" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Set the governance auto-block mode", + "summary": "Account inbound-email overload status", "tags": [ "agents" ] } }, - "/agents/blocked-email-senders/{blocked_id}": { - "delete": { - "description": "Remove a blocked sender by id.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; the blocked sender must belong to the key's account.", - "operationId": "unblock_email_sender_api_api_agents_blocked_email_senders__blocked_id__delete", + "/agents/inbound-email-status/cancel-queued": { + "post": { + "description": "Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run has consumed no quota, so this merely fails them. Returns the count cancelled.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account.", + "operationId": "cancel_queued_email_runs_api_api_agents_inbound_email_status_cancel_queued_post", "parameters": [ - { - "in": "path", - "name": "blocked_id", - "required": true, - "schema": { - "title": "Blocked Id", - "type": "string" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -11716,40 +14137,46 @@ } ], "responses": { - "204": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CancelQueuedRunsResponse" + } + } + }, "description": "Successful Response" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Unblock an inbound email sender", + "summary": "Cancel all queued inbound-email runs", "tags": [ "agents" ] } }, - "/agents/evaluation-criteria/{criteria_id}": { - "delete": { - "description": "Delete an evaluation criteria and all associated evaluation results.\n\nThis action is permanent and cannot be undone. All historical result\nrecords tied to the criteria are removed as well.", - "operationId": "delete_evaluation_criteria_api_agents_evaluation_criteria__criteria_id__delete", - "parameters": [ - { - "in": "path", - "name": "criteria_id", - "required": true, - "schema": { - "title": "Criteria Id", - "type": "string" - } - }, + "/agents/inbound-email-status/resume": { + "post": { + "description": "Manually lift the account-wide inbound pause. If the queued backlog is still above the ceiling the breaker re-arms on the next evaluation \u2014 this is a one-shot override, not a permanent disable.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account.", + "operationId": "resume_inbound_email_api_api_agents_inbound_email_status_resume_post", + "parameters": [ { "$ref": "#/components/parameters/X-Account-Id" }, @@ -11758,38 +14185,46 @@ } ], "responses": { - "204": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResumeInboundResponse" + } + } + }, "description": "Successful Response" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Delete Evaluation Criteria", + "summary": "Manually resume paused inbound email", "tags": [ - "agent-evaluations" + "agents" ] - }, - "get": { - "description": "Get a single evaluation criteria by ID.\n\nReturns the full criteria configuration including type-specific fields,\ncurrent enabled state, and a summary of recent evaluation results.", - "operationId": "get_evaluation_criteria_api_agents_evaluation_criteria__criteria_id__get", + } + }, + "/agents/preview-import": { + "post": { + "description": "Validate an `agent_definition` payload (the same shape produced by `GET /agents/{agent_id}/export`) without creating or modifying any agent. On success returns a summary the client can show before commit (counts of steps, schedules, alert configs, evaluation criteria, governance policies). On failure returns the same 422 body shape used by `POST /agents` and `PUT /agents/{id}` so callers can render line/column-anchored errors.\n\nCoverage: everything decidable from the payload itself \u2014 schema, step ids, nesting depth, text lengths, attachment references, prompt-tool declarations, step-graph cycles, racing step references, and `for_each` aggregation. Rules that depend on account state (email recipients, memory-bank types, cloud-drive connections, the agent's own trigger) can only run at save time, so `POST /agents` may still reject a payload this endpoint accepts.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. No DB writes.", + "operationId": "preview_import_agent_api_agents_preview_import_post", "parameters": [ - { - "in": "path", - "name": "criteria_id", - "required": true, - "schema": { - "title": "Criteria Id", - "type": "string" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -11797,12 +14232,22 @@ "$ref": "#/components/parameters/Seclai-Version" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__agents__AgentImportPreviewRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EvaluationCriteriaResponse" + "$ref": "#/components/schemas/routers__api__agents__AgentImportPreviewResponse" } } }, @@ -11812,31 +14257,42 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/AgentDefinitionImportErrorResponse" } } }, - "description": "Validation Error" + "description": "The supplied `agent_definition` payload failed validation. The body lists each error with a 1-indexed line/column pointing into the canonical pretty-printed echo of the payload (also returned in `source`)." + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Get Evaluation Criteria", + "summary": "Preview an agent_definition import", "tags": [ - "agent-evaluations" + "agents" ] - }, - "patch": { - "description": "Update an evaluation criteria.\n\nAccepts a partial update \u2013 only the fields included in the request body\nare modified. Use this to toggle enabled/disabled, change the\nevaluation prompt, adjust retries, or rename the criteria.", - "operationId": "update_evaluation_criteria_api_agents_evaluation_criteria__criteria_id__patch", + } + }, + "/agents/runs/search": { + "post": { + "description": "Search agent traces using semantic similarity.\n\nFinds step-run outputs that are most semantically similar to the query.\nResults include the matching text, agent/step metadata, and a similarity score.\n\nAgent traces are automatically indexed when runs complete. The first 7 days of storage are free; extended retention is billed.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Searches only within your account's traces.", + "operationId": "search_agent_runs_api_agents_runs_search_post", "parameters": [ - { - "in": "path", - "name": "criteria_id", - "required": true, - "schema": { - "title": "Criteria Id", - "type": "string" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -11848,7 +14304,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateEvaluationCriteriaRequest" + "$ref": "#/components/schemas/routers__api__agents__AgentTraceSearchRequest" } } }, @@ -11859,7 +14315,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EvaluationCriteriaResponse" + "$ref": "#/components/schemas/AgentTraceSearchResponse" } } }, @@ -11874,68 +14330,46 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Update Evaluation Criteria", + "summary": "Search agent traces", "tags": [ - "agent-evaluations" + "agents" ] } }, - "/agents/evaluation-criteria/{criteria_id}/compatible-runs": { - "get": { - "description": "List agent runs that have a completed step matching the criteria's target step.\n\nReturns runs whose step output can be used for testing or replaying the\nevaluation criteria. Results are ordered newest-first and paginated.", - "operationId": "list_compatible_runs_api_agents_evaluation_criteria__criteria_id__compatible_runs_get", + "/agents/runs/{run_id}": { + "delete": { + "description": "Cancel an in-flight (`processing`) or queued (`queued`) agent run.\n\nA `queued` run is an inbound-email run parked by the per-plan rate quota that has not yet been dispatched; it has consumed no quota.\n\nIf the run is already in a terminal state (`completed` or `failed`), cancellation will be rejected.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only cancel runs belonging to your account.", + "operationId": "delete_agent_run_api_agents_runs__run_id__delete", "parameters": [ { "in": "path", - "name": "criteria_id", + "name": "run_id", "required": true, "schema": { - "title": "Criteria Id", + "title": "Run Id", "type": "string" } }, - { - "in": "query", - "name": "page", - "required": false, - "schema": { - "default": 1, - "minimum": 1, - "title": "Page", - "type": "integer" - } - }, - { - "in": "query", - "name": "limit", - "required": false, - "schema": { - "default": 20, - "maximum": 100, - "minimum": 1, - "title": "Limit", - "type": "integer" - } - }, - { - "in": "query", - "name": "started_after", - "required": false, - "schema": { - "anyOf": [ - { - "format": "date-time", - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Started After" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -11948,7 +14382,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CompatibleRunListResponse" + "$ref": "#/components/schemas/AgentRunResponse" } } }, @@ -11963,107 +14397,54 @@ } }, "description": "Validation Error" - } - }, - "summary": "List Compatible Runs", - "tags": [ - "agent-evaluations" - ] - } - }, - "/agents/evaluation-criteria/{criteria_id}/results": { - "get": { - "description": "List evaluation results for a criteria with optional filtering.\n\nSupports filtering by status (pending, passed, failed, skipped, error),\nflagged-only mode, and an optional time range. Results are paginated\nwith configurable page size.", - "operationId": "list_evaluation_results_api_agents_evaluation_criteria__criteria_id__results_get", - "parameters": [ - { - "in": "path", - "name": "criteria_id", - "required": true, - "schema": { - "title": "Criteria Id", - "type": "string" - } - }, - { - "in": "query", - "name": "status", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Status" - } - }, - { - "in": "query", - "name": "flagged_only", - "required": false, - "schema": { - "default": false, - "title": "Flagged Only", - "type": "boolean" - } }, - { - "in": "query", - "name": "time_from", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" } - ], - "title": "Time From" - } - }, - { - "in": "query", - "name": "time_to", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" } - ], - "title": "Time To" + } } - }, + } + }, + "summary": "Cancel an agent run", + "tags": [ + "agents" + ] + }, + "get": { + "description": "Fetch the latest snapshot for an agent run created by `POST /agents/{agent_id}/runs` or `POST /agents/{agent_id}/runs/stream`.\n\nThe response includes `status`, `error_count`, and `output` once the run completes. Use `include_step_outputs=true` to include per-step outputs, timing, durations, and credits.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only access runs belonging to your account.", + "operationId": "get_agent_run_api_agents_runs__run_id__get", + "parameters": [ { - "in": "query", - "name": "page", - "required": false, + "in": "path", + "name": "run_id", + "required": true, "schema": { - "default": 1, - "minimum": 1, - "title": "Page", - "type": "integer" + "title": "Run Id", + "type": "string" } }, { + "description": "If true, include per-step outputs with timing, durations, and credits.", "in": "query", - "name": "limit", + "name": "include_step_outputs", "required": false, "schema": { - "default": 20, - "maximum": 100, - "minimum": 1, - "title": "Limit", - "type": "integer" + "default": false, + "description": "If true, include per-step outputs with timing, durations, and credits.", + "title": "Include Step Outputs", + "type": "boolean" } }, { @@ -12078,7 +14459,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EvaluationResultListResponse" + "$ref": "#/components/schemas/AgentRunResponse" } } }, @@ -12093,23 +14474,43 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "List Evaluation Results", + "summary": "Get an agent run", "tags": [ - "agent-evaluations" + "agents" ] - }, - "post": { - "description": "Record an evaluation result for a criteria.\n\nUse this endpoint to push results from external test harnesses, CI/CD\npipelines, or custom evaluation logic. Each result is linked to an\nagent run and optionally a specific step run.", - "operationId": "create_evaluation_result_api_agents_evaluation_criteria__criteria_id__results_post", + } + }, + "/agents/{agent_id}": { + "delete": { + "description": "Soft-delete an agent. The agent will no longer appear in listings or be accessible via the API.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only delete agents belonging to your account.", + "operationId": "delete_agent_api_agents__agent_id__delete", "parameters": [ { "in": "path", - "name": "criteria_id", + "name": "agent_id", "required": true, "schema": { - "title": "Criteria Id", + "title": "Agent Id", "type": "string" } }, @@ -12120,55 +14521,54 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateEvaluationResultRequest" - } - } - }, - "required": true - }, "responses": { - "201": { + "204": { + "description": "Successful Response" + }, + "422": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EvaluationResultResponse" + "$ref": "#/components/schemas/HTTPValidationError" } } }, - "description": "Successful Response" + "description": "Validation Error" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Create Evaluation Result", + "summary": "Delete an agent", "tags": [ - "agent-evaluations" + "agents" ] - } - }, - "/agents/evaluation-criteria/{criteria_id}/summary": { + }, "get": { - "description": "Get an aggregated summary of evaluation results for a criteria.\n\nReturns total, passed, failed, error, and flagged counts alongside the\naverage score, giving a quick overview of how the criteria is performing.", - "operationId": "get_evaluation_summary_api_agents_evaluation_criteria__criteria_id__summary_get", + "description": "Fetch an agent's metadata (name, description, trigger type, timestamps).\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only access agents belonging to your account.", + "operationId": "get_agent_metadata_api_agents__agent_id__get", "parameters": [ { "in": "path", - "name": "criteria_id", + "name": "agent_id", "required": true, "schema": { - "title": "Criteria Id", + "title": "Agent Id", "type": "string" } }, @@ -12184,7 +14584,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EvaluationResultSummaryResponse" + "$ref": "#/components/schemas/AgentSummaryResponse" } } }, @@ -12199,79 +14599,42 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Get Evaluation Summary", + "summary": "Get an agent", "tags": [ - "agent-evaluations" + "agents" ] - } - }, - "/agents/evaluation-results/non-manual-summary": { - "get": { - "description": "Get an evaluation summary for API key clients.\n\nReturns aggregated pass/fail/flagged counts and pass rates for each evaluation mode (eval_and_retry, sample_and_flag).\n\nThe ``agent_id`` scoping parameter is part of the ``2026-07-27`` changeset\n(opt in via the ``Seclai-Version`` header). Clients on the legacy baseline\nalways receive the account-wide rollup; ``agent_id`` is ignored for them so\nthe endpoint's behavior is frozen. With ``2026-07-27`` or later, the summary\nis scoped to ``agent_id`` when supplied (and returns 404 if it doesn't exist).", - "operationId": "get_non_manual_evaluation_summary_api_agents_evaluation_results_non_manual_summary_get", + }, + "put": { + "description": "Update an agent's name, description, evaluation settings, and model lifecycle settings.\n\nEvaluation settings: `evaluation_mode` ('output_expectation', 'eval_and_retry', 'sample_and_flag'), `default_evaluation_tier` ('fast', 'balanced', 'thorough'), `max_retries`, `retry_on_failure`, `sampling_config`.\n\nModel lifecycle settings: `prompt_model_auto_upgrade_strategy` ('none', 'early_adopter', 'middle_of_road', 'cautious_adopter'), `prompt_model_auto_rollback_enabled`, `prompt_model_auto_rollback_triggers` (list of 'agent_eval_fail', 'governance_flag', 'governance_block', 'agent_run_failed').\n\nReplacing the workflow from an export:\n- Pass `agent_definition` with the JSON shape produced by `GET /agents/{id}/export`. Update only touches the workflow + agent metadata \u2014 alert_configs, evaluation_criteria, governance_policies, schedules, and solution links from the imported file are NOT applied (use the dedicated endpoints for those, or `POST /agents` to import as a new agent).\n- `entity_remap: {source_uuid: target_uuid}` substitutes workflow entity refs before save (same shape as `POST /agents`).\n\nAt least one field must be provided.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only update agents belonging to your account.", + "operationId": "update_agent_api_agents__agent_id__put", "parameters": [ { - "description": "Scope the summary to a single agent. Omit for account-wide.", - "in": "query", + "in": "path", "name": "agent_id", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Scope the summary to a single agent. Omit for account-wide.", - "title": "Agent Id" - } - }, - { - "in": "query", - "name": "days", - "required": false, - "schema": { - "default": 30, - "maximum": 730, - "minimum": 1, - "title": "Days", - "type": "integer" - } - }, - { - "in": "query", - "name": "start_date", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Start Date" - } - }, - { - "in": "query", - "name": "end_date", - "required": false, + "required": true, "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "End Date" + "title": "Agent Id", + "type": "string" } }, { @@ -12281,12 +14644,22 @@ "$ref": "#/components/parameters/Seclai-Version" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__agents__UpdateAgentRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/schemas__v1__agent_evaluations__NonManualEvaluationSummaryResponse" + "$ref": "#/components/schemas/AgentSummaryResponse" } } }, @@ -12296,28 +14669,66 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/AgentDefinitionImportErrorResponse" } } }, - "description": "Validation Error" + "description": "The supplied `agent_definition` payload failed validation. The body lists each error with a 1-indexed line/column pointing into the canonical pretty-printed echo of the payload (also returned in `source`)." + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Get Non Manual Evaluation Summary", + "summary": "Update agent metadata", "tags": [ - "agent-evaluations" + "agents" ] } }, - "/agents/inbound-email-rejections": { + "/agents/{agent_id}/ai-assistant/conversations": { "get": { - "description": "List recent inbound emails that were quietly discarded before running an agent (unauthorized sender, unknown alias, spam/virus, flood-shed) for this account's agents.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; always scoped to the key's account.", - "operationId": "list_inbound_email_rejections_api_api_agents_inbound_email_rejections_get", + "description": "Fetch the AI assistant conversation history for a specific step of an agent.\n\nReturns past conversation turns (user inputs, AI responses, accept/decline status) ordered oldest first. Use `step_type` to filter by step type, and optionally `step_id` to narrow to a specific step instance.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Only agents belonging to your account can be queried.", + "operationId": "get_ai_conversation_history_api_agents__agent_id__ai_assistant_conversations_get", "parameters": [ { - "description": "Filter to a single agent's rejections", - "in": "query", + "in": "path", "name": "agent_id", + "required": true, + "schema": { + "title": "Agent Id", + "type": "string" + } + }, + { + "description": "Step type to look up.", + "in": "query", + "name": "step_type", + "required": true, + "schema": { + "description": "Step type to look up.", + "title": "Step Type", + "type": "string" + } + }, + { + "description": "Step ID to filter by.", + "in": "query", + "name": "step_id", "required": false, "schema": { "anyOf": [ @@ -12328,22 +14739,37 @@ "type": "null" } ], - "description": "Filter to a single agent's rejections", - "title": "Agent Id" + "description": "Step ID to filter by.", + "title": "Step Id" } }, { + "description": "Max turns to return.", "in": "query", "name": "limit", "required": false, "schema": { - "default": 50, - "maximum": 200, + "default": 10, + "description": "Max turns to return.", + "maximum": 50, "minimum": 1, "title": "Limit", "type": "integer" } }, + { + "description": "Number of recent turns to skip.", + "in": "query", + "name": "offset", + "required": false, + "schema": { + "default": 0, + "description": "Number of recent turns to skip.", + "minimum": 0, + "title": "Offset", + "type": "integer" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -12356,11 +14782,7 @@ "content": { "application/json": { "schema": { - "items": { - "$ref": "#/components/schemas/InboundEmailRejectionResponse" - }, - "title": "Response List Inbound Email Rejections Api Api Agents Inbound Email Rejections Get", - "type": "array" + "$ref": "#/components/schemas/AiConversationHistoryResponse" } } }, @@ -12375,49 +14797,46 @@ } }, "description": "Validation Error" - } - }, - "summary": "List discarded inbound emails", - "tags": [ - "agents" - ] - } - }, - "/agents/inbound-email-status": { - "get": { - "description": "Whether the account-wide overload circuit breaker has currently paused new inbound email (all inbound turned away until the queued backlog drains), plus the size of the QUEUED (over-quota parked) run backlog.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; always scoped to the key's account.", - "operationId": "get_inbound_email_status_api_api_agents_inbound_email_status_get", - "parameters": [ - { - "$ref": "#/components/parameters/X-Account-Id" }, - { - "$ref": "#/components/parameters/Seclai-Version" - } - ], - "responses": { - "200": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/InboundEmailStatusResponse" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Successful Response" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Account inbound-email overload status", + "summary": "Get AI conversation history", "tags": [ "agents" ] } }, - "/agents/inbound-email-status/cancel-queued": { + "/agents/{agent_id}/ai-assistant/generate-steps": { "post": { - "description": "Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run consumed no quota or credits at queue time, so this merely fails them. Returns the count cancelled.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account.", - "operationId": "cancel_queued_email_runs_api_api_agents_inbound_email_status_cancel_queued_post", + "description": "Use the AI assistant to generate a full agent step workflow from a natural language description.\n\nProvide a description of what the agent should do, along with optional context (current steps, trigger type). The AI produces a complete set of agent steps.\nUse mode 'generate_full' for new workflows or 'modify_workflow' to refine existing ones.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Only agents belonging to your account can be used.", + "operationId": "generate_agent_steps_api_agents__agent_id__ai_assistant_generate_steps_post", "parameters": [ + { + "in": "path", + "name": "agent_id", + "required": true, + "schema": { + "title": "Agent Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -12425,29 +14844,76 @@ "$ref": "#/components/parameters/Seclai-Version" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateAgentStepsRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CancelQueuedRunsResponse" + "$ref": "#/components/schemas/GenerateAgentStepsResponse" } } }, "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Cancel all queued inbound-email runs", + "summary": "Generate agent workflow", "tags": [ "agents" ] } }, - "/agents/inbound-email-status/resume": { + "/agents/{agent_id}/ai-assistant/step-config": { "post": { - "description": "Manually lift the account-wide inbound pause. If the queued backlog is still above the ceiling the breaker re-arms on the next evaluation \u2014 this is a one-shot override, not a permanent disable.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account.", - "operationId": "resume_inbound_email_api_api_agents_inbound_email_status_resume_post", + "description": "Use the AI assistant to generate or refine a single step's configuration.\n\nProvide the step type, a natural language instruction, and optionally the current configuration. The AI will produce a proposed configuration along with an explanation. The suggestion is stored as a conversation turn that can be accepted or declined separately via the mark endpoint.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Only agents belonging to your account can be used.", + "operationId": "generate_step_config_api_agents__agent_id__ai_assistant_step_config_post", "parameters": [ + { + "in": "path", + "name": "agent_id", + "required": true, + "schema": { + "title": "Agent Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -12455,29 +14921,85 @@ "$ref": "#/components/parameters/Seclai-Version" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateStepConfigRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ResumeInboundResponse" + "$ref": "#/components/schemas/GenerateStepConfigResponse" } } }, "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Manually resume paused inbound email", + "summary": "Generate step configuration", "tags": [ "agents" ] } }, - "/agents/preview-import": { - "post": { - "description": "Validate an `agent_definition` payload (the same shape produced by `GET /agents/{agent_id}/export`) without creating or modifying any agent. On success returns a summary the client can show before commit (counts of steps, schedules, alert configs, evaluation criteria, governance policies). On failure returns the same 422 body shape used by `POST /agents` and `PUT /agents/{id}` so callers can render line/column-anchored errors.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. No DB writes.", - "operationId": "preview_import_agent_api_agents_preview_import_post", + "/agents/{agent_id}/ai-assistant/{conversation_id}": { + "patch": { + "description": "Accept or decline a proposed AI assistant configuration for a conversation turn.\n\nThis only updates the tracking status on the conversation record. To actually apply the proposed configuration, use the agent definition update endpoint separately.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. The conversation must belong to one of your agents.", + "operationId": "mark_ai_suggestion_api_agents__agent_id__ai_assistant__conversation_id__patch", "parameters": [ + { + "in": "path", + "name": "agent_id", + "required": true, + "schema": { + "title": "Agent Id", + "type": "string" + } + }, + { + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "title": "Conversation Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -12489,7 +15011,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__agents__AgentImportPreviewRequest" + "$ref": "#/components/schemas/MarkAiSuggestionRequest" } } }, @@ -12500,7 +15022,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__agents__AgentImportPreviewResponse" + "$ref": "#/components/schemas/OkResponse" } } }, @@ -12510,24 +15032,51 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentDefinitionImportErrorResponse" + "$ref": "#/components/schemas/HTTPValidationError" } } }, - "description": "The supplied `agent_definition` payload failed validation. The body lists each error with a 1-indexed line/column pointing into the canonical pretty-printed echo of the payload (also returned in `source`)." + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Preview an agent_definition import", + "summary": "Accept or decline suggestion", "tags": [ "agents" ] } }, - "/agents/runs/search": { - "post": { - "description": "Search agent traces using semantic similarity.\n\nFinds step-run outputs that are most semantically similar to the query.\nResults include the matching text, agent/step metadata, and a similarity score.\n\nAgent traces are automatically indexed when runs complete. The first 7 days of storage are free; extended retention is billed.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Searches only within your account's traces.", - "operationId": "search_agent_runs_api_agents_runs_search_post", + "/agents/{agent_id}/attachment-references": { + "get": { + "description": "Return the static attachment-reference contract for an agent \u2014 what files the agent's definition expects on a run.\n\nCall this BEFORE staging uploads so you know whether the agent accepts files at all (``requires_uploads``), and which specific filenames/indexes/patterns the templates reference. Mismatched batches are rejected at run time with HTTP 400.", + "operationId": "api_get_agent_attachment_references_api_agents__agent_id__attachment_references_get", "parameters": [ + { + "in": "path", + "name": "agent_id", + "required": true, + "schema": { + "title": "Agent Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -12535,22 +15084,12 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/routers__api__agents__AgentTraceSearchRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentTraceSearchResponse" + "$ref": "#/components/schemas/AgentAttachmentRefsApiResponse" } } }, @@ -12565,25 +15104,43 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Search agent traces", + "summary": "Get agent attachment-reference contract", "tags": [ "agents" ] } }, - "/agents/runs/{run_id}": { - "delete": { - "description": "Cancel an in-flight (`processing`) or queued (`queued`) agent run.\n\nA `queued` run is an inbound-email run parked by the per-plan rate quota that has not yet been dispatched; cancelling it consumes no quota or credits.\n\nIf the run is already in a terminal state (`completed` or `failed`), cancellation will be rejected.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only cancel runs belonging to your account.", - "operationId": "delete_agent_run_api_agents_runs__run_id__delete", + "/agents/{agent_id}/callers": { + "get": { + "description": "List the live agents that call this agent via a `call_agent` step. They must be disabled before this agent can be paused.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; the agent must belong to the key's account.", + "operationId": "get_agent_callers_api_api_agents__agent_id__callers_get", "parameters": [ { "in": "path", - "name": "run_id", + "name": "agent_id", "required": true, "schema": { - "title": "Run Id", + "title": "Agent Id", "type": "string" } }, @@ -12599,7 +15156,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentRunResponse" + "items": { + "$ref": "#/components/schemas/AgentCallerApiResponse" + }, + "title": "Response Get Agent Callers Api Api Agents Agent Id Callers Get", + "type": "array" } } }, @@ -12614,38 +15175,46 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Cancel an agent run", + "summary": "List agents that call this agent", "tags": [ "agents" ] - }, + } + }, + "/agents/{agent_id}/definition": { "get": { - "description": "Fetch the latest snapshot for an agent run created by `POST /agents/{agent_id}/runs` or `POST /agents/{agent_id}/runs/stream`.\n\nThe response includes `status`, `error_count`, and `output` once the run completes. Use `include_step_outputs=true` to include per-step outputs, timing, durations, and credits.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only access runs belonging to your account.", - "operationId": "get_agent_run_api_agents_runs__run_id__get", + "description": "Fetch the current agent definition from the main branch.\n\nThe response includes `change_id` which must be provided when updating the definition (optimistic locking).\n\nThe definition contains the agent's step workflow. Available step types:\n- `prompt_call`: Call an LLM with a prompt template\n- `retrieval`: Search a knowledge base\n- `regex_replace`: Reshape text via ordered regex find/replace rules\n- `gate`: Evaluate conditions, stop or continue child execution\n- `retry`: Re-execute from a target ancestor step (for quality-control loops; pair with a `gate` step for conditional retrying. Fields: `target_step_id` (ancestor step ID), `max_retries` (1\u201310))\n- `evaluate_step`: Score a selected previous step output and emit JSON with `score`, `passed`, and `pass_threshold` (fields: `target_step_id`, `evaluation_prompt`, `pass_threshold`, optional `evaluation_tier`, optional `expectation_config`)\n- `extract_data`: Progressively read and analyze large input\n- `extract_content`: Extract structured data (JSON, HTML, XML)\n- `add_chat_turn` / `load_chat_history`: Record a turn or load running history from a conversation memory bank\n- `add_memory` / `search_memory` / `load_memory`: Write, semantic-search, or load entries on a general memory bank\n- `send_email`: Send email with step output\n- `webhook_call`: POST data to an external URL\n- `write_aws_s3_object`: Write output to S3\n- `call_agent`: Invoke another agent\n- `write_metadata`: Write a value to content metadata (for filtering/gates; content-triggered agents only. Fields: `metadata_key`, `content`)\n- `write_content_attachment`: Write a file-backed attachment to content (optionally indexed for retrieval; content-triggered agents only. Fields: `attachment_key`, `content`, `content_type`, `indexed`)\n- `load_content_attachment`: Load a previously written attachment (content-triggered agents only. Fields: `attachment_key`)\n- `load_content`: Load the full text body of a source document (typically used with content-triggered agents; can also load by explicit `content_version_id`. Fields: `content_version_id` optional)\n- `streaming_result`: Stream LLM tokens in real-time via SSE (must be a direct child of `prompt_call`; requires `dynamic_input` or `template_input` trigger; `priority: true` enables real-time streaming). To stream **and** return a schema-validated payload, add a sibling branch `extract_content` (`expected_format: \"json\"` + `json_schema`) \u2192 `display_result` under the same `prompt_call` \u2014 a `display_result` takes precedence over the stream regardless of which finishes first, so its validated output becomes the run's result while the tokens act as a progress channel\n- `display_result`: Show output to the user\n- `join`: Merge parallel branches\n- `merge`: Combine multiple inputs into a single templated output\n- `text`: Static text literal\n- `for_each`: Iterate a body over a list of items (body lives in `body[]`)\n- `if_else`: Conditional dispatch. Evaluates `conditions` (same shape as `gate`) and runs `then_steps` on match, otherwise the optional `else_steps`. The chosen branch's output flows to the if_else step's own `child_steps` (post-branch continuation chain). **`display_result` and `streaming_result` are not allowed inside `then_steps` / `else_steps`** \u2014 end each branch with a content-producing step (e.g. `text`, `prompt_call`) and place the single `display_result` in `child_steps`.\n- `switch`: Single-discriminator dispatch. Renders `discriminator` (default `{{input}}`) and routes to the first matching `cases[]` entry (equality by default; pass a list in `match` for `$in` semantics) or to `else_steps` when nothing matches. The chosen case's output flows to the switch step's own `child_steps`. **`display_result` and `streaming_result` are not allowed inside `cases[].steps` or `else_steps`** \u2014 end each case with a content-producing step and place the single `display_result` in `child_steps`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only access agents belonging to your account.", + "operationId": "get_agent_definition_api_agents__agent_id__definition_get", "parameters": [ { "in": "path", - "name": "run_id", + "name": "agent_id", "required": true, "schema": { - "title": "Run Id", + "title": "Agent Id", "type": "string" } }, - { - "description": "If true, include per-step outputs with timing, durations, and credits.", - "in": "query", - "name": "include_step_outputs", - "required": false, - "schema": { - "default": false, - "description": "If true, include per-step outputs with timing, durations, and credits.", - "title": "Include Step Outputs", - "type": "boolean" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -12658,7 +15227,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentRunResponse" + "$ref": "#/components/schemas/AgentDefinitionResponse" } } }, @@ -12673,18 +15242,34 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Get an agent run", + "summary": "Get agent definition", "tags": [ "agents" ] - } - }, - "/agents/{agent_id}": { - "delete": { - "description": "Soft-delete an agent. The agent will no longer appear in listings or be accessible via the API.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only delete agents belonging to your account.", - "operationId": "delete_agent_api_agents__agent_id__delete", + }, + "put": { + "description": "Update the agent's definition on the main branch.\n\nUses **optimistic locking**: provide `expected_change_id` from the last `GET /agents/{agent_id}/definition`. Returns `409 Conflict` if the definition was modified since your last read.\n\nThe definition contains the agent's step workflow. Step types include `prompt_call`, `retrieval`, `regex_replace`, `gate`, `retry`, `evaluate_step`, `extract_data`, `extract_content`, `add_chat_turn`, `load_chat_history`, `add_memory`, `search_memory`, `load_memory`, `streaming_result`, `send_email`, `webhook_call`, `write_aws_s3_object`, `call_agent`, `write_metadata`, `write_content_attachment`, `load_content_attachment`, `load_content`, `display_result`, `join`, `merge`, `text`, `for_each`, `if_else`, and `switch`. Non-composite step types (`display_result`, `join`, `retry`, `streaming_result`) cannot contain child steps.\n\n**Retry steps** re-execute from a target ancestor step for quality-control loops. Configure with `target_step_id` (ancestor step ID) and `max_retries` (1\u201310). Best practice: place a `gate` step before the retry to make retries conditional.\n\n**if_else** runs `then_steps` when its `conditions` (same shape as `gate`) match, otherwise its optional `else_steps`. Either branch's output flows to the if_else step's own `child_steps` (the post-branch continuation chain).\n\n**switch** dispatches on a `discriminator` template (default `{{input}}`) to the first matching case (equality by default; pass a list in `match` for `$in` semantics) or to `else_steps` when no case matches. Cases own their own `steps` subtrees; the chosen branch's output flows to the switch step's own `child_steps`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only update agents belonging to your account.", + "operationId": "update_agent_definition_api_agents__agent_id__definition_put", "parameters": [ { "in": "path", @@ -12702,8 +15287,25 @@ "$ref": "#/components/parameters/Seclai-Version" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateAgentDefinitionRequest" + } + } + }, + "required": true + }, "responses": { - "204": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentDefinitionResponse" + } + } + }, "description": "Successful Response" }, "422": { @@ -12715,16 +15317,36 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Delete an agent", + "summary": "Update agent definition", "tags": [ "agents" ] - }, - "get": { - "description": "Fetch an agent's metadata (name, description, trigger type, timestamps).\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only access agents belonging to your account.", - "operationId": "get_agent_metadata_api_agents__agent_id__get", + } + }, + "/agents/{agent_id}/disable": { + "post": { + "description": "Disable an agent so it stops firing from every trigger path (API runs return 409, inbound email is turned away, scheduled/content triggers are skipped).\n\nReturns **409** with the blocking callers when other live agents still call this one via a `call_agent` step \u2014 disable those first.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token bound to a user (the acting user is recorded); the agent must belong to the key's account.", + "operationId": "disable_agent_api_api_agents__agent_id__disable_post", "parameters": [ { "in": "path", @@ -12762,16 +15384,36 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Get an agent", + "summary": "Pause (disable) an agent", "tags": [ "agents" ] - }, - "put": { - "description": "Update an agent's name, description, evaluation settings, and model lifecycle settings.\n\nEvaluation settings: `evaluation_mode` ('output_expectation', 'eval_and_retry', 'sample_and_flag'), `default_evaluation_tier` ('fast', 'balanced', 'thorough'), `max_retries`, `retry_on_failure`, `sampling_config`.\n\nModel lifecycle settings: `prompt_model_auto_upgrade_strategy` ('none', 'early_adopter', 'middle_of_road', 'cautious_adopter'), `prompt_model_auto_rollback_enabled`, `prompt_model_auto_rollback_triggers` (list of 'agent_eval_fail', 'governance_flag', 'governance_block', 'agent_run_failed').\n\nReplacing the workflow from an export:\n- Pass `agent_definition` with the JSON shape produced by `GET /agents/{id}/export`. Update only touches the workflow + agent metadata \u2014 alert_configs, evaluation_criteria, governance_policies, schedules, and solution links from the imported file are NOT applied (use the dedicated endpoints for those, or `POST /agents` to import as a new agent).\n- `entity_remap: {source_uuid: target_uuid}` substitutes workflow entity refs before save (same shape as `POST /agents`).\n\nAt least one field must be provided.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only update agents belonging to your account.", - "operationId": "update_agent_api_agents__agent_id__put", + } + }, + "/agents/{agent_id}/enable": { + "post": { + "description": "Re-enable a paused agent (clears the disable state, whether it was paused manually or auto-paused by the inbound-email overload safeguard).\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token bound to a user (the acting user is recorded); the agent must belong to the key's account.", + "operationId": "enable_agent_api_api_agents__agent_id__enable_post", "parameters": [ { "in": "path", @@ -12789,16 +15431,6 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/routers__api__agents__UpdateAgentRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { @@ -12814,23 +15446,41 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentDefinitionImportErrorResponse" + "$ref": "#/components/schemas/HTTPValidationError" } } }, - "description": "The supplied `agent_definition` payload failed validation. The body lists each error with a 1-indexed line/column pointing into the canonical pretty-printed echo of the payload (also returned in `source`)." + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Update agent metadata", + "summary": "Resume (enable) a paused agent", "tags": [ "agents" ] } }, - "/agents/{agent_id}/ai-assistant/conversations": { + "/agents/{agent_id}/evaluation-criteria": { "get": { - "description": "Fetch the AI assistant conversation history for a specific step of an agent.\n\nReturns past conversation turns (user inputs, AI responses, accept/decline status) ordered oldest first. Use `step_type` to filter by step type, and optionally `step_id` to narrow to a specific step instance.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Only agents belonging to your account can be queried.", - "operationId": "get_ai_conversation_history_api_agents__agent_id__ai_assistant_conversations_get", + "description": "List evaluation criteria configured for an agent.\n\nResponse shape is version-gated by the ``Seclai-Version`` header:\n\n- **Default / legacy** (no header, or a date before ``2026-07-27``): a bare\n JSON array of criteria (unpaginated \u2014 every criterion for the agent).\n- **``Seclai-Version: 2026-07-27`` or later**: the canonical paginated\n envelope ``{data, pagination: {page, limit, total, pages, has_next,\n has_prev}}``.\n\nEach criterion carries its type, configuration, and a summary of results\n(pass / fail counts). Criteria can be filtered client-side by type or\nenabled status.", + "operationId": "list_evaluation_criteria_api_agents__agent_id__evaluation_criteria_get", "parameters": [ { "in": "path", @@ -12842,61 +15492,28 @@ } }, { - "description": "Step type to look up.", - "in": "query", - "name": "step_type", - "required": true, - "schema": { - "description": "Step type to look up.", - "title": "Step Type", - "type": "string" - } - }, - { - "description": "Step ID to filter by.", "in": "query", - "name": "step_id", + "name": "page", "required": false, "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Step ID to filter by.", - "title": "Step Id" + "default": 1, + "minimum": 1, + "title": "Page", + "type": "integer" } }, { - "description": "Max turns to return.", "in": "query", "name": "limit", "required": false, "schema": { - "default": 10, - "description": "Max turns to return.", - "maximum": 50, + "default": 20, + "maximum": 100, "minimum": 1, "title": "Limit", "type": "integer" } }, - { - "description": "Number of recent turns to skip.", - "in": "query", - "name": "offset", - "required": false, - "schema": { - "default": 0, - "description": "Number of recent turns to skip.", - "minimum": 0, - "title": "Offset", - "type": "integer" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -12909,7 +15526,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AiConversationHistoryResponse" + "items": { + "$ref": "#/components/schemas/EvaluationCriteriaResponse" + }, + "title": "Response List Evaluation Criteria Api Agents Agent Id Evaluation Criteria Get", + "type": "array" } } }, @@ -12924,18 +15545,34 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Get AI conversation history", + "summary": "List Evaluation Criteria", "tags": [ - "agents" + "agent-evaluations" ] - } - }, - "/agents/{agent_id}/ai-assistant/generate-steps": { + }, "post": { - "description": "Use the AI assistant to generate a full agent step workflow from a natural language description.\n\nProvide a description of what the agent should do, along with optional context (current steps, trigger type). The AI produces a complete set of agent steps.\nUse mode 'generate_full' for new workflows or 'modify_workflow' to refine existing ones.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Only agents belonging to your account can be used.", - "operationId": "generate_agent_steps_api_agents__agent_id__ai_assistant_generate_steps_post", + "description": "Create new step evaluation settings for an agent.\n\nThe evaluation mode, retry settings, and sample frequency are inherited\nfrom the agent and stored on the criteria row for historical reference.", + "operationId": "create_evaluation_criteria_api_agents__agent_id__evaluation_criteria_post", "parameters": [ { "in": "path", @@ -12957,18 +15594,18 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GenerateAgentStepsRequest" + "$ref": "#/components/schemas/CreateEvaluationCriteriaRequest" } } }, "required": true }, "responses": { - "200": { + "201": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GenerateAgentStepsResponse" + "$ref": "#/components/schemas/EvaluationCriteriaResponse" } } }, @@ -12983,18 +15620,36 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Generate agent workflow", + "summary": "Create Evaluation Criteria", "tags": [ - "agents" + "agent-evaluations" ] } }, - "/agents/{agent_id}/ai-assistant/step-config": { + "/agents/{agent_id}/evaluation-criteria/test-draft": { "post": { - "description": "Use the AI assistant to generate or refine a single step's configuration.\n\nProvide the step type, a natural language instruction, and optionally the current configuration. The AI will produce a proposed configuration along with an explanation. The suggestion is stored as a conversation turn that can be accepted or declined separately via the mark endpoint.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Only agents belonging to your account can be used.", - "operationId": "generate_step_config_api_agents__agent_id__ai_assistant_step_config_post", + "description": "Run an ephemeral evaluation against provided step output without persisting results.\n\nUse this to interactively test evaluation prompts and expectation\nconfigurations while editing criteria. The evaluation is a billed LLM\ncall; only its result goes unrecorded.", + "operationId": "test_draft_evaluation_api_agents__agent_id__evaluation_criteria_test_draft_post", "parameters": [ { "in": "path", @@ -13016,7 +15671,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GenerateStepConfigRequest" + "$ref": "#/components/schemas/TestDraftEvaluationRequest" } } }, @@ -13027,7 +15682,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GenerateStepConfigResponse" + "$ref": "#/components/schemas/TestDraftEvaluationResponse" } } }, @@ -13042,18 +15697,36 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Generate step configuration", + "summary": "Test Draft Evaluation", "tags": [ - "agents" + "agent-evaluations" ] } }, - "/agents/{agent_id}/ai-assistant/{conversation_id}": { - "patch": { - "description": "Accept or decline a proposed AI assistant configuration for a conversation turn.\n\nThis only updates the tracking status on the conversation record. To actually apply the proposed configuration, use the agent definition update endpoint separately.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. The conversation must belong to one of your agents.", - "operationId": "mark_ai_suggestion_api_agents__agent_id__ai_assistant__conversation_id__patch", + "/agents/{agent_id}/evaluation-results": { + "get": { + "description": "List evaluation results across all criteria configured on an agent.\n\nReturns a paginated list of evaluation results with optional filtering by status, criteria, and date range. Results include score, pass/fail status, and details.", + "operationId": "list_agent_evaluation_results_api_agents__agent_id__evaluation_results_get", "parameters": [ { "in": "path", @@ -13065,12 +15738,100 @@ } }, { - "in": "path", - "name": "conversation_id", - "required": true, + "in": "query", + "name": "status", + "required": false, "schema": { - "title": "Conversation Id", - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + { + "in": "query", + "name": "step", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Step" + } + }, + { + "in": "query", + "name": "flagged_only", + "required": false, + "schema": { + "default": false, + "title": "Flagged Only", + "type": "boolean" + } + }, + { + "in": "query", + "name": "time_from", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Time From" + } + }, + { + "in": "query", + "name": "time_to", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Time To" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "minimum": 1, + "title": "Page", + "type": "integer" + } + }, + { + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 20, + "maximum": 100, + "minimum": 1, + "title": "Limit", + "type": "integer" } }, { @@ -13080,22 +15841,12 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MarkAiSuggestionRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/OkResponse" + "$ref": "#/components/schemas/EvaluationResultWithCriteriaListResponse" } } }, @@ -13110,26 +15861,131 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Accept or decline suggestion", + "summary": "List Agent Evaluation Results", "tags": [ - "agents" + "agent-evaluations" ] } }, - "/agents/{agent_id}/attachment-references": { + "/agents/{agent_id}/evaluation-runs": { "get": { - "description": "Return the static attachment-reference contract for an agent \u2014 what files the agent's definition expects on a run.\n\nCall this BEFORE staging uploads so you know whether the agent accepts files at all (``requires_uploads``), and which specific filenames/indexes/patterns the templates reference. Mismatched batches are rejected at run time with HTTP 400.", - "operationId": "api_get_agent_attachment_references_api_agents__agent_id__attachment_references_get", + "description": "List evaluation results grouped by agent run.\n\nReturns paginated per-run summaries with pass/fail counts and optional\nfiltering by evaluation outcome, step, or date range.", + "operationId": "list_evaluation_runs_api_agents__agent_id__evaluation_runs_get", "parameters": [ { - "in": "path", - "name": "agent_id", - "required": true, + "in": "path", + "name": "agent_id", + "required": true, + "schema": { + "title": "Agent Id", + "type": "string" + } + }, + { + "in": "query", + "name": "status", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + { + "in": "query", + "name": "step", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Step" + } + }, + { + "in": "query", + "name": "time_from", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Time From" + } + }, + { + "in": "query", + "name": "time_to", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Time To" + } + }, + { + "in": "query", + "name": "page", + "required": false, "schema": { - "title": "Agent Id", - "type": "string" + "default": 1, + "minimum": 1, + "title": "Page", + "type": "integer" + } + }, + { + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 20, + "maximum": 100, + "minimum": 1, + "title": "Limit", + "type": "integer" } }, { @@ -13144,7 +16000,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentAttachmentRefsApiResponse" + "$ref": "#/components/schemas/EvaluationRunSummaryListResponse" } } }, @@ -13159,71 +16015,36 @@ } }, "description": "Validation Error" - } - }, - "summary": "Get agent attachment-reference contract", - "tags": [ - "agents" - ] - } - }, - "/agents/{agent_id}/callers": { - "get": { - "description": "List the live agents that call this agent via a `call_agent` step. They must be disabled before this agent can be paused.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; the agent must belong to the key's account.", - "operationId": "get_agent_callers_api_api_agents__agent_id__callers_get", - "parameters": [ - { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } - }, - { - "$ref": "#/components/parameters/X-Account-Id" }, - { - "$ref": "#/components/parameters/Seclai-Version" - } - ], - "responses": { - "200": { + "503": { "content": { "application/json": { "schema": { - "items": { - "$ref": "#/components/schemas/AgentCallerApiResponse" - }, - "title": "Response Get Agent Callers Api Api Agents Agent Id Callers Get", - "type": "array" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "type": "integer" } } - }, - "description": "Validation Error" + } } }, - "summary": "List agents that call this agent", + "summary": "List Evaluation Runs", "tags": [ - "agents" + "agent-evaluations" ] } }, - "/agents/{agent_id}/definition": { + "/agents/{agent_id}/export": { "get": { - "description": "Fetch the current agent definition from the main branch.\n\nThe response includes `change_id` which must be provided when updating the definition (optimistic locking).\n\nThe definition contains the agent's step workflow. Available step types:\n- `prompt_call`: Call an LLM with a prompt template\n- `retrieval`: Search a knowledge base\n- `regex_replace`: Reshape text via ordered regex find/replace rules\n- `gate`: Evaluate conditions, stop or continue child execution\n- `retry`: Re-execute from a target ancestor step (for quality-control loops; pair with a `gate` step for conditional retrying. Fields: `target_step_id` (ancestor step ID), `max_retries` (1\u201310))\n- `evaluate_step`: Score a selected previous step output and emit JSON with `score`, `passed`, and `pass_threshold` (fields: `target_step_id`, `evaluation_prompt`, `pass_threshold`, optional `evaluation_tier`, optional `expectation_config`)\n- `extract_data`: Progressively read and analyze large input\n- `extract_content`: Extract structured data (JSON, HTML, XML)\n- `add_chat_turn` / `load_chat_history`: Record a turn or load running history from a conversation memory bank\n- `add_memory` / `search_memory` / `load_memory`: Write, semantic-search, or load entries on a general memory bank\n- `send_email`: Send email with step output\n- `webhook_call`: POST data to an external URL\n- `write_aws_s3_object`: Write output to S3\n- `call_agent`: Invoke another agent\n- `write_metadata`: Write a value to content metadata (for filtering/gates; content-triggered agents only. Fields: `metadata_key`, `content`)\n- `write_content_attachment`: Write a file-backed attachment to content (optionally indexed for retrieval; content-triggered agents only. Fields: `attachment_key`, `content`, `content_type`, `indexed`)\n- `load_content_attachment`: Load a previously written attachment (content-triggered agents only. Fields: `attachment_key`)\n- `load_content`: Load the full text body of a source document (typically used with content-triggered agents; can also load by explicit `content_version_id`. Fields: `content_version_id` optional)\n- `streaming_result`: Stream LLM tokens in real-time via SSE (must be a direct child of `prompt_call`; requires `dynamic_input` or `template_input` trigger; `priority: true` enables real-time streaming)\n- `display_result`: Show output to the user\n- `join`: Merge parallel branches\n- `merge`: Combine multiple inputs into a single templated output\n- `text`: Static text literal\n- `for_each`: Iterate a body over a list of items (body lives in `body[]`)\n- `if_else`: Conditional dispatch. Evaluates `conditions` (same shape as `gate`) and runs `then_steps` on match, otherwise the optional `else_steps`. The chosen branch's output flows to the if_else step's own `child_steps` (post-branch continuation chain). **`display_result` and `streaming_result` are not allowed inside `then_steps` / `else_steps`** \u2014 end each branch with a content-producing step (e.g. `text`, `prompt_call`) and place the single `display_result` in `child_steps`.\n- `switch`: Single-discriminator dispatch. Renders `discriminator` (default `{{input}}`) and routes to the first matching `cases[]` entry (equality by default; pass a list in `match` for `$in` semantics) or to `else_steps` when nothing matches. The chosen case's output flows to the switch step's own `child_steps`. **`display_result` and `streaming_result` are not allowed inside `cases[].steps` or `else_steps`** \u2014 end each case with a content-producing step and place the single `display_result` in `child_steps`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only access agents belonging to your account.", - "operationId": "get_agent_definition_api_agents__agent_id__definition_get", + "description": "Export an agent definition as a portable JSON snapshot.\n\nThe response contains the full definition, trigger configuration with schedules, alert configs, evaluation criteria, agent-scoped governance policies, and a resolved dependency manifest that maps every referenced external entity UUID to its human-readable name.\n\nResponse shape:\n- `export_version`: schema version (currently `\"5\"`)\n- `exported_at`: ISO-8601 timestamp\n- `agent`: name, description, schema_version, definition, timestamps\n- `trigger`: trigger type, input template, schedules\n- `alert_configs`: alert type, thresholds, recipients\n- `evaluation_criteria`: evaluation settings per step\n- `governance_policies`: agent-scoped governance policies\n- `dependencies`: knowledge_bases, memory_banks, source_connections, agents, users\n\nQuery params:\n- `download` (default true): when true, sets `Content-Disposition: attachment` so clients treat the response as a file download.\n\nAuth & scoping:\n- Requires `X-API-Key`. You can only export agents belonging to your account.", + "operationId": "export_agent_api_agents__agent_id__export_get", "parameters": [ { "in": "path", @@ -13234,6 +16055,18 @@ "type": "string" } }, + { + "description": "Return as file download", + "in": "query", + "name": "download", + "required": false, + "schema": { + "default": true, + "description": "Return as file download", + "title": "Download", + "type": "boolean" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -13246,7 +16079,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentDefinitionResponse" + "$ref": "#/components/schemas/AgentExportResponse" } } }, @@ -13261,75 +16094,36 @@ } }, "description": "Validation Error" - } - }, - "summary": "Get agent definition", - "tags": [ - "agents" - ] - }, - "put": { - "description": "Update the agent's definition on the main branch.\n\nUses **optimistic locking**: provide `expected_change_id` from the last `GET /agents/{agent_id}/definition`. Returns `409 Conflict` if the definition was modified since your last read.\n\nThe definition contains the agent's step workflow. Step types include `prompt_call`, `retrieval`, `regex_replace`, `gate`, `retry`, `evaluate_step`, `extract_data`, `extract_content`, `add_chat_turn`, `load_chat_history`, `add_memory`, `search_memory`, `load_memory`, `streaming_result`, `send_email`, `webhook_call`, `write_aws_s3_object`, `call_agent`, `write_metadata`, `write_content_attachment`, `load_content_attachment`, `load_content`, `display_result`, `join`, `merge`, `text`, `for_each`, `if_else`, and `switch`. Non-composite step types (`display_result`, `join`, `retry`, `streaming_result`) cannot contain child steps.\n\n**Retry steps** re-execute from a target ancestor step for quality-control loops. Configure with `target_step_id` (ancestor step ID) and `max_retries` (1\u201310). Best practice: place a `gate` step before the retry to make retries conditional.\n\n**if_else** runs `then_steps` when its `conditions` (same shape as `gate`) match, otherwise its optional `else_steps`. Either branch's output flows to the if_else step's own `child_steps` (the post-branch continuation chain).\n\n**switch** dispatches on a `discriminator` template (default `{{input}}`) to the first matching case (equality by default; pass a list in `match` for `$in` semantics) or to `else_steps` when no case matches. Cases own their own `steps` subtrees; the chosen branch's output flows to the switch step's own `child_steps`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only update agents belonging to your account.", - "operationId": "update_agent_definition_api_agents__agent_id__definition_put", - "parameters": [ - { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } }, - { - "$ref": "#/components/parameters/X-Account-Id" - }, - { - "$ref": "#/components/parameters/Seclai-Version" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateAgentDefinitionRequest" - } - } - }, - "required": true - }, - "responses": { - "200": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentDefinitionResponse" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "type": "integer" } } - }, - "description": "Validation Error" + } } }, - "summary": "Update agent definition", + "summary": "Export agent definition", "tags": [ "agents" ] } }, - "/agents/{agent_id}/disable": { - "post": { - "description": "Disable an agent so it stops firing from every trigger path (API runs return 409, inbound email is turned away, scheduled/content triggers are skipped).\n\nReturns **409** with the blocking callers when other live agents still call this one via a `call_agent` step \u2014 disable those first.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token bound to a user (the acting user is recorded); the agent must belong to the key's account.", - "operationId": "disable_agent_api_api_agents__agent_id__disable_post", + "/agents/{agent_id}/input-uploads/{upload_id}": { + "get": { + "description": "Poll the processing status of a file upload created via `POST /agents/{agent_id}/upload-input`.\n\nPossible `status` values: `processing`, `ready`, `failed`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", + "operationId": "api_get_agent_input_upload_status_api_agents__agent_id__input_uploads__upload_id__get", "parameters": [ { "in": "path", @@ -13340,6 +16134,15 @@ "type": "string" } }, + { + "in": "path", + "name": "upload_id", + "required": true, + "schema": { + "title": "Upload Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -13352,7 +16155,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentSummaryResponse" + "$ref": "#/components/schemas/UploadAgentInputApiResponse" } } }, @@ -13367,67 +16170,36 @@ } }, "description": "Validation Error" - } - }, - "summary": "Pause (disable) an agent", - "tags": [ - "agents" - ] - } - }, - "/agents/{agent_id}/enable": { - "post": { - "description": "Re-enable a paused agent (clears the disable state, whether it was paused manually or auto-paused by the inbound-email overload safeguard).\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token bound to a user (the acting user is recorded); the agent must belong to the key's account.", - "operationId": "enable_agent_api_api_agents__agent_id__enable_post", - "parameters": [ - { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } }, - { - "$ref": "#/components/parameters/X-Account-Id" - }, - { - "$ref": "#/components/parameters/Seclai-Version" - } - ], - "responses": { - "200": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentSummaryResponse" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "type": "integer" } } - }, - "description": "Validation Error" + } } }, - "summary": "Resume (enable) a paused agent", + "summary": "Get upload status", "tags": [ "agents" ] } }, - "/agents/{agent_id}/evaluation-criteria": { + "/agents/{agent_id}/runs": { "get": { - "description": "List evaluation criteria configured for an agent.\n\nResponse shape is version-gated by the ``Seclai-Version`` header:\n\n- **Default / legacy** (no header, or a date before ``2026-07-27``): a bare\n JSON array of criteria (unpaginated \u2014 every criterion for the agent).\n- **``Seclai-Version: 2026-07-27`` or later**: the canonical paginated\n envelope ``{data, pagination: {page, limit, total, pages, has_next,\n has_prev}}``.\n\nEach criterion carries its type, configuration, and a summary of results\n(pass / fail counts). Criteria can be filtered client-side by type or\nenabled status.", - "operationId": "list_evaluation_criteria_api_agents__agent_id__evaluation_criteria_get", + "description": "List runs for a specific agent (most recent first), with pagination.\n\nTypical use cases:\n- Build a traces UI for an agent.\n- Debug recent executions and inspect terminal statuses.\n\nNotes:\n- This endpoint returns a summary list. Fetch full details with `GET /agents/runs/{run_id}`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only list runs for agents in your account.", + "operationId": "list_agent_runs_api_agents__agent_id__runs_get", "parameters": [ { "in": "path", @@ -13439,28 +16211,50 @@ } }, { + "description": "Page number", "in": "query", "name": "page", "required": false, "schema": { "default": 1, + "description": "Page number", "minimum": 1, "title": "Page", "type": "integer" } }, { + "description": "Items per page", "in": "query", "name": "limit", "required": false, "schema": { - "default": 20, + "default": 50, + "description": "Items per page", "maximum": 100, "minimum": 1, "title": "Limit", "type": "integer" } }, + { + "description": "Filter runs by status", + "in": "query", + "name": "status", + "required": false, + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/PendingProcessingCompletedFailedStatus" + }, + { + "type": "null" + } + ], + "description": "Filter runs by status", + "title": "Status" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -13473,11 +16267,7 @@ "content": { "application/json": { "schema": { - "items": { - "$ref": "#/components/schemas/EvaluationCriteriaResponse" - }, - "title": "Response List Evaluation Criteria Api Agents Agent Id Evaluation Criteria Get", - "type": "array" + "$ref": "#/components/schemas/routers__api__agents__AgentRunListResponse" } } }, @@ -13492,16 +16282,34 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "List Evaluation Criteria", + "summary": "List agent runs", "tags": [ - "agent-evaluations" + "agents" ] }, "post": { - "description": "Create new step evaluation settings for an agent.\n\nThe evaluation mode, retry settings, and sample frequency are inherited\nfrom the agent and stored on the criteria row for historical reference.", - "operationId": "create_evaluation_criteria_api_agents__agent_id__evaluation_criteria_post", + "description": "Start an agent run.\n\nAn *agent* is an automated workflow that can monitor content from your sources, process it with AI, and trigger actions. This endpoint creates a new run and returns a `run_id` you can poll to retrieve status and output.\n\nWhen to use:\n- Use this endpoint for request/response style integrations where polling is acceptable.\n- Use `POST /agents/{agent_id}/runs/stream` if you need real-time progress via SSE.\n\nKey fields:\n- `input`: text input for agents with a `dynamic_input` trigger.\n- `input_upload_id` / `input_upload_ids`: reference one or more files previously uploaded via `POST /agents/{agent_id}/upload-input`. Send them **with** `input` to pair prompt text with the files (the text leads, each file's extracted text follows); only the two upload fields are mutually exclusive with each other.\n- `priority`: set true for latency-sensitive, user-facing work. For agents with a `streaming_result` step, set `priority=true` to enable real-time token streaming; otherwise the run still proceeds, but without live token streaming.\n- `metadata`: a JSON object that becomes available to agent steps for string substitution.\n\nAfter starting:\n- Poll `GET /agents/runs/{run_id}` until `status` is `completed` or `failed`.\n- Use `include_step_outputs=true` to include per-step outputs, timing, and credits.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", + "operationId": "run_agent_api_agents__agent_id__runs_post", "parameters": [ { "in": "path", @@ -13523,23 +16331,33 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateEvaluationCriteriaRequest" + "$ref": "#/components/schemas/AgentRunRequest" } } }, "required": true }, "responses": { - "201": { + "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EvaluationCriteriaResponse" + "$ref": "#/components/schemas/AgentRunResponse" } } }, "description": "Successful Response" }, + "402": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InsufficientCreditsResponse" + } + } + }, + "description": "Insufficient credits \u2014 the account has exhausted its credits." + }, "422": { "content": { "application/json": { @@ -13549,18 +16367,36 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Create Evaluation Criteria", + "summary": "Run an agent", "tags": [ - "agent-evaluations" + "agents" ] } }, - "/agents/{agent_id}/evaluation-criteria/test-draft": { + "/agents/{agent_id}/runs/stream": { "post": { - "description": "Run an ephemeral evaluation against provided step output without persisting results.\n\nUse this to interactively test evaluation prompts and expectation\nconfigurations while editing criteria. No credits are consumed because\nthe result is not recorded.", - "operationId": "test_draft_evaluation_api_agents__agent_id__evaluation_criteria_test_draft_post", + "description": "Start a **priority** agent run and stream run events using Server-Sent Events (SSE).\n\nThis is the best option for interactive UIs where you want progress updates as the run executes.\n\nHow it works:\n- The first `init` event contains an `AgentRunResponse` snapshot, including the `run_id`.\n- Subsequent events are forwarded from the run event stream (status changes, step events, etc).\n- If the agent contains a `streaming_result` step, `stream_token` events deliver individual LLM tokens (with a `token` field) and a `stream_end` event signals completion.\n- The final `done` event contains the terminal snapshot (including `output` and `credits` when available).\n\nInput options (for `dynamic_input` triggers):\n- `input`: text input passed directly.\n- `input_upload_id` / `input_upload_ids`: reference one or more files uploaded via `POST /agents/{agent_id}/upload-input`. Combine either with `input` to send prompt text alongside the files; only the two upload fields are mutually exclusive with each other.\n\nClient guidance:\n- Keep the connection open and handle keepalive comments.\n- On `timeout` or `error`, the payload includes `run_id` so clients can resume by polling `GET /agents/runs/{run_id}`.\n- `stream_token` events carry the model's raw output. When the agent pairs `streaming_result` with a sibling `extract_content`/`display_result` branch, that branch's `display_result` takes precedence over the stream, so the `done` snapshot's `output` is the validated payload and the tokens are a progress channel \u2014 render tokens live, but read the result from `done`. Check `done.status` first: the streamed text is already the run's output when the stream ends, so a run that FAILED its validation step still carries that raw text in `output`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", + "operationId": "run_streaming_agent_api_agents__agent_id__runs_stream_post", "parameters": [ { "in": "path", @@ -13582,7 +16418,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TestDraftEvaluationRequest" + "$ref": "#/components/schemas/AgentRunStreamRequest" } } }, @@ -13592,12 +16428,26 @@ "200": { "content": { "application/json": { + "schema": {} + }, + "text/event-stream": { + "example": ": keepalive\n\nevent: init\ndata: {\"run_id\":\"...\",\"status\":\"pending\",\"error_count\":0,\"credits\":0.0,\"priority\":true,\"input\":\"...\",\"output\":null,\"attempts\":[]}\n\nevent: done\ndata: {\"run_id\":\"...\",\"status\":\"completed\",\"error_count\":0,\"credits\":0.0,\"priority\":true,\"input\":\"...\",\"output\":\"...\",\"attempts\":[]}\n\n", "schema": { - "$ref": "#/components/schemas/TestDraftEvaluationResponse" + "type": "string" } } }, - "description": "Successful Response" + "description": "Streams agent run events via Server-Sent Events (SSE); run is always created as priority.\n\nSSE events:\n- `event: init` \u2014 `data` is an `AgentRunResponse` snapshot (includes `run_id`).\n- `event: done` \u2014 `data` is the final `AgentRunResponse` snapshot (includes `output`, `credits`, etc).\n- Other events (e.g. `status`, step events) are forwarded from the run event stream.\n- On `timeout` / `error`, the payload includes `run_id` so clients can fetch status via `GET /agents/runs/{run_id}`." + }, + "402": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InsufficientCreditsResponse" + } + } + }, + "description": "Insufficient credits \u2014 the account has exhausted its credits." }, "422": { "content": { @@ -13608,18 +16458,36 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Test Draft Evaluation", + "summary": "Run an agent (stream events)", "tags": [ - "agent-evaluations" + "agents" ] } }, - "/agents/{agent_id}/evaluation-results": { + "/agents/{agent_id}/runs/{run_id}/evaluation-results": { "get": { - "description": "List evaluation results across all criteria configured on an agent.\n\nReturns a paginated list of evaluation results with optional filtering by status, criteria, and date range. Results include score, pass/fail status, and details.", - "operationId": "list_agent_evaluation_results_api_agents__agent_id__evaluation_results_get", + "description": "List evaluation results recorded for a specific agent run.\n\nResponse shape is version-gated by the ``Seclai-Version`` header:\n\n- **Default / legacy** (no header, or a date before ``2026-07-27``): a bare\n JSON array of results (unpaginated \u2014 every result for the run).\n- **``Seclai-Version: 2026-07-27`` or later**: the canonical paginated\n envelope ``{data, pagination: {page, limit, total, pages, has_next,\n has_prev}}``.\n\nResults span all evaluation criteria for the given run, useful for getting a\ncomplete quality snapshot of a single execution.", + "operationId": "list_run_evaluation_results_api_agents__agent_id__runs__run_id__evaluation_results_get", "parameters": [ { "in": "path", @@ -13631,77 +16499,12 @@ } }, { - "in": "query", - "name": "status", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Status" - } - }, - { - "in": "query", - "name": "step", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Step" - } - }, - { - "in": "query", - "name": "flagged_only", - "required": false, - "schema": { - "default": false, - "title": "Flagged Only", - "type": "boolean" - } - }, - { - "in": "query", - "name": "time_from", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Time From" - } - }, - { - "in": "query", - "name": "time_to", - "required": false, + "in": "path", + "name": "run_id", + "required": true, "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Time To" + "title": "Run Id", + "type": "string" } }, { @@ -13739,7 +16542,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EvaluationResultWithCriteriaListResponse" + "items": { + "$ref": "#/components/schemas/EvaluationResultWithCriteriaResponse" + }, + "title": "Response List Run Evaluation Results Api Agents Agent Id Runs Run Id Evaluation Results Get", + "type": "array" } } }, @@ -13754,113 +16561,53 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "List Agent Evaluation Results", + "summary": "List Run Evaluation Results", "tags": [ "agent-evaluations" ] } }, - "/agents/{agent_id}/evaluation-runs": { - "get": { - "description": "List evaluation results grouped by agent run.\n\nReturns paginated per-run summaries with pass/fail counts and optional\nfiltering by evaluation outcome, step, or date range.", - "operationId": "list_evaluation_runs_api_agents__agent_id__evaluation_runs_get", - "parameters": [ - { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } - }, - { - "in": "query", - "name": "status", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Status" - } - }, - { - "in": "query", - "name": "step", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Step" - } - }, - { - "in": "query", - "name": "time_from", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Time From" - } - }, - { - "in": "query", - "name": "time_to", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Time To" - } - }, + "/agents/{agent_id}/triggers/{trigger_id}/email-config": { + "put": { + "description": "Set the custom alias, sender allowlist, and inbound-handling flags (`ignore_auto_generated`, `require_sender_auth`, `queue_on_quota`) on an agent's EMAIL_RECEIVED trigger, and return its computed email address(es). Omitted fields are left unchanged.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; the trigger must belong to an agent in the key's account.", + "operationId": "set_email_trigger_config_api_api_agents__agent_id__triggers__trigger_id__email_config_put", + "parameters": [ { - "in": "query", - "name": "page", - "required": false, + "in": "path", + "name": "agent_id", + "required": true, "schema": { - "default": 1, - "minimum": 1, - "title": "Page", - "type": "integer" + "title": "Agent Id", + "type": "string" } }, { - "in": "query", - "name": "limit", - "required": false, + "in": "path", + "name": "trigger_id", + "required": true, "schema": { - "default": 20, - "maximum": 100, - "minimum": 1, - "title": "Limit", - "type": "integer" + "title": "Trigger Id", + "type": "string" } }, { @@ -13870,12 +16617,22 @@ "$ref": "#/components/parameters/Seclai-Version" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__agents__SetEmailTriggerConfigRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EvaluationRunSummaryListResponse" + "$ref": "#/components/schemas/EmailTriggerConfigResponse" } } }, @@ -13890,18 +16647,36 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "List Evaluation Runs", + "summary": "Configure an EMAIL_RECEIVED trigger", "tags": [ - "agent-evaluations" + "agents" ] } }, - "/agents/{agent_id}/export": { - "get": { - "description": "Export an agent definition as a portable JSON snapshot.\n\nThe response contains the full definition, trigger configuration with schedules, alert configs, evaluation criteria, agent-scoped governance policies, and a resolved dependency manifest that maps every referenced external entity UUID to its human-readable name.\n\nResponse shape:\n- `export_version`: schema version (currently `\"2\"`)\n- `exported_at`: ISO-8601 timestamp\n- `agent`: name, description, schema_version, definition, timestamps\n- `trigger`: trigger type, input template, schedules\n- `alert_configs`: alert type, thresholds, recipients\n- `evaluation_criteria`: evaluation settings per step\n- `governance_policies`: agent-scoped governance policies\n- `dependencies`: knowledge_bases, memory_banks, source_connections, agents, users\n\nQuery params:\n- `download` (default true): when true, sets `Content-Disposition: attachment` so clients treat the response as a file download.\n\nAuth & scoping:\n- Requires `X-API-Key`. You can only export agents belonging to your account.", - "operationId": "export_agent_api_agents__agent_id__export_get", + "/agents/{agent_id}/upload-input": { + "post": { + "description": "Upload a file to use as input for a `dynamic_input` agent run.\n\nSupports the same file types as content source uploads: text, PDF, DOCX, audio, video, images, etc. Text and document files are processed synchronously; audio/video are submitted for asynchronous transcription.\n\n**Size limit:** 200 MB per file.\n\n**Supported extensions:** txt, html, md, csv, xml, json, pdf, msg, docx, doc, pptx, ppt, xlsx, xls, zip, epub, png, jpg, gif, bmp, tiff, webp, mp3, wav, m4a, flac, ogg, mp4, mov, avi.\n\nAfter uploading, poll `GET /agents/{agent_id}/input-uploads/{upload_id}` until `status` is `ready`, then pass `input_upload_id` to `POST /agents/{agent_id}/runs`.\n\n**Multi-modal routing:** non-text uploads (image, audio, video, PDF) are surfaced natively to multi-modal-capable prompt steps; text-only models fall back to the OCR / transcript text counterpart. Audio originals are preserved past transcription so audio-capable models (Gemini 2.5/3, GPT-5 audio) read them directly; the agent-input-binary janitor sweeps originals once they pass your account's agent-trace retention (the agent-traces source's retention period; free default 7 days).\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", + "operationId": "api_upload_agent_input_api_agents__agent_id__upload_input_post", "parameters": [ { "in": "path", @@ -13913,17 +16688,63 @@ } }, { - "description": "Return as file download", - "in": "query", - "name": "download", - "required": false, - "schema": { - "default": true, - "description": "Return as file download", - "title": "Download", - "type": "boolean" - } + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadAgentInputApiResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Upload file input", + "tags": [ + "agents" + ] + } + }, + "/ai-assistant/feedback": { + "post": { + "description": "Submit thumbs-up/down feedback on any AI assistant interaction. Negative feedback with a comment is analyzed for concerning issues.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", + "operationId": "api_ai_feedback_api_ai_assistant_feedback_post", + "parameters": [ { "$ref": "#/components/parameters/X-Account-Id" }, @@ -13931,12 +16752,22 @@ "$ref": "#/components/parameters/Seclai-Version" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__ai_assistant__AiAssistantFeedbackRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentExportResponse" + "$ref": "#/components/schemas/AiAssistantFeedbackResponse" } } }, @@ -13951,37 +16782,105 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Export agent definition", + "summary": "Submit AI assistant feedback", "tags": [ - "agents" + "ai-assistant" ] } }, - "/agents/{agent_id}/input-uploads/{upload_id}": { - "get": { - "description": "Poll the processing status of a file upload created via `POST /agents/{agent_id}/upload-input`.\n\nPossible `status` values: `processing`, `ready`, `failed`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", - "operationId": "api_get_agent_input_upload_status_api_agents__agent_id__input_uploads__upload_id__get", + "/ai-assistant/knowledge-base": { + "post": { + "description": "Generate a knowledge base creation/modification plan without requiring an existing solution. May also propose prerequisite source creation actions.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", + "operationId": "api_ai_knowledge_base_api_ai_assistant_knowledge_base_post", "parameters": [ { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } + "$ref": "#/components/parameters/X-Account-Id" }, { - "in": "path", - "name": "upload_id", - "required": true, - "schema": { - "title": "Upload Id", - "type": "string" + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__solutions__AiAssistantGenerateRequest" + } } }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AiAssistantGenerateResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Generate a knowledge base plan (standalone)", + "tags": [ + "ai-assistant" + ] + } + }, + "/ai-assistant/memory-bank": { + "post": { + "description": "Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, mode, compaction prompt, and retention settings.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", + "operationId": "api_ai_memory_bank_api_ai_assistant_memory_bank_post", + "parameters": [ { "$ref": "#/components/parameters/X-Account-Id" }, @@ -13989,12 +16888,22 @@ "$ref": "#/components/parameters/Seclai-Version" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__memory_banks__MemoryBankAiAssistantRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UploadAgentInputApiResponse" + "$ref": "#/components/schemas/MemoryBankAiAssistantResponse" } } }, @@ -14007,73 +16916,64 @@ "$ref": "#/components/schemas/HTTPValidationError" } } - }, - "description": "Validation Error" + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Get upload status", + "summary": "Generate a memory bank configuration (standalone)", "tags": [ - "agents" + "ai-assistant" ] } }, - "/agents/{agent_id}/runs": { + "/ai-assistant/memory-bank/last-conversation": { "get": { - "description": "List runs for a specific agent (most recent first), with pagination.\n\nTypical use cases:\n- Build a traces UI for an agent.\n- Debug recent executions and inspect terminal statuses.\n\nNotes:\n- This endpoint returns a summary list. Fetch full details with `GET /agents/runs/{run_id}`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only list runs for agents in your account.", - "operationId": "list_agent_runs_api_agents__agent_id__runs_get", + "description": "Fetch the most recent memory bank AI assistant conversation turns for the authenticated user. Returns turns in oldest-first order with a total count for pagination via limit/offset query parameters.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", + "operationId": "api_ai_memory_bank_history_api_ai_assistant_memory_bank_last_conversation_get", "parameters": [ { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "required": false, - "schema": { - "default": 1, - "description": "Page number", - "minimum": 1, - "title": "Page", - "type": "integer" - } - }, - { - "description": "Items per page", + "description": "Max turns.", "in": "query", "name": "limit", "required": false, "schema": { - "default": 50, - "description": "Items per page", - "maximum": 100, + "default": 5, + "description": "Max turns.", + "maximum": 50, "minimum": 1, "title": "Limit", "type": "integer" } }, { - "description": "Filter runs by status", + "description": "Skip count.", "in": "query", - "name": "status", + "name": "offset", "required": false, "schema": { - "anyOf": [ - { - "$ref": "#/components/schemas/PendingProcessingCompletedFailedStatus" - }, - { - "type": "null" - } - ], - "description": "Filter runs by status", - "title": "Status" + "default": 0, + "description": "Skip count.", + "minimum": 0, + "title": "Offset", + "type": "integer" } }, { @@ -14088,7 +16988,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__agents__AgentRunListResponse" + "$ref": "#/components/schemas/routers__api__memory_banks__MemoryBankLastConversationResponse" } } }, @@ -14103,23 +17003,44 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "List agent runs", + "summary": "Fetch memory bank AI conversation history", "tags": [ - "agents" + "ai-assistant" ] - }, - "post": { - "description": "Start an agent run.\n\nAn *agent* is an automated workflow that can monitor content from your sources, process it with AI, and trigger actions. This endpoint creates a new run and returns a `run_id` you can poll to retrieve status and output.\n\nWhen to use:\n- Use this endpoint for request/response style integrations where polling is acceptable.\n- Use `POST /agents/{agent_id}/runs/stream` if you need real-time progress via SSE.\n\nKey fields:\n- `input`: text input for agents with a `dynamic_input` trigger.\n- `input_upload_id`: alternatively, reference a file previously uploaded via `POST /agents/{agent_id}/upload-input` (mutually exclusive with `input`).\n- `priority`: set true for latency-sensitive, user-facing work. For agents with a `streaming_result` step, set `priority=true` to enable real-time token streaming; otherwise the run still proceeds, but without live token streaming.\n- `metadata`: a JSON object that becomes available to agent steps for string substitution.\n\nAfter starting:\n- Poll `GET /agents/runs/{run_id}` until `status` is `completed` or `failed`.\n- Use `include_step_outputs=true` to include per-step outputs, timing, and credits.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", - "operationId": "run_agent_api_agents__agent_id__runs_post", + } + }, + "/ai-assistant/memory-bank/{conversation_id}": { + "patch": { + "description": "Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to true to accept the proposed configuration, or false to decline it. The accepted status is recorded for audit purposes.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", + "operationId": "api_ai_memory_bank_accept_api_ai_assistant_memory_bank__conversation_id__patch", "parameters": [ { "in": "path", - "name": "agent_id", + "name": "conversation_id", "required": true, "schema": { - "title": "Agent Id", + "format": "uuid", + "title": "Conversation Id", "type": "string" } }, @@ -14134,7 +17055,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentRunRequest" + "$ref": "#/components/schemas/routers__api__memory_banks__MemoryBankAcceptRequest" } } }, @@ -14145,53 +17066,52 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentRunResponse" + "$ref": "#/components/schemas/OkResponse" } } }, "description": "Successful Response" }, - "402": { + "422": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/InsufficientCreditsResponse" + "$ref": "#/components/schemas/HTTPValidationError" } } }, - "description": "Insufficient credits \u2014 the account has exhausted its credits." + "description": "Validation Error" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Run an agent", + "summary": "Accept or decline a memory bank AI suggestion", "tags": [ - "agents" + "ai-assistant" ] } }, - "/agents/{agent_id}/runs/stream": { + "/ai-assistant/solution": { "post": { - "description": "Start a **priority** agent run and stream run events using Server-Sent Events (SSE).\n\nThis is the best option for interactive UIs where you want progress updates as the run executes.\n\nHow it works:\n- The first `init` event contains an `AgentRunResponse` snapshot, including the `run_id`.\n- Subsequent events are forwarded from the run event stream (status changes, step events, etc).\n- If the agent contains a `streaming_result` step, `stream_token` events deliver individual LLM tokens (with a `token` field) and a `stream_end` event signals completion.\n- The final `done` event contains the terminal snapshot (including `output` and `credits` when available).\n\nInput options (for `dynamic_input` triggers):\n- `input`: text input passed directly.\n- `input_upload_id`: reference a file uploaded via `POST /agents/{agent_id}/upload-input` (mutually exclusive with `input`).\n\nClient guidance:\n- Keep the connection open and handle keepalive comments.\n- On `timeout` or `error`, the payload includes `run_id` so clients can resume by polling `GET /agents/runs/{run_id}`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", - "operationId": "run_streaming_agent_api_agents__agent_id__runs_stream_post", + "description": "Generate a complete solution plan covering sources, knowledge bases, and agents without requiring an existing solution. Supports SSE streaming when ``Accept: text/event-stream`` is set.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", + "operationId": "api_ai_solution_api_ai_assistant_solution_post", "parameters": [ - { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -14203,7 +17123,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AgentRunStreamRequest" + "$ref": "#/components/schemas/routers__api__solutions__AiAssistantGenerateRequest" } } }, @@ -14211,28 +17131,14 @@ }, "responses": { "200": { - "content": { - "application/json": { - "schema": {} - }, - "text/event-stream": { - "example": ": keepalive\n\nevent: init\ndata: {\"run_id\":\"...\",\"status\":\"pending\",\"error_count\":0,\"credits\":0.0,\"priority\":true,\"input\":\"...\",\"output\":null,\"attempts\":[]}\n\nevent: done\ndata: {\"run_id\":\"...\",\"status\":\"completed\",\"error_count\":0,\"credits\":0.0,\"priority\":true,\"input\":\"...\",\"output\":\"...\",\"attempts\":[]}\n\n", - "schema": { - "type": "string" - } - } - }, - "description": "Streams agent run events via Server-Sent Events (SSE); run is always created as priority.\n\nSSE events:\n- `event: init` \u2014 `data` is an `AgentRunResponse` snapshot (includes `run_id`).\n- `event: done` \u2014 `data` is the final `AgentRunResponse` snapshot (includes `output`, `credits`, etc).\n- Other events (e.g. `status`, step events) are forwarded from the run event stream.\n- On `timeout` / `error`, the payload includes `run_id` so clients can fetch status via `GET /agents/runs/{run_id}`." - }, - "402": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/InsufficientCreditsResponse" + "$ref": "#/components/schemas/AiAssistantGenerateResponse" } } }, - "description": "Insufficient credits \u2014 the account has exhausted its credits." + "description": "Successful Response" }, "422": { "content": { @@ -14243,122 +17149,37 @@ } }, "description": "Validation Error" - } - }, - "summary": "Run an agent (stream events)", - "tags": [ - "agents" - ] - } - }, - "/agents/{agent_id}/runs/{run_id}/evaluation-results": { - "get": { - "description": "List evaluation results recorded for a specific agent run.\n\nResponse shape is version-gated by the ``Seclai-Version`` header:\n\n- **Default / legacy** (no header, or a date before ``2026-07-27``): a bare\n JSON array of results (unpaginated \u2014 every result for the run).\n- **``Seclai-Version: 2026-07-27`` or later**: the canonical paginated\n envelope ``{data, pagination: {page, limit, total, pages, has_next,\n has_prev}}``.\n\nResults span all evaluation criteria for the given run, useful for getting a\ncomplete quality snapshot of a single execution.", - "operationId": "list_run_evaluation_results_api_agents__agent_id__runs__run_id__evaluation_results_get", - "parameters": [ - { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } - }, - { - "in": "path", - "name": "run_id", - "required": true, - "schema": { - "title": "Run Id", - "type": "string" - } - }, - { - "in": "query", - "name": "page", - "required": false, - "schema": { - "default": 1, - "minimum": 1, - "title": "Page", - "type": "integer" - } - }, - { - "in": "query", - "name": "limit", - "required": false, - "schema": { - "default": 20, - "maximum": 100, - "minimum": 1, - "title": "Limit", - "type": "integer" - } - }, - { - "$ref": "#/components/parameters/X-Account-Id" }, - { - "$ref": "#/components/parameters/Seclai-Version" - } - ], - "responses": { - "200": { + "503": { "content": { "application/json": { "schema": { - "items": { - "$ref": "#/components/schemas/EvaluationResultWithCriteriaResponse" - }, - "title": "Response List Run Evaluation Results Api Agents Agent Id Runs Run Id Evaluation Results Get", - "type": "array" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "type": "integer" } } - }, - "description": "Validation Error" + } } }, - "summary": "List Run Evaluation Results", + "summary": "Generate a solution plan (standalone)", "tags": [ - "agent-evaluations" + "ai-assistant" ] - } - }, - "/agents/{agent_id}/triggers/{trigger_id}/email-config": { - "put": { - "description": "Set the custom alias, sender allowlist, and inbound-handling flags (`ignore_auto_generated`, `require_sender_auth`, `queue_on_quota`) on an agent's EMAIL_RECEIVED trigger, and return its computed email address(es). Omitted fields are left unchanged.\n\nAuth & scoping: requires `X-API-Key` header or OAuth Bearer token; the trigger must belong to an agent in the key's account.", - "operationId": "set_email_trigger_config_api_api_agents__agent_id__triggers__trigger_id__email_config_put", - "parameters": [ - { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } - }, - { - "in": "path", - "name": "trigger_id", - "required": true, - "schema": { - "title": "Trigger Id", - "type": "string" - } - }, + } + }, + "/ai-assistant/source": { + "post": { + "description": "Generate a content source creation/modification plan without requiring an existing solution. The AI proposes actions for the user to review before any changes are made.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", + "operationId": "api_ai_source_api_ai_assistant_source_post", + "parameters": [ { "$ref": "#/components/parameters/X-Account-Id" }, @@ -14370,7 +17191,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__agents__SetEmailTriggerConfigRequest" + "$ref": "#/components/schemas/routers__api__solutions__AiAssistantGenerateRequest" } } }, @@ -14381,7 +17202,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTriggerConfigResponse" + "$ref": "#/components/schemas/AiAssistantGenerateResponse" } } }, @@ -14396,68 +17217,47 @@ } }, "description": "Validation Error" - } - }, - "summary": "Configure an EMAIL_RECEIVED trigger", - "tags": [ - "agents" - ] - } - }, - "/agents/{agent_id}/upload-input": { - "post": { - "description": "Upload a file to use as input for a `dynamic_input` agent run.\n\nSupports the same file types as content source uploads: text, PDF, DOCX, audio, video, images, etc. Text and document files are processed synchronously; audio/video are submitted for asynchronous transcription.\n\n**Size limit:** 200 MB per file.\n\n**Supported extensions:** txt, html, md, csv, xml, json, pdf, msg, docx, doc, pptx, ppt, xlsx, xls, zip, epub, png, jpg, gif, bmp, tiff, webp, mp3, wav, m4a, flac, ogg, mp4, mov, avi.\n\nAfter uploading, poll `GET /agents/{agent_id}/input-uploads/{upload_id}` until `status` is `ready`, then pass `input_upload_id` to `POST /agents/{agent_id}/runs`.\n\n**Multi-modal routing:** non-text uploads (image, audio, video, PDF) are surfaced natively to multi-modal-capable prompt steps; text-only models fall back to the OCR / transcript text counterpart. Audio originals are preserved past transcription so audio-capable models (Gemini 2.5/3, GPT-5 audio) read them directly; the agent-input-binary janitor sweeps originals once they pass your account's agent-trace retention (the agent-traces source's retention period; free default 7 days).\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.", - "operationId": "api_upload_agent_input_api_agents__agent_id__upload_input_post", - "parameters": [ - { - "in": "path", - "name": "agent_id", - "required": true, - "schema": { - "title": "Agent Id", - "type": "string" - } }, - { - "$ref": "#/components/parameters/X-Account-Id" - }, - { - "$ref": "#/components/parameters/Seclai-Version" - } - ], - "responses": { - "202": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UploadAgentInputApiResponse" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Successful Response" - }, - "422": { - "content": { - "application/json": { + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "type": "integer" } } - }, - "description": "Validation Error" + } } }, - "summary": "Upload file input", + "summary": "Generate a source plan (standalone)", "tags": [ - "agents" + "ai-assistant" ] } }, - "/ai-assistant/feedback": { + "/ai-assistant/{conversation_id}/accept": { "post": { - "description": "Submit thumbs-up/down feedback on any AI assistant interaction. Negative feedback with a comment is analyzed for concerning issues.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", - "operationId": "api_ai_feedback_api_ai_assistant_feedback_post", + "description": "Accept and execute a previously proposed standalone plan. If the plan contains destructive actions (deletions), ``confirm_deletions`` must be set to true.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", + "operationId": "api_ai_accept_api_ai_assistant__conversation_id__accept_post", "parameters": [ + { + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "format": "uuid", + "title": "Conversation Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -14469,7 +17269,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__ai_assistant__AiAssistantFeedbackRequest" + "$ref": "#/components/schemas/routers__api__solutions__AiAssistantAcceptRequest" } } }, @@ -14480,7 +17280,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AiAssistantFeedbackResponse" + "$ref": "#/components/schemas/AiAssistantAcceptResponse" } } }, @@ -14495,19 +17295,47 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Submit AI assistant feedback", + "summary": "Accept and execute a standalone plan", "tags": [ "ai-assistant" ] } }, - "/ai-assistant/knowledge-base": { + "/ai-assistant/{conversation_id}/decline": { "post": { - "description": "Generate a knowledge base creation/modification plan without requiring an existing solution. May also propose prerequisite source creation actions.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", - "operationId": "api_ai_knowledge_base_api_ai_assistant_knowledge_base_post", + "description": "Decline a previously proposed standalone plan. No resources are modified. The conversation is marked as declined.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", + "operationId": "api_ai_decline_api_ai_assistant__conversation_id__decline_post", "parameters": [ + { + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "format": "uuid", + "title": "Conversation Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -14515,49 +17343,169 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/routers__api__solutions__AiAssistantGenerateRequest" - } - } - }, - "required": true - }, "responses": { - "200": { + "204": { + "description": "Successful Response" + }, + "422": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AiAssistantGenerateResponse" + "$ref": "#/components/schemas/HTTPValidationError" } } }, - "description": "Successful Response" + "description": "Validation Error" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Generate a knowledge base plan (standalone)", + "summary": "Decline a standalone plan", "tags": [ "ai-assistant" ] } }, - "/ai-assistant/memory-bank": { - "post": { - "description": "Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, mode, compaction prompt, and retention settings.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", - "operationId": "api_ai_memory_bank_api_ai_assistant_memory_bank_post", + "/alerts": { + "get": { + "description": "List alerts for the account with optional filters.\n\nFilters:\n- `status`: triggered, acknowledged, resolved, dismissed\n- `agent_id`: filter by agent\n- `source_connection_id`: filter by source\n- `time_from` / `time_to`: ISO 8601 date range\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Results are scoped to the caller's account.", + "operationId": "list_alerts_api_alerts_get", "parameters": [ + { + "description": "Page number", + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "description": "Page number", + "minimum": 1, + "title": "Page", + "type": "integer" + } + }, + { + "description": "Items per page", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 20, + "description": "Items per page", + "maximum": 100, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "description": "Filter by alert status", + "in": "query", + "name": "status", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by alert status", + "title": "Status" + } + }, + { + "description": "Filter by agent ID", + "in": "query", + "name": "agent_id", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by agent ID", + "title": "Agent Id" + } + }, + { + "description": "Filter by source connection ID", + "in": "query", + "name": "source_connection_id", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by source connection ID", + "title": "Source Connection Id" + } + }, + { + "description": "From (ISO 8601)", + "in": "query", + "name": "time_from", + "required": false, + "schema": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "From (ISO 8601)", + "title": "Time From" + } + }, + { + "description": "To (ISO 8601)", + "in": "query", + "name": "time_to", + "required": false, + "schema": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "To (ISO 8601)", + "title": "Time To" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -14565,22 +17513,12 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/routers__api__memory_banks__MemoryBankAiAssistantRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/MemoryBankAiAssistantResponse" + "$ref": "#/components/schemas/routers__api__alerts__AlertListResponse" } } }, @@ -14595,43 +17533,115 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Generate a memory bank configuration (standalone)", + "summary": "List alerts", "tags": [ - "ai-assistant" + "alerts" ] } }, - "/ai-assistant/memory-bank/last-conversation": { + "/alerts/configs": { "get": { - "description": "Fetch the most recent memory bank AI assistant conversation turns for the authenticated user. Returns turns in oldest-first order with a total count for pagination via limit/offset query parameters.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", - "operationId": "api_ai_memory_bank_history_api_ai_assistant_memory_bank_last_conversation_get", + "description": "List alert configurations.\n\nFilters:\n- `agent_id`: list configs for a specific agent\n- `source_connection_id`: list configs for a specific source\n- Neither: list account-level agent alert configs\n- `scope=source`: list account-level source alert configs\n\nCredits alerts (`credits_low_threshold`, `credits_runout_prediction`, `credits_usage_spike`) are account-level alert configs. They are evaluated by the credits alert sweep and default-enabled configs may be auto-created for active accounts at runtime.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "list_alert_configs_api_alerts_configs_get", "parameters": [ { - "description": "Max turns.", + "description": "Filter by agent ID", "in": "query", - "name": "limit", + "name": "agent_id", "required": false, "schema": { - "default": 5, - "description": "Max turns.", - "maximum": 50, + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by agent ID", + "title": "Agent Id" + } + }, + { + "description": "Filter by source connection ID", + "in": "query", + "name": "source_connection_id", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by source connection ID", + "title": "Source Connection Id" + } + }, + { + "description": "Set to 'source' to list account-level source alert configs", + "in": "query", + "name": "scope", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Set to 'source' to list account-level source alert configs", + "title": "Scope" + } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "description": "Page number", "minimum": 1, - "title": "Limit", + "title": "Page", "type": "integer" } }, { - "description": "Skip count.", + "description": "Items per page", "in": "query", - "name": "offset", + "name": "limit", "required": false, "schema": { - "default": 0, - "description": "Skip count.", - "minimum": 0, - "title": "Offset", + "default": 50, + "description": "Items per page", + "maximum": 100, + "minimum": 1, + "title": "Limit", "type": "integer" } }, @@ -14647,7 +17657,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__memory_banks__MemoryBankLastConversationResponse" + "$ref": "#/components/schemas/AlertConfigListResponse" } } }, @@ -14662,29 +17672,35 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Fetch memory bank AI conversation history", + "summary": "List alert configs", "tags": [ - "ai-assistant" + "alerts" ] - } - }, - "/ai-assistant/memory-bank/{conversation_id}": { - "patch": { - "description": "Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to true to accept the proposed configuration, or false to decline it. The accepted status is recorded for audit purposes.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", - "operationId": "api_ai_memory_bank_accept_api_ai_assistant_memory_bank__conversation_id__patch", + }, + "post": { + "description": "Create a new alert configuration.\n\nAgent alert types: run_failed, consecutive_failures, error_rate_spike, run_burst, slow_run, credits_low_threshold, credits_runout_prediction, credits_usage_spike, non_manual_eval_failed, non_manual_eval_flagged, governance_flagged, governance_blocked, model_newer_available, model_deprecated, model_sunset.\nSource alert types: pull_failed, consecutive_pull_failures, pull_error_rate_spike.\n\nDistribution types: owner, owner_admins, selected_members. Organization accounts are normalized to owner_admins.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "create_alert_config_api_alerts_configs_post", "parameters": [ - { - "in": "path", - "name": "conversation_id", - "required": true, - "schema": { - "format": "uuid", - "title": "Conversation Id", - "type": "string" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -14696,18 +17712,18 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__memory_banks__MemoryBankAcceptRequest" + "$ref": "#/components/schemas/CreateAlertConfigRequest" } } }, "required": true }, "responses": { - "200": { + "201": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/OkResponse" + "$ref": "#/components/schemas/AlertConfigResponse" } } }, @@ -14722,19 +17738,46 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Accept or decline a memory bank AI suggestion", + "summary": "Create alert config", "tags": [ - "ai-assistant" + "alerts" ] } }, - "/ai-assistant/solution": { - "post": { - "description": "Generate a complete solution plan covering sources, knowledge bases, and agents without requiring an existing solution. Supports SSE streaming when ``Accept: text/event-stream`` is set.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", - "operationId": "api_ai_solution_api_ai_assistant_solution_post", + "/alerts/configs/{config_id}": { + "delete": { + "description": "Delete an alert configuration. This permanently removes the config and stops any future alerts of this type from being triggered.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "delete_alert_config_api_alerts_configs__config_id__delete", "parameters": [ + { + "in": "path", + "name": "config_id", + "required": true, + "schema": { + "title": "Config Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -14742,49 +17785,57 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/routers__api__solutions__AiAssistantGenerateRequest" - } - } - }, - "required": true - }, "responses": { - "200": { + "204": { + "description": "Successful Response" + }, + "422": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AiAssistantGenerateResponse" + "$ref": "#/components/schemas/HTTPValidationError" } } }, - "description": "Successful Response" + "description": "Validation Error" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Generate a solution plan (standalone)", + "summary": "Delete alert config", "tags": [ - "ai-assistant" + "alerts" ] - } - }, - "/ai-assistant/source": { - "post": { - "description": "Generate a content source creation/modification plan without requiring an existing solution. The AI proposes actions for the user to review before any changes are made.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", - "operationId": "api_ai_source_api_ai_assistant_source_post", + }, + "get": { + "description": "Get a specific alert configuration by ID.\n\nReturns all fields including type, enabled state, threshold, cooldown, distribution type, and recipient list.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "get_alert_config_api_alerts_configs__config_id__get", "parameters": [ + { + "in": "path", + "name": "config_id", + "required": true, + "schema": { + "title": "Config Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -14792,22 +17843,12 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/routers__api__solutions__AiAssistantGenerateRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AiAssistantGenerateResponse" + "$ref": "#/components/schemas/AlertConfigResponse" } } }, @@ -14822,26 +17863,41 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Generate a source plan (standalone)", + "summary": "Get alert config", "tags": [ - "ai-assistant" + "alerts" ] - } - }, - "/ai-assistant/{conversation_id}/accept": { - "post": { - "description": "Accept and execute a previously proposed standalone plan. If the plan contains destructive actions (deletions), ``confirm_deletions`` must be set to true.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", - "operationId": "api_ai_accept_api_ai_assistant__conversation_id__accept_post", + }, + "patch": { + "description": "Update an alert configuration. Only provided fields are updated.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "update_alert_config_api_alerts_configs__config_id__patch", "parameters": [ { "in": "path", - "name": "conversation_id", + "name": "config_id", "required": true, "schema": { - "format": "uuid", - "title": "Conversation Id", + "title": "Config Id", "type": "string" } }, @@ -14856,7 +17912,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__solutions__AiAssistantAcceptRequest" + "$ref": "#/components/schemas/UpdateAlertConfigRequest" } } }, @@ -14867,7 +17923,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AiAssistantAcceptResponse" + "$ref": "#/components/schemas/AlertConfigResponse" } } }, @@ -14882,27 +17938,66 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Accept and execute a standalone plan", + "summary": "Update alert config", "tags": [ - "ai-assistant" + "alerts" ] } }, - "/ai-assistant/{conversation_id}/decline": { - "post": { - "description": "Decline a previously proposed standalone plan. No resources are modified. The conversation is marked as declined.\n\nAuth: requires ``X-API-Key`` header or OAuth Bearer token.", - "operationId": "api_ai_decline_api_ai_assistant__conversation_id__decline_post", + "/alerts/organization-preferences/list": { + "get": { + "description": "List per-organization alert delivery preferences for the authenticated user.\n\nBy default, only explicit override rows are returned. Set `include_defaults=true` to return the effective subscribed state for every alert type in every organization the user can manage.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.\n- Only organizations where the user is an owner or administrator are included.", + "operationId": "list_organization_preferences_api_alerts_organization_preferences_list_get", "parameters": [ { - "in": "path", - "name": "conversation_id", - "required": true, + "description": "Optional organization filter", + "in": "query", + "name": "organization_id", + "required": false, "schema": { - "format": "uuid", - "title": "Conversation Id", - "type": "string" + "anyOf": [ + { + "format": "uuid", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional organization filter", + "title": "Organization Id" + } + }, + { + "description": "Include default subscribed entries for all alert types", + "in": "query", + "name": "include_defaults", + "required": false, + "schema": { + "default": false, + "description": "Include default subscribed entries for all alert types", + "title": "Include Defaults", + "type": "boolean" } }, { @@ -14913,7 +18008,14 @@ } ], "responses": { - "204": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OrganizationAlertPreferenceListResponse" + } + } + }, "description": "Successful Response" }, "422": { @@ -14925,136 +18027,131 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Decline a standalone plan", + "summary": "List organization alert delivery preferences", "tags": [ - "ai-assistant" + "alerts" ] } }, - "/alerts": { - "get": { - "description": "List alerts for the account with optional filters.\n\nFilters:\n- `status`: triggered, acknowledged, resolved, dismissed\n- `agent_id`: filter by agent\n- `source_connection_id`: filter by source\n- `time_from` / `time_to`: ISO 8601 date range\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Results are scoped to the caller's account.", - "operationId": "list_alerts_api_alerts_get", + "/alerts/organization-preferences/{organization_id}/{alert_type}": { + "patch": { + "description": "Update the authenticated user's personal delivery preference for one alert type in one organization.\n\nSetting `subscribed=false` stores an explicit opt-out override. Setting `subscribed=true` removes the override and restores the default subscribed behavior.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.\n- Only owners and administrators can update preferences for an organization.", + "operationId": "update_organization_preference_api_alerts_organization_preferences__organization_id___alert_type__patch", "parameters": [ { - "description": "Page number", - "in": "query", - "name": "page", - "required": false, + "in": "path", + "name": "organization_id", + "required": true, "schema": { - "default": 1, - "description": "Page number", - "minimum": 1, - "title": "Page", - "type": "integer" + "format": "uuid", + "title": "Organization Id", + "type": "string" } }, { - "description": "Items per page", - "in": "query", - "name": "limit", - "required": false, + "in": "path", + "name": "alert_type", + "required": true, "schema": { - "default": 20, - "description": "Items per page", - "maximum": 100, - "minimum": 1, - "title": "Limit", - "type": "integer" + "title": "Alert Type", + "type": "string" } }, { - "description": "Filter by alert status", - "in": "query", - "name": "status", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Filter by alert status", - "title": "Status" - } + "$ref": "#/components/parameters/X-Account-Id" }, { - "description": "Filter by agent ID", - "in": "query", - "name": "agent_id", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Filter by agent ID", - "title": "Agent Id" + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__alerts__UpdateOrganizationAlertPreferenceRequest" + } } }, - { - "description": "Filter by source connection ID", - "in": "query", - "name": "source_connection_id", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__alerts__OrganizationAlertPreferenceResponse" } - ], - "description": "Filter by source connection ID", - "title": "Source Connection Id" - } + } + }, + "description": "Successful Response" }, - { - "description": "From (ISO 8601)", - "in": "query", - "name": "time_from", - "required": false, - "schema": { - "anyOf": [ - { - "format": "date-time", - "type": "string" - }, - { - "type": "null" + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" } - ], - "description": "From (ISO 8601)", - "title": "Time From" + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } } - }, + } + }, + "summary": "Update organization alert delivery preference", + "tags": [ + "alerts" + ] + } + }, + "/alerts/{alert_id}": { + "get": { + "description": "Get full alert detail including history, comments, and subscribers.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "get_alert_detail_api_alerts__alert_id__get", + "parameters": [ { - "description": "To (ISO 8601)", - "in": "query", - "name": "time_to", - "required": false, + "in": "path", + "name": "alert_id", + "required": true, "schema": { - "anyOf": [ - { - "format": "date-time", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "To (ISO 8601)", - "title": "Time To" + "title": "Alert Id", + "type": "string" } }, { @@ -15069,7 +18166,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__alerts__AlertListResponse" + "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" } } }, @@ -15084,98 +18181,44 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "List alerts", + "summary": "Get alert detail", "tags": [ "alerts" ] } }, - "/alerts/configs": { - "get": { - "description": "List alert configurations.\n\nFilters:\n- `agent_id`: list configs for a specific agent\n- `source_connection_id`: list configs for a specific source\n- Neither: list account-level agent alert configs\n- `scope=source`: list account-level source alert configs\n\nCredits alerts (`credits_low_threshold`, `credits_runout_prediction`, `credits_usage_spike`) are account-level alert configs. They are evaluated by the credits alert sweep and default-enabled configs may be auto-created for active accounts at runtime.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "list_alert_configs_api_alerts_configs_get", + "/alerts/{alert_id}/comments": { + "post": { + "description": "Add a comment to an alert. Comments are visible to all subscribers and are included in the alert detail response.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "add_alert_comment_api_alerts__alert_id__comments_post", "parameters": [ { - "description": "Filter by agent ID", - "in": "query", - "name": "agent_id", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Filter by agent ID", - "title": "Agent Id" - } - }, - { - "description": "Filter by source connection ID", - "in": "query", - "name": "source_connection_id", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Filter by source connection ID", - "title": "Source Connection Id" - } - }, - { - "description": "Set to 'source' to list account-level source alert configs", - "in": "query", - "name": "scope", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Set to 'source' to list account-level source alert configs", - "title": "Scope" - } - }, - { - "description": "Page number", - "in": "query", - "name": "page", - "required": false, - "schema": { - "default": 1, - "description": "Page number", - "minimum": 1, - "title": "Page", - "type": "integer" - } - }, - { - "description": "Items per page", - "in": "query", - "name": "limit", - "required": false, + "in": "path", + "name": "alert_id", + "required": true, "schema": { - "default": 50, - "description": "Items per page", - "maximum": 100, - "minimum": 1, - "title": "Limit", - "type": "integer" + "title": "Alert Id", + "type": "string" } }, { @@ -15185,12 +18228,22 @@ "$ref": "#/components/parameters/Seclai-Version" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__alerts__AddCommentRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AlertConfigListResponse" + "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" } } }, @@ -15205,17 +18258,46 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "List alert configs", + "summary": "Add alert comment", "tags": [ "alerts" ] - }, + } + }, + "/alerts/{alert_id}/status": { "post": { - "description": "Create a new alert configuration.\n\nAgent alert types: run_failed, consecutive_failures, error_rate_spike, run_burst, slow_run, credits_low_threshold, credits_runout_prediction, credits_usage_spike, non_manual_eval_failed, non_manual_eval_flagged, governance_flagged, governance_blocked, model_newer_available, model_deprecated, model_sunset.\nSource alert types: pull_failed, consecutive_pull_failures, pull_error_rate_spike.\n\nDistribution types: owner, owner_admins, selected_members. Organization accounts are normalized to owner_admins.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "create_alert_config_api_alerts_configs_post", + "description": "Change the status of an alert. Valid statuses: triggered, acknowledged, resolved, dismissed.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "change_alert_status_api_alerts__alert_id__status_post", "parameters": [ + { + "in": "path", + "name": "alert_id", + "required": true, + "schema": { + "title": "Alert Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -15227,18 +18309,18 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateAlertConfigRequest" + "$ref": "#/components/schemas/ChangeStatusRequest" } } }, "required": true }, "responses": { - "201": { + "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AlertConfigResponse" + "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" } } }, @@ -15253,25 +18335,43 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Create alert config", + "summary": "Change alert status", "tags": [ "alerts" ] } }, - "/alerts/configs/{config_id}": { - "delete": { - "description": "Delete an alert configuration. This permanently removes the config and stops any future alerts of this type from being triggered.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "delete_alert_config_api_alerts_configs__config_id__delete", + "/alerts/{alert_id}/subscribe": { + "post": { + "description": "Subscribe the current user to an alert. Subscribed users receive email notifications when the alert status changes or new comments are added, for as long as they remain an owner or administrator of the account.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "subscribe_to_alert_api_alerts__alert_id__subscribe_post", "parameters": [ { "in": "path", - "name": "config_id", + "name": "alert_id", "required": true, "schema": { - "title": "Config Id", + "title": "Alert Id", "type": "string" } }, @@ -15283,7 +18383,14 @@ } ], "responses": { - "204": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" + } + } + }, "description": "Successful Response" }, "422": { @@ -15295,23 +18402,43 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Delete alert config", + "summary": "Subscribe to alert", "tags": [ "alerts" ] - }, - "get": { - "description": "Get a specific alert configuration by ID.\n\nReturns all fields including type, enabled state, threshold, cooldown, distribution type, and recipient list.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "get_alert_config_api_alerts_configs__config_id__get", + } + }, + "/alerts/{alert_id}/unsubscribe": { + "post": { + "description": "Unsubscribe the current user from an alert. The user will no longer receive email notifications for status changes or new comments on this alert.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "operationId": "unsubscribe_from_alert_api_alerts__alert_id__unsubscribe_post", "parameters": [ { "in": "path", - "name": "config_id", + "name": "alert_id", "required": true, "schema": { - "title": "Config Id", + "title": "Alert Id", "type": "string" } }, @@ -15327,7 +18454,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AlertConfigResponse" + "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" } } }, @@ -15342,26 +18469,37 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Get alert config", + "summary": "Unsubscribe from alert", "tags": [ "alerts" ] - }, - "patch": { - "description": "Update an alert configuration. Only provided fields are updated.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "update_alert_config_api_alerts_configs__config_id__patch", + } + }, + "/cloud-drives": { + "get": { + "description": "List the account's cloud-drive connections. Use a connection's `id` as `cloud_drive_connection_id` when creating a `cloud_drive` content source or binding a file-change agent trigger. `realtime_updates` reports whether changes arrive within seconds or on the scheduled backstop sweep.\n\nRequires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned.", + "operationId": "list_cloud_drives_api_api_cloud_drives_get", "parameters": [ - { - "in": "path", - "name": "config_id", - "required": true, - "schema": { - "title": "Config Id", - "type": "string" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -15369,80 +18507,51 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateAlertConfigRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AlertConfigResponse" + "items": { + "$ref": "#/components/schemas/CloudDriveResponseModel" + }, + "title": "Response List Cloud Drives Api Api Cloud Drives Get", + "type": "array" } } }, "description": "Successful Response" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Update alert config", + "summary": "List the account's cloud-drive connections", "tags": [ - "alerts" + "cloud_drives" ] } }, - "/alerts/organization-preferences/list": { + "/cloud-drives/providers": { "get": { - "description": "List per-organization alert delivery preferences for the authenticated user.\n\nBy default, only explicit override rows are returned. Set `include_defaults=true` to return the effective subscribed state for every alert type in every organization the user can manage.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.\n- Only organizations where the user is an owner or administrator are included.", - "operationId": "list_organization_preferences_api_alerts_organization_preferences_list_get", + "description": "List the cloud-drive providers whose OAuth app is configured on this deployment (e.g. Dropbox, Google Drive), with the permissions each requests. A provider missing from this list cannot be connected here.\n\nRequires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned.", + "operationId": "list_cloud_drive_providers_api_api_cloud_drives_providers_get", "parameters": [ - { - "description": "Optional organization filter", - "in": "query", - "name": "organization_id", - "required": false, - "schema": { - "anyOf": [ - { - "format": "uuid", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Optional organization filter", - "title": "Organization Id" - } - }, - { - "description": "Include default subscribed entries for all alert types", - "in": "query", - "name": "include_defaults", - "required": false, - "schema": { - "default": false, - "description": "Include default subscribed entries for all alert types", - "title": "Include Defaults", - "type": "boolean" - } - }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -15455,50 +18564,53 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/OrganizationAlertPreferenceListResponse" + "items": { + "$ref": "#/components/schemas/CloudDriveProviderResponseModel" + }, + "title": "Response List Cloud Drive Providers Api Api Cloud Drives Providers Get", + "type": "array" } } }, "description": "Successful Response" }, - "422": { + "503": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "List organization alert delivery preferences", + "summary": "List configured cloud-drive providers", "tags": [ - "alerts" + "cloud_drives" ] } }, - "/alerts/organization-preferences/{organization_id}/{alert_type}": { - "patch": { - "description": "Update the authenticated user's personal delivery preference for one alert type in one organization.\n\nSetting `subscribed=false` stores an explicit opt-out override. Setting `subscribed=true` removes the override and restores the default subscribed behavior.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.\n- Only owners and administrators can update preferences for an organization.", - "operationId": "update_organization_preference_api_alerts_organization_preferences__organization_id___alert_type__patch", + "/cloud-drives/{connection_id}": { + "delete": { + "description": "Soft-delete a connection and clear its tokens. Refused with **409** while anything still depends on it \u2014 a live agent trigger, or a `cloud_drive` content source ingesting into a knowledge base. `GET /{connection_id}/agents` shows which agents reference it, but does NOT list content sources, so treat the 409 as the authoritative check rather than a clean /agents response.\n\nRequires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned.", + "operationId": "delete_cloud_drive_api_api_cloud_drives__connection_id__delete", "parameters": [ { "in": "path", - "name": "organization_id", + "name": "connection_id", "required": true, "schema": { "format": "uuid", - "title": "Organization Id", - "type": "string" - } - }, - { - "in": "path", - "name": "alert_type", - "required": true, - "schema": { - "title": "Alert Type", + "title": "Connection Id", "type": "string" } }, @@ -15509,22 +18621,12 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/routers__api__alerts__UpdateOrganizationAlertPreferenceRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__alerts__OrganizationAlertPreferenceResponse" + "$ref": "#/components/schemas/OkResponse" } } }, @@ -15539,25 +18641,42 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Update organization alert delivery preference", + "summary": "Delete a cloud-drive connection", "tags": [ - "alerts" + "cloud_drives" ] - } - }, - "/alerts/{alert_id}": { + }, "get": { - "description": "Get full alert detail including history, comments, and subscribers.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "get_alert_detail_api_alerts__alert_id__get", + "description": "Fetch a single cloud-drive connection by id.\n\nRequires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned.", + "operationId": "get_cloud_drive_api_api_cloud_drives__connection_id__get", "parameters": [ { "in": "path", - "name": "alert_id", + "name": "connection_id", "required": true, "schema": { - "title": "Alert Id", + "format": "uuid", + "title": "Connection Id", "type": "string" } }, @@ -15573,7 +18692,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" + "$ref": "#/components/schemas/CloudDriveResponseModel" } } }, @@ -15588,25 +18707,42 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Get alert detail", + "summary": "Get a cloud-drive connection", "tags": [ - "alerts" + "cloud_drives" ] - } - }, - "/alerts/{alert_id}/comments": { - "post": { - "description": "Add a comment to an alert. Comments are visible to all subscribers and are included in the alert detail response.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "add_alert_comment_api_alerts__alert_id__comments_post", + }, + "patch": { + "description": "Rename a connection and/or change the folder it watches. Changing the folder resets the sync cursor, so existing files in the new folder are not replayed as triggers.\n\nRequires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned.", + "operationId": "update_cloud_drive_api_api_cloud_drives__connection_id__patch", "parameters": [ { "in": "path", - "name": "alert_id", + "name": "connection_id", "required": true, "schema": { - "title": "Alert Id", + "format": "uuid", + "title": "Connection Id", "type": "string" } }, @@ -15621,7 +18757,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__alerts__AddCommentRequest" + "$ref": "#/components/schemas/CloudDriveUpdateRequest" } } }, @@ -15632,7 +18768,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" + "$ref": "#/components/schemas/CloudDriveResponseModel" } } }, @@ -15647,25 +18783,44 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Add alert comment", + "summary": "Update a cloud-drive connection", "tags": [ - "alerts" + "cloud_drives" ] } }, - "/alerts/{alert_id}/status": { - "post": { - "description": "Change the status of an alert. Valid statuses: triggered, acknowledged, resolved, dismissed.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "change_alert_status_api_alerts__alert_id__status_post", + "/cloud-drives/{connection_id}/agents": { + "get": { + "description": "Agents that reference this connection \u2014 via a cloud-drive step, a `prompt_call` cloud-drive tool, or a file-change trigger. Check this before disconnecting or deleting a connection.\n\nRequires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned.", + "operationId": "get_agents_using_cloud_drive_api_api_cloud_drives__connection_id__agents_get", "parameters": [ { "in": "path", - "name": "alert_id", + "name": "connection_id", "required": true, "schema": { - "title": "Alert Id", + "format": "uuid", + "title": "Connection Id", "type": "string" } }, @@ -15676,22 +18831,16 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ChangeStatusRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" + "items": { + "$ref": "#/components/schemas/AgentUsingCloudDriveResponseModel" + }, + "title": "Response Get Agents Using Cloud Drive Api Api Cloud Drives Connection Id Agents Get", + "type": "array" } } }, @@ -15706,25 +18855,44 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Change alert status", + "summary": "List agents using a cloud-drive connection", "tags": [ - "alerts" + "cloud_drives" ] } }, - "/alerts/{alert_id}/subscribe": { + "/cloud-drives/{connection_id}/disconnect": { "post": { - "description": "Subscribe the current user to an alert. Subscribed users receive email notifications when the alert status changes or new comments are added.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "subscribe_to_alert_api_alerts__alert_id__subscribe_post", + "description": "Revoke and clear the stored tokens and stop change notifications, keeping the connection row so it can be reconnected from the app. Agents bound to it stop firing until it is reconnected.\n\nRequires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned.", + "operationId": "disconnect_cloud_drive_api_api_cloud_drives__connection_id__disconnect_post", "parameters": [ { "in": "path", - "name": "alert_id", + "name": "connection_id", "required": true, "schema": { - "title": "Alert Id", + "format": "uuid", + "title": "Connection Id", "type": "string" } }, @@ -15740,7 +18908,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" + "$ref": "#/components/schemas/CloudDriveResponseModel" } } }, @@ -15755,28 +18923,59 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Subscribe to alert", + "summary": "Disconnect a cloud-drive connection", "tags": [ - "alerts" + "cloud_drives" ] } }, - "/alerts/{alert_id}/unsubscribe": { - "post": { - "description": "Unsubscribe the current user from an alert. The user will no longer receive email notifications for status changes or new comments on this alert.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", - "operationId": "unsubscribe_from_alert_api_alerts__alert_id__unsubscribe_post", + "/cloud-drives/{connection_id}/rejections": { + "get": { + "description": "Recent files the connection deliberately skipped, newest first, with the reason: `too_large` (above the size cap), `download_failed` (the provider would not serve the bytes), or `flood` (the per-sync or per-account run cap was hit, so remaining changes were dropped).\n\nThis is the answer to \"why didn't my agent run for that file?\" \u2014 a skipped file fires no trigger and appears nowhere else.\n\nRequires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned.", + "operationId": "list_cloud_drive_rejections_api_api_cloud_drives__connection_id__rejections_get", "parameters": [ { "in": "path", - "name": "alert_id", + "name": "connection_id", "required": true, "schema": { - "title": "Alert Id", + "format": "uuid", + "title": "Connection Id", "type": "string" } }, + { + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 50, + "maximum": 200, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -15789,7 +18988,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__alerts__AlertDetailResponse" + "items": { + "$ref": "#/components/schemas/CloudDriveRejectionResponseModel" + }, + "title": "Response List Cloud Drive Rejections Api Api Cloud Drives Connection Id Rejections Get", + "type": "array" } } }, @@ -15804,17 +19007,35 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Unsubscribe from alert", + "summary": "List files this connection did not process", "tags": [ - "alerts" + "cloud_drives" ] } }, "/contents/{source_connection_content_version}": { "delete": { - "description": "Delete a content item (a `SourceConnectionContentVersion`).\n\nUse this to remove an uploaded or indexed item from your account. Deleting content can affect agents and knowledge base workflows that reference this item.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only delete content belonging to your account.", + "description": "Delete a content item (a `SourceConnectionContentVersion`).\n\nUse this to remove an uploaded or indexed item from your account. Deleting content can affect agents and knowledge base workflows that reference this item.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only delete content belonging to your account.\n- A key bound to a user must belong to an owner or administrator of the account; a viewer's key is refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected.", "operationId": "delete_content_api_contents__source_connection_content_version__delete", "parameters": [ { @@ -15837,6 +19058,9 @@ "204": { "description": "Successful Response" }, + "403": { + "description": "The key's user is a member of the account but not an owner or administrator (`error.code` is `permission_denied`)." + }, "422": { "content": { "application/json": { @@ -15846,6 +19070,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Delete content", @@ -15913,6 +19155,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get content details", @@ -15921,7 +19181,7 @@ ] }, "put": { - "description": "Replace a content version using a small inline text payload.\n\n**Maximum payload size:** 8192 bytes (UTF-8).\n\n**Supported content types:**\n- `application/json`\n- `application/xml`\n- `text/csv`\n- `text/html`\n- `text/markdown`\n- `text/plain`\n- `text/x-markdown`\n- `text/xml`\n\nNotes:\n- Use this endpoint for small text payloads; larger files should use `/upload`.\n- `title` is merged into `metadata.title` when not already present.", + "description": "Replace a content version using a small inline text payload.\n\n**Maximum payload size:** 8192 bytes (UTF-8).\n\n**Supported content types:**\n- `application/json`\n- `application/xml`\n- `text/csv`\n- `text/html`\n- `text/markdown`\n- `text/plain`\n- `text/x-markdown`\n- `text/xml`\n\nNotes:\n- A key bound to a user must belong to an owner or administrator of the account; a viewer's key is refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected.\n- Use this endpoint for small text payloads; larger files should use `/upload`.\n- `title` is merged into `metadata.title` when not already present.\n- The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps working, and reads return the previous content until indexing finishes; poll `list_source_content_status` to follow it. The returned `content_version_id` is the new version.", "operationId": "replace_content_with_inline_text_api_contents__source_connection_content_version__put", "parameters": [ { @@ -15961,6 +19221,9 @@ }, "description": "Successful Response" }, + "403": { + "description": "The key's user is not an owner or administrator of the account (`error.code` is `permission_denied`), or the account is suspended (`suspended_account`)." + }, "422": { "content": { "application/json": { @@ -15970,6 +19233,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Replace a content version with inline text", @@ -16039,6 +19320,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List content embeddings", @@ -16049,7 +19348,7 @@ }, "/contents/{source_connection_content_version}/upload": { "post": { - "description": "Upload a new file and replace the content backing an existing `SourceConnectionContentVersion`.\n\nThis behaves like a source file upload, but it targets an existing content version ID. This is useful when you want to correct or update an uploaded document while keeping references stable.\n\n**Maximum file size:** 209715200 bytes.\n\n**Supported MIME types:**\n- `application/epub+zip`\n- `application/json`\n- `application/pdf`\n- `application/vnd.ms-excel`\n- `application/vnd.ms-outlook`\n- `application/vnd.ms-powerpoint`\n- `application/vnd.openxmlformats-officedocument.presentationml.presentation`\n- `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`\n- `application/vnd.openxmlformats-officedocument.wordprocessingml.document`\n- `application/xml`\n- `application/zip`\n- `audio/flac`\n- `audio/mp4`\n- `audio/mpeg`\n- `audio/ogg`\n- `audio/wav`\n- `image/bmp`\n- `image/gif`\n- `image/jpeg`\n- `image/png`\n- `image/svg+xml`\n- `image/tiff`\n- `image/webp`\n- `text/csv`\n- `text/html`\n- `text/markdown`\n- `text/plain`\n- `text/x-markdown`\n- `text/xml`\n- `video/mp4`\n- `video/quicktime`\n- `video/x-msvideo`\n\nNotes:\n- If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension.\n- Use `metadata` to attach an arbitrary JSON object of metadata (for example `metadata={\"category\":\"docs\"}`).\n- `title` is a convenience field and is merged into the metadata as `metadata.title` (it does not override an existing `metadata.title`).\n- For backwards compatibility, you can also pass form fields named `metadata_` (for example `metadata_author=...`). These override keys from `metadata`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only replace content belonging to your account.", + "description": "Upload a new file and replace the content backing an existing `SourceConnectionContentVersion`.\n\nThis behaves like a source file upload, but it targets an existing content version ID. This is useful when you want to correct or update an uploaded document while keeping references stable.\n\n**Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized before it is stored).\n\n**Supported MIME types:**\n- `application/epub+zip`\n- `application/json`\n- `application/pdf`\n- `application/vnd.ms-excel`\n- `application/vnd.ms-outlook`\n- `application/vnd.ms-powerpoint`\n- `application/vnd.openxmlformats-officedocument.presentationml.presentation`\n- `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`\n- `application/vnd.openxmlformats-officedocument.wordprocessingml.document`\n- `application/xml`\n- `application/zip`\n- `audio/flac`\n- `audio/mp4`\n- `audio/mpeg`\n- `audio/ogg`\n- `audio/wav`\n- `image/bmp`\n- `image/gif`\n- `image/jpeg`\n- `image/png`\n- `image/svg+xml`\n- `image/tiff`\n- `image/webp`\n- `text/csv`\n- `text/html`\n- `text/markdown`\n- `text/plain`\n- `text/x-markdown`\n- `text/xml`\n- `video/mp4`\n- `video/quicktime`\n- `video/x-msvideo`\n\nNotes:\n- A key bound to a user must belong to an owner or administrator of the account; a viewer's key is refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected.\n- The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps working, and reads return the previous content until indexing finishes; poll `list_source_content_status` to follow it. The returned `content_version_id` is the new version.\n- If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension.\n- Use `metadata` to attach an arbitrary JSON object of metadata (for example `metadata={\"category\":\"docs\"}`).\n- `title` is a convenience field and is merged into the metadata as `metadata.title` (it does not override an existing `metadata.title`).\n- For backwards compatibility, you can also pass form fields named `metadata_` (for example `metadata_author=...`). These override keys from `metadata`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only replace content belonging to your account.", "operationId": "upload_file_to_content_api_contents__source_connection_content_version__upload_post", "parameters": [ { @@ -16089,6 +19388,9 @@ }, "description": "Successful Response" }, + "403": { + "description": "The key's user is not an owner or administrator of the account (`error.code` is `permission_denied`), or the account is suspended (`suspended_account`)." + }, "422": { "content": { "application/json": { @@ -16098,6 +19400,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Replace a content version with a new upload", @@ -16181,6 +19501,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Search documentation", @@ -16211,6 +19549,24 @@ } }, "description": "Successful Response" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List the account's email domains + plan capabilities", @@ -16259,6 +19615,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Add + provision an email domain", @@ -16269,7 +19643,7 @@ }, "/email-domains/use-shared-domain": { "post": { - "description": "Clear the account's primary domain so agent email reverts to the shared `agent.seclai.com` sending/inbound scheme, WITHOUT removing the configured domain(s) \u2014 they stay verified and can be promoted again later. Owner/admin only.\n\nAuth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account.", + "description": "Clear the account's primary domain so agent email reverts to the shared `agent.seclai.com` sending domain, WITHOUT removing the configured domain(s) \u2014 they stay verified and can be promoted again later. Owner/admin only.\n\nAuth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account.", "operationId": "use_shared_domain_api_api_email_domains_use_shared_domain_post", "parameters": [ { @@ -16282,6 +19656,24 @@ "responses": { "204": { "description": "Successful Response" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Revert to the shared agent.seclai.com sending domain", @@ -16332,6 +19724,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Remove an email domain", @@ -16402,6 +19812,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "DMARC aggregate-report summary for a domain", @@ -16412,7 +19840,7 @@ }, "/email-domains/{domain_id}/primary": { "post": { - "description": "Promote a verified domain to the account's primary domain \u2014 agent email then sends FROM and receives ON this domain (`@`, `@`) instead of the shared `agent.seclai.com`. The domain must be verified. Owner/admin only.\n\nAuth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account.", + "description": "Promote a verified domain to the account's primary domain \u2014 agent email then sends FROM this domain and shows its addresses on it (`@`, `@`) instead of the shared `agent.seclai.com`; addresses keep resolving on the account's other verified domains and the shared form. The domain must be verified. Owner/admin only.\n\nAuth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account.", "operationId": "set_primary_email_domain_api_api_email_domains__domain_id__primary_post", "parameters": [ { @@ -16452,9 +19880,27 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Make a verified domain the account's primary sending/inbound domain", + "summary": "Make a verified domain the account's primary sending domain", "tags": [ "email-domains" ] @@ -16502,6 +19948,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Send a test email from a verified domain to the account owner", @@ -16552,6 +20016,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Run a verification check immediately ('Check now')", @@ -16608,6 +20090,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Generate a governance plan", @@ -16669,6 +20169,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List AI assistant conversations", @@ -16725,6 +20243,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Accept a governance plan", @@ -16772,8 +20308,26 @@ "$ref": "#/components/schemas/HTTPValidationError" } } - }, - "description": "Validation Error" + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Decline a governance plan", @@ -16866,6 +20420,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List Knowledge Bases", @@ -16917,6 +20489,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Create Knowledge Base", @@ -16959,6 +20549,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Delete Knowledge Base", @@ -17006,6 +20614,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Knowledge Base", @@ -17063,6 +20689,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Update Knowledge Base", @@ -17093,6 +20737,24 @@ } }, "description": "Successful Response" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get current user identity", @@ -17203,6 +20865,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List Memory Banks", @@ -17251,6 +20931,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Create Memory Bank", @@ -17304,6 +21002,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Generate a memory bank configuration", @@ -17371,6 +21087,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Fetch memory bank AI conversation history", @@ -17431,6 +21165,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Accept or decline a memory bank AI suggestion", @@ -17461,6 +21213,24 @@ } }, "description": "Successful Response" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List Templates", @@ -17511,6 +21281,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Test Compaction Prompt Standalone", @@ -17553,6 +21341,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Delete Memory Bank", @@ -17600,6 +21406,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Memory Bank", @@ -17657,6 +21481,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Update Memory Bank", @@ -17706,6 +21548,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Agents Using Bank", @@ -17716,7 +21576,7 @@ }, "/memory_banks/{memory_bank_id}/compact": { "post": { - "description": "Trigger an on-demand compaction run for a memory bank.\n\nThe bank must have at least one compaction threshold configured (max_age_days, max_turns, or max_size_tokens). Compaction runs asynchronously \u2014 the response confirms scheduling, not completion.", + "description": "Trigger an on-demand compaction run for a memory bank.\n\nThe bank must have at least one compaction threshold configured (max_turns or max_size_tokens). Age no longer triggers compaction \u2014 use retention_days to remove entries by age. Compaction runs asynchronously \u2014 the response confirms scheduling, not completion.", "operationId": "compact_memory_bank_api_memory_banks__memory_bank_id__compact_post", "parameters": [ { @@ -17755,6 +21615,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Compact Memory Bank", @@ -17797,6 +21675,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Delete Memory Bank Source", @@ -17894,6 +21790,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Memory Bank Entry Stats", @@ -17951,8 +21865,26 @@ "$ref": "#/components/schemas/HTTPValidationError" } } - }, - "description": "Validation Error" + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Test Compaction Prompt", @@ -17963,7 +21895,7 @@ }, "/models": { "get": { - "description": "List all enabled LLM models with full details.\n\nReturns models grouped by provider, including capabilities, credit pricing, tool support, variant tiers, and lifecycle status.\n\nOptional query parameters:\n- `provider`: filter by provider (e.g. 'anthropic', 'openai')\n- `supports_tool_use`: filter to models with tool calling support\n- `supports_thinking`: filter to models with extended thinking support\n- `supports_input_media`: filter to models accepting an input modality (`image`/`audio`/`video`/`pdf` or a full MIME)\n- `supports_output_media`: filter to models producing an output modality (`image`/`audio`/`video`) \u2014 e.g. to find generation models\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "description": "List the enabled LLM models with full details.\n\nReturns models grouped by provider, including capabilities, credit pricing, tool support, variant tiers, and lifecycle status.\n\nA model whose credit rate has not been published yet is omitted, so you are never offered a model that cannot be billed and therefore cannot be run. Such a model may appear later without any other change.\n\nOptional query parameters:\n- `provider`: filter by provider (e.g. 'anthropic', 'openai')\n- `supports_tool_use`: filter to models with tool calling support\n- `supports_thinking`: filter to models with extended thinking support\n- `supports_input_media`: filter to models accepting an input modality (`image`/`audio`/`video`/`pdf` or a full MIME)\n- `supports_output_media`: filter to models producing an output modality (`image`/`audio`/`video`) \u2014 e.g. to find generation models\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", "operationId": "list_models_api_models_get", "parameters": [ { @@ -18087,6 +22019,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List Models", @@ -18184,6 +22134,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List Alerts", @@ -18207,6 +22175,24 @@ "responses": { "204": { "description": "Successful Response" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Mark All Read", @@ -18237,6 +22223,24 @@ } }, "description": "Successful Response" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Alert Unread Count", @@ -18280,6 +22284,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Mark Read", @@ -18288,6 +22310,82 @@ ] } }, + "/models/embedders": { + "get": { + "description": "List the embedding models a source can be created with.\n\nEach entry carries the `model_type` to pass as `embedding_model` when creating a source, the `dimensions` it supports, and \u2014 most importantly for multi-modal indexing \u2014 `supported_input_media`: the modalities that embedder can actually index. A source only honours a `media_types` entry its embedder lists here; unsupported kinds are dropped at save time with an `embedder_warning`, so check this before choosing an embedder for a knowledge base of images or video.\n\nText-only embedders report `supported_input_media` as null. Pricing is reported as `credits` (per ~1,000 English words of text) plus `per_modality_rates` for the non-text modalities a multi-modal embedder bills differently.\n\nAn embedder whose credit rate has not been published yet is omitted, so you are never offered one that cannot be billed.\n\nOptional query parameters:\n- `supports_input_media`: keep only embedders that can index this modality (`text`/`image`/`video`/`audio` or a full MIME)\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical for every account.", + "operationId": "list_embedding_models_api_models_embedders_get", + "parameters": [ + { + "description": "Filter to embedders that can index this input modality \u2014 a coarse kind (text, image, video, audio) or a full MIME.", + "in": "query", + "name": "supports_input_media", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter to embedders that can index this input modality \u2014 a coarse kind (text, image, video, audio) or a full MIME.", + "title": "Supports Input Media" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmbeddingModelListResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "List Embedding Models", + "tags": [ + "models" + ] + } + }, "/models/generation-tiers": { "get": { "description": "List the media-generation quality tiers and the model + cost each resolves to.\n\nOn a prompt_call's `media_generation` tool \u2014 and the dedicated generate_* steps via tier routing \u2014 the author/LLM chooses a *tier* (fast/balanced/thorough), never a model. This is the surface that maps each `(modality, tier)` to its concrete generator, raw `credits_per_unit`, `unit_label`, and a human-readable scaled `price_label`. Global routing/pricing (the same for every account); read-only. REST parity with the `list_generation_tiers` MCP tool.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", @@ -18310,6 +22408,24 @@ } }, "description": "Successful Response" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Generation Tiers", @@ -18320,7 +22436,7 @@ }, "/models/playground/experiments": { "get": { - "description": "List model playground experiments for the account.\n\nReturns a paginated, time-filtered list of experiments ordered by creation date descending.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account.", + "description": "List model playground experiments for the account.\n\nReturns a paginated, time-filtered list of experiments ordered by creation date descending.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account and, when the credential is bound to a user, to that user.", "operationId": "list_experiments_api_models_playground_experiments_get", "parameters": [ { @@ -18429,6 +22545,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List Experiments", @@ -18437,7 +22571,7 @@ ] }, "post": { - "description": "Create and schedule a model playground experiment.\n\nRuns the given prompt against 1-10 models in parallel and optionally evaluates the outputs with an LLM judge.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", + "description": "Create and schedule a model playground experiment.\n\nRuns the given prompt against 1-10 models in parallel and optionally evaluates the outputs with an LLM judge.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.\n- When the credential is bound to a user, the experiment belongs to that user; only that user or an account-scoped key can cancel or delete it.", "operationId": "create_experiment_api_models_playground_experiments_post", "parameters": [ { @@ -18477,6 +22611,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Create Experiment", @@ -18487,7 +22639,7 @@ }, "/models/playground/experiments/{experiment_id}": { "delete": { - "description": "Soft-delete a model playground experiment.\n\nRemoves the experiment from list/detail views while preserving audit history.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth access token. The experiment must belong to the caller's account.", + "description": "Soft-delete a model playground experiment.\n\nRemoves the experiment from list/detail views while preserving audit history.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth access token. The experiment must belong to the caller's account and, when the credential is bound to a user, to that user; otherwise 404.", "operationId": "delete_experiment_endpoint_api_models_playground_experiments__experiment_id__delete", "parameters": [ { @@ -18520,6 +22672,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Delete Experiment Endpoint", @@ -18528,7 +22698,7 @@ ] }, "get": { - "description": "Get details and results for a specific model playground experiment.\n\nReturns the full experiment payload including prompt, model outputs, and evaluation results (if available).\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's account.", + "description": "Get details and results for a specific model playground experiment.\n\nReturns the full experiment payload including prompt, model outputs, and evaluation results (if available).\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's account and, when the credential is bound to a user, to that user; otherwise 404.", "operationId": "get_experiment_api_models_playground_experiments__experiment_id__get", "parameters": [ { @@ -18568,6 +22738,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Experiment", @@ -18578,7 +22766,7 @@ }, "/models/playground/experiments/{experiment_id}/cancel": { "post": { - "description": "Cancel a running or pending model playground experiment.\n\nSignals running model calls to abort and marks the experiment as canceled.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's account.", + "description": "Cancel a running or pending model playground experiment.\n\nSignals running model calls to abort and marks the experiment as canceled.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's account and, when the credential is bound to a user, to that user; otherwise 404.", "operationId": "cancel_experiment_endpoint_api_models_playground_experiments__experiment_id__cancel_post", "parameters": [ { @@ -18618,6 +22806,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Cancel Experiment Endpoint", @@ -18626,6 +22832,54 @@ ] } }, + "/models/rerankers": { + "get": { + "description": "List the reranker models a knowledge base can be created with.\n\nA reranker re-scores the top results of a vector search for relevance. Each entry carries the `model_type` to pass as `reranker_model` on a knowledge base, its `credits_per_action`, and whether it is the platform default (`is_default`, used when you omit `reranker_model`).\n\nTo disable reranking, send `\"none\"` or an empty string as `reranker_model` rather than a value from this list. Reranking scores text, so a knowledge base whose sources all embed media natively \u2014 whose chunks carry no text \u2014 defaults to no reranker.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical for every account.", + "operationId": "list_reranker_models_api_models_rerankers_get", + "parameters": [ + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RerankerModelListResponse" + } + } + }, + "description": "Successful Response" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "List Reranker Models", + "tags": [ + "models" + ] + } + }, "/models/{model_id}/details": { "get": { "description": "Get detailed information about a specific model.\n\nReturns full model details including capabilities, credit pricing, tool support, variant tiers, and lifecycle status.\n\nThe `model_id` is the model enum identifier (e.g. 'anthropic_claude_opus_4_6').\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.", @@ -18667,6 +22921,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Model", @@ -18801,11 +23073,29 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Recommendations", @@ -18891,6 +23181,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Search resources", @@ -19003,6 +23311,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List solutions", @@ -19051,6 +23377,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Create a solution", @@ -19094,6 +23438,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Delete a solution", @@ -19142,6 +23504,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get a solution", @@ -19200,6 +23580,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Update a solution", @@ -19260,6 +23658,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Unlink agents", @@ -19318,6 +23734,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Link agents", @@ -19378,6 +23812,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Generate solution plan", @@ -19438,6 +23890,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Generate knowledge base plan", @@ -19498,6 +23968,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Generate source plan", @@ -19568,6 +24056,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Accept plan", @@ -19621,6 +24127,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Decline plan", @@ -19675,6 +24199,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List conversations", @@ -19733,6 +24275,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Add conversation turn", @@ -19796,6 +24356,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Mark conversation turn", @@ -19856,6 +24434,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Unlink knowledge bases", @@ -19914,6 +24510,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Link knowledge bases", @@ -19974,6 +24588,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Unlink source connections", @@ -20032,6 +24664,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Link source connections", @@ -20137,11 +24787,29 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" } } }, - "description": "Validation Error" + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List sources", @@ -20193,6 +24861,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Create Source", @@ -20236,6 +24922,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Delete Source", @@ -20284,6 +24988,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Source", @@ -20292,7 +25014,7 @@ ] }, "post": { - "description": "Upload a small text payload to a content source (no multipart/form-data required).\n\n**Maximum payload size:** 8192 bytes (UTF-8).\n\n**Supported content types:**\n- `application/json`\n- `application/xml`\n- `text/csv`\n- `text/html`\n- `text/markdown`\n- `text/plain`\n- `text/x-markdown`\n- `text/xml`\n\nNotes:\n- Use this endpoint for small text payloads; larger files should use `/upload`.\n- `title` is merged into `metadata.title` when not already present.", + "description": "Upload a small text payload to a content source (no multipart/form-data required).\n\n**Maximum payload size:** 8192 bytes (UTF-8).\n\n**Supported content types:**\n- `application/json`\n- `application/xml`\n- `text/csv`\n- `text/html`\n- `text/markdown`\n- `text/plain`\n- `text/x-markdown`\n- `text/xml`\n\nNotes:\n- A key bound to a user must belong to an owner or administrator of the account; a viewer's key is refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected.\n- Use this endpoint for small text payloads; larger files should use `/upload`.\n- `title` is merged into `metadata.title` when not already present.\n\nTracking indexing progress:\n- **Which id you get back depends on `status`, and they are not interchangeable:**\n - `uploaded` \u2014 a new item. `content_version_id` is set and `source_connection_content_version_id` is `null`. Indexing continues in the background after this call returns.\n - `duplicate` \u2014 this exact file is already on the source, so nothing was created and nothing is being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll.\n- For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned `content_version_id`, or `GET /sources/{id}/contents?content_version_id=\u2026&content_version_id=\u2026` for a whole batch, to follow each item through to `completed` or `failed`.\n- On those status endpoints `source_connection_content_version_id` stays `null` until the item finishes indexing; that is the id `GET /contents/{id}` takes.", "operationId": "upload_inline_text_to_source_api_sources__source_connection_id__post", "parameters": [ { @@ -20300,9 +25022,258 @@ "name": "source_connection_id", "required": true, "schema": { - "format": "uuid", - "title": "Source Connection Id", - "type": "string" + "format": "uuid", + "title": "Source Connection Id", + "type": "string" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InlineTextUploadRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/routers__api__sources__FileUploadResponse" + } + } + }, + "description": "Successful Response" + }, + "403": { + "description": "The key's user is not an owner or administrator of the account (`error.code` is `permission_denied`), or the account is suspended (`suspended_account`)." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Upload inline text to a content source", + "tags": [ + "sources" + ] + }, + "put": { + "description": "Update a content source's configuration. Only provided fields are changed; omitted fields are left unchanged.\n\nSystem-managed sources only allow `retention_days` updates.", + "operationId": "update_source_api_sources__source_connection_id__put", + "parameters": [ + { + "in": "path", + "name": "source_connection_id", + "required": true, + "schema": { + "format": "uuid", + "title": "Source Connection Id", + "type": "string" + } + }, + { + "$ref": "#/components/parameters/X-Account-Id" + }, + { + "$ref": "#/components/parameters/Seclai-Version" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSourceBody" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SourceResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } + } + }, + "summary": "Update Source", + "tags": [ + "sources" + ] + } + }, + "/sources/{source_connection_id}/contents": { + "get": { + "description": "List every content item this source has attempted to index, with the status of each.\n\nUnlike the source's `content_count`, which only counts finished items, this listing includes items that are still processing and items that failed \u2014 so a bulk upload can report per-item progress and point at the specific items that did not make it.\n\nCorrelating with an upload:\n- Each item is keyed by `content_version_id`, which is what the upload endpoints return. Pass those ids as repeated `content_version_id` query parameters to poll exactly the items you uploaded.\n- `source_connection_content_version_id` is `null` until an item finishes indexing; once set, it is the id `GET /contents/{id}` takes.\n- `content_status` reaches `completed` on success and `failed` on error, with the reason in `error`. The intermediate values are `pending`, `fetching`, `transcribing`, `scanning`, and `indexing`.\n\nParameters:\n- Pagination: `page` and `limit`.\n- Sorting: `sort` (created_at/title/status) and `order` (asc/desc). `created_at` sorts on when the item was uploaded or pulled.\n- Filtering: `status` and repeatable `content_version_id`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only list content for sources belonging to your account.", + "operationId": "list_source_contents_api_sources__source_connection_id__contents_get", + "parameters": [ + { + "in": "path", + "name": "source_connection_id", + "required": true, + "schema": { + "format": "uuid", + "title": "Source Connection Id", + "type": "string" + } + }, + { + "description": "Page number", + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "description": "Page number", + "minimum": 1, + "title": "Page", + "type": "integer" + } + }, + { + "description": "Items per page", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 20, + "description": "Items per page", + "maximum": 100, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "description": "Sort field (created_at/title/status)", + "in": "query", + "name": "sort", + "required": false, + "schema": { + "default": "created_at", + "description": "Sort field (created_at/title/status)", + "title": "Sort", + "type": "string" + } + }, + { + "description": "Sort order", + "in": "query", + "name": "order", + "required": false, + "schema": { + "default": "desc", + "description": "Sort order", + "pattern": "^(asc|desc)$", + "title": "Order", + "type": "string" + } + }, + { + "description": "Filter to one status: pending, fetching, transcribing, scanning, indexing, completed, or failed. Use `failed` to list only the items that could not be indexed.", + "in": "query", + "name": "status", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter to one status: pending, fetching, transcribing, scanning, indexing, completed, or failed. Use `failed` to list only the items that could not be indexed.", + "title": "Status" + } + }, + { + "description": "Filter to specific content versions, repeatable. Pass the `content_version_id` values returned by the upload endpoints to poll exactly the items you uploaded in a single request. At most 500 ids per request \u2014 beyond that, page through the unfiltered listing or split the poll.", + "in": "query", + "name": "content_version_id", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "format": "uuid", + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Filter to specific content versions, repeatable. Pass the `content_version_id` values returned by the upload endpoints to poll exactly the items you uploaded in a single request. At most 500 ids per request \u2014 beyond that, page through the unfiltered listing or split the poll.", + "title": "Content Version Id" } }, { @@ -20312,22 +25283,12 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InlineTextUploadRequest" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/routers__api__sources__FileUploadResponse" + "$ref": "#/components/schemas/SourceContentStatusListResponse" } } }, @@ -20342,16 +25303,36 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Upload inline text to a content source", + "summary": "List content items and their indexing status", "tags": [ "sources" ] - }, - "put": { - "description": "Update a content source's configuration. Only provided fields are changed; omitted fields are left unchanged.\n\nSystem-managed sources only allow `retention_days` updates.", - "operationId": "update_source_api_sources__source_connection_id__put", + } + }, + "/sources/{source_connection_id}/contents/{content_version_id}": { + "get": { + "description": "Get the indexing status of a single content item, addressed by the `content_version_id` the upload endpoints return.\n\nUse this to follow one uploaded file through indexing. To follow many at once, use `GET /sources/{id}/contents` with repeated `content_version_id` parameters instead of polling this endpoint per item.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. You can only access content belonging to your account.", + "operationId": "get_source_content_status_endpoint_api_sources__source_connection_id__contents__content_version_id__get", "parameters": [ { "in": "path", @@ -20363,6 +25344,16 @@ "type": "string" } }, + { + "in": "path", + "name": "content_version_id", + "required": true, + "schema": { + "format": "uuid", + "title": "Content Version Id", + "type": "string" + } + }, { "$ref": "#/components/parameters/X-Account-Id" }, @@ -20370,22 +25361,12 @@ "$ref": "#/components/parameters/Seclai-Version" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSourceBody" - } - } - }, - "required": true - }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SourceResponse" + "$ref": "#/components/schemas/SourceContentStatusResponse" } } }, @@ -20400,9 +25381,27 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, - "summary": "Update Source", + "summary": "Get one content item's indexing status", "tags": [ "sources" ] @@ -20458,6 +25457,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get Source Embedding Migration", @@ -20519,6 +25536,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Start Source Embedding Migration", @@ -20529,7 +25564,7 @@ }, "/sources/{source_connection_id}/embedding-migration/cancel": { "post": { - "description": "Cancel an active embedding migration for a custom-index source.\n\nOnly pending, running, or switching migrations can be cancelled.", + "description": "Cancel an active embedding migration for a custom-index source.\n\nOnly pending and running migrations can be cancelled. A migration that has reached the switching phase is committing its switch-over in a single transaction, so there is no half-applied state to back out of and cancel is refused.", "operationId": "cancel_source_embedding_migration_api_sources__source_connection_id__embedding_migration_cancel_post", "parameters": [ { @@ -20569,6 +25604,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Cancel Source Embedding Migration", @@ -20642,6 +25695,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "List exports", @@ -20650,7 +25721,7 @@ ] }, "post": { - "description": "Start an asynchronous export job. Poll GET .../exports/{export_id} until status becomes completed, then use /download to retrieve the file.", + "description": "Start an asynchronous export job. Poll GET .../exports/{export_id} until status becomes completed, then use /download to retrieve the file. On an organization account, a key bound to a user must belong to an owner or administrator; a viewer's key is refused with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected.", "operationId": "create_source_export_api_sources__source_connection_id__exports_post", "parameters": [ { @@ -20691,6 +25762,9 @@ }, "description": "Successful Response" }, + "403": { + "description": "The key's user is not an owner or administrator of the organization account (`error.code` is `permission_denied`)." + }, "422": { "content": { "application/json": { @@ -20700,6 +25774,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Create export", @@ -20760,6 +25852,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Estimate export size", @@ -20770,7 +25880,7 @@ }, "/sources/{source_connection_id}/exports/{export_id}": { "delete": { - "description": "Delete an export job and remove the associated file from S3. This is a soft-delete: the database record is retained for audit purposes but the backing file is permanently removed.", + "description": "Delete an export job and remove the associated file from S3. This is a soft-delete: the database record is retained for audit purposes but the backing file is permanently removed. On an organization account, a key bound to a user must belong to an owner or administrator; a viewer's key is refused with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected.", "operationId": "delete_source_export_api_sources__source_connection_id__exports__export_id__delete", "parameters": [ { @@ -20804,6 +25914,9 @@ "204": { "description": "Successful Response" }, + "403": { + "description": "The key's user is not an owner or administrator of the organization account (`error.code` is `permission_denied`)." + }, "422": { "content": { "application/json": { @@ -20813,6 +25926,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Delete export", @@ -20871,6 +26002,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get export status", @@ -20881,7 +26030,7 @@ }, "/sources/{source_connection_id}/exports/{export_id}/cancel": { "post": { - "description": "Cancel a pending or running export. The background task will stop at the next chunk boundary. Completed, failed, expired, or already-cancelled exports cannot be cancelled.", + "description": "Cancel a pending or running export. The background task will stop at the next chunk boundary. Completed, failed, expired, or already-cancelled exports cannot be cancelled. On an organization account, a key bound to a user must belong to an owner or administrator; a viewer's key is refused with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected.", "operationId": "cancel_source_export_api_sources__source_connection_id__exports__export_id__cancel_post", "parameters": [ { @@ -20922,6 +26071,9 @@ }, "description": "Successful Response" }, + "403": { + "description": "The key's user is not an owner or administrator of the organization account (`error.code` is `permission_denied`)." + }, "422": { "content": { "application/json": { @@ -20931,6 +26083,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Cancel export", @@ -20989,6 +26159,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Download export", @@ -20999,7 +26187,7 @@ }, "/sources/{source_connection_id}/upload": { "post": { - "description": "Upload a file to a content source.\n\n**Maximum file size:** 209715200 bytes.\n\n**Supported MIME types:**\n- `application/epub+zip`\n- `application/json`\n- `application/pdf`\n- `application/vnd.ms-excel`\n- `application/vnd.ms-outlook`\n- `application/vnd.ms-powerpoint`\n- `application/vnd.openxmlformats-officedocument.presentationml.presentation`\n- `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`\n- `application/vnd.openxmlformats-officedocument.wordprocessingml.document`\n- `application/xml`\n- `application/zip`\n- `audio/flac`\n- `audio/mp4`\n- `audio/mpeg`\n- `audio/ogg`\n- `audio/wav`\n- `image/bmp`\n- `image/gif`\n- `image/jpeg`\n- `image/png`\n- `image/svg+xml`\n- `image/tiff`\n- `image/webp`\n- `text/csv`\n- `text/html`\n- `text/markdown`\n- `text/plain`\n- `text/x-markdown`\n- `text/xml`\n- `video/mp4`\n- `video/quicktime`\n- `video/x-msvideo`\n\nNotes:\n- If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension.\n- Use `metadata` to attach an arbitrary JSON object of metadata (for example `metadata={\"author\":\"Ada\",\"category\":\"docs\"}`).\n- `title` is a convenience field and is merged into the metadata as `metadata.title` (it does not override an existing `metadata.title`).\n- For backwards compatibility, you can also pass form fields named `metadata_` (for example `metadata_author=...`). These override keys from `metadata`.\n\nResponse:\n- `status` is `uploaded` for a new upload, or `duplicate` when the same file already exists for this source.", + "description": "Upload a file to a content source.\n\n**Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized before it is stored).\n\n**Supported MIME types:**\n- `application/epub+zip`\n- `application/json`\n- `application/pdf`\n- `application/vnd.ms-excel`\n- `application/vnd.ms-outlook`\n- `application/vnd.ms-powerpoint`\n- `application/vnd.openxmlformats-officedocument.presentationml.presentation`\n- `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`\n- `application/vnd.openxmlformats-officedocument.wordprocessingml.document`\n- `application/xml`\n- `application/zip`\n- `audio/flac`\n- `audio/mp4`\n- `audio/mpeg`\n- `audio/ogg`\n- `audio/wav`\n- `image/bmp`\n- `image/gif`\n- `image/jpeg`\n- `image/png`\n- `image/svg+xml`\n- `image/tiff`\n- `image/webp`\n- `text/csv`\n- `text/html`\n- `text/markdown`\n- `text/plain`\n- `text/x-markdown`\n- `text/xml`\n- `video/mp4`\n- `video/quicktime`\n- `video/x-msvideo`\n\nNotes:\n- A key bound to a user must belong to an owner or administrator of the account; a viewer's key is refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected.\n- If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension.\n- Use `metadata` to attach an arbitrary JSON object of metadata (for example `metadata={\"author\":\"Ada\",\"category\":\"docs\"}`).\n- `title` is a convenience field and is merged into the metadata as `metadata.title` (it does not override an existing `metadata.title`).\n- For backwards compatibility, you can also pass form fields named `metadata_` (for example `metadata_author=...`). These override keys from `metadata`.\n\nResponse:\n- `status` is `uploaded` for a new upload, or `duplicate` when the same file already exists for this source.\n\nTracking indexing progress:\n- **Which id you get back depends on `status`, and they are not interchangeable:**\n - `uploaded` \u2014 a new item. `content_version_id` is set and `source_connection_content_version_id` is `null`. Indexing continues in the background after this call returns.\n - `duplicate` \u2014 this exact file is already on the source, so nothing was created and nothing is being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll.\n- For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned `content_version_id`, or `GET /sources/{id}/contents?content_version_id=\u2026&content_version_id=\u2026` for a whole batch, to follow each item through to `completed` or `failed`.\n- On those status endpoints `source_connection_content_version_id` stays `null` until the item finishes indexing; that is the id `GET /contents/{id}` takes.", "operationId": "upload_file_to_source_api_sources__source_connection_id__upload_post", "parameters": [ { @@ -21039,6 +26227,9 @@ }, "description": "Successful Response" }, + "403": { + "description": "The key's user is not an owner or administrator of the account (`error.code` is `permission_denied`), or the account is suspended (`suspended_account`)." + }, "422": { "content": { "application/json": { @@ -21048,6 +26239,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Upload a file to a content source", @@ -21058,7 +26267,7 @@ }, "/v2/agent-runs/{run_id}/attachments/{attachment_id}": { "get": { - "description": "Streams the bytes of an attachment emitted by a step in the given agent run. ``attachment_id`` is the URL-safe-base64-encoded ``storage_key`` (use the encoder shared by webhook + email payload builders).\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.\n- The calling account must own ``run_id``; lookup failures (missing run, cross-account run, soft-deleted agent, unreferenced storage_key) all collapse to a single 404 to prevent cross-tenant existence enumeration.\n\nMIME handling:\n- Inline-safe MIMEs (image/*, audio/*, video/*, application/pdf, text/plain, application/vnd.seclai.manifest+json) are served with their declared type.\n- Everything else is served as ``application/octet-stream`` with an attachment disposition to prevent stored-XSS.", + "description": "Streams the bytes of an attachment emitted by a step in the given agent run. ``attachment_id`` is the ``id`` of an entry in the run's or a step's ``attachments``, or the URL-safe-base64-encoded storage key, which webhook and email links carry.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.\n- The calling account must own ``run_id``; lookup failures (missing run, cross-account run, soft-deleted agent, a run whose trace was purged, a file not in the run) all collapse to a single 404 to prevent cross-tenant existence enumeration.\n\nMIME handling:\n- Inline-safe MIMEs (image/*, audio/*, video/*, application/pdf, text/plain, application/vnd.seclai.manifest+json) are served with their declared type.\n- Everything else is served as ``application/octet-stream`` with an attachment disposition to prevent stored-XSS.", "operationId": "serve_agent_run_attachment_api_v2_agent_runs__run_id__attachments__attachment_id__get", "parameters": [ { @@ -21161,6 +26370,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Download an agent-run attachment", @@ -21191,6 +26418,24 @@ } }, "description": "Successful Response" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Get the account's API version", @@ -21239,6 +26484,24 @@ } }, "description": "Validation Error" + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceUnavailableError" + } + } + }, + "description": "A dependency is unavailable. `database_unavailable` is temporary (for example routine maintenance) and carries a `Retry-After` header, after which the request can be retried unchanged. `vector_store_unavailable` means the vector store backing an embeddings operation is not configured; it carries no `Retry-After` because it does not clear without an operator.", + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying. Sent only with `database_unavailable`.", + "schema": { + "type": "integer" + } + } + } } }, "summary": "Pin (or clear) the account's API version", @@ -21260,8 +26523,13 @@ "default": "2026-07-01", "known": [ "2026-07-01", - "2026-07-27" + "2026-07-27", + "2026-08-03", + "2026-08-21", + "2026-09-28", + "2026-09-30", + "2026-10-03" ], - "latest": "2026-07-27" + "latest": "2026-10-03" } } diff --git a/pyproject.toml b/pyproject.toml index 2b8abce..74719eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -136,7 +136,7 @@ filterwarnings = [ ] [tool.ruff] -target-version = "py313" +target-version = "py311" line-length = 88 exclude = [ # Vendored from seclai/sdk-tools via git subtree — formatting it here would diff --git a/seclai/__init__.py b/seclai/__init__.py index e256d5c..3aab514 100644 --- a/seclai/__init__.py +++ b/seclai/__init__.py @@ -20,6 +20,10 @@ - :class:`SeclaiStreamingError` — SSE stream errors - :class:`AgentRunStreamRequest` — typed request body for streaming runs - :data:`JSONValue` — recursive JSON type alias +- :class:`ApiVersion` — dated API versions this release was built against +- :data:`DEFAULT_API_VERSION` / :data:`LATEST_API_VERSION` — the baseline and + newest known version +- :func:`unwrap_items` — read a version-gated list response in either shape """ from .auth import ( diff --git a/seclai/_generated/api/agent_evaluations/create_evaluation_criteria_api_agents_agent_id_evaluation_criteria_post.py b/seclai/_generated/api/agent_evaluations/create_evaluation_criteria_api_agents_agent_id_evaluation_criteria_post.py index 637de7c..1295105 100644 --- a/seclai/_generated/api/agent_evaluations/create_evaluation_criteria_api_agents_agent_id_evaluation_criteria_post.py +++ b/seclai/_generated/api/agent_evaluations/create_evaluation_criteria_api_agents_agent_id_evaluation_criteria_post.py @@ -10,6 +10,7 @@ from ...models.create_evaluation_criteria_request import CreateEvaluationCriteriaRequest from ...models.evaluation_criteria_response import EvaluationCriteriaResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EvaluationCriteriaResponse | HTTPValidationError | None: +) -> EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 201: response_201 = EvaluationCriteriaResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EvaluationCriteriaResponse | HTTPValidationError]: +) -> Response[ + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +87,9 @@ def sync_detailed( body: CreateEvaluationCriteriaRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationCriteriaResponse | HTTPValidationError]: +) -> Response[ + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError +]: """Create Evaluation Criteria Create new step evaluation settings for an agent. @@ -101,7 +111,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationCriteriaResponse | HTTPValidationError] + Response[EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -125,7 +135,7 @@ def sync( body: CreateEvaluationCriteriaRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationCriteriaResponse | HTTPValidationError | None: +) -> EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError | None: """Create Evaluation Criteria Create new step evaluation settings for an agent. @@ -147,7 +157,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationCriteriaResponse | HTTPValidationError + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -166,7 +176,9 @@ async def asyncio_detailed( body: CreateEvaluationCriteriaRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationCriteriaResponse | HTTPValidationError]: +) -> Response[ + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError +]: """Create Evaluation Criteria Create new step evaluation settings for an agent. @@ -188,7 +200,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationCriteriaResponse | HTTPValidationError] + Response[EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -210,7 +222,7 @@ async def asyncio( body: CreateEvaluationCriteriaRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationCriteriaResponse | HTTPValidationError | None: +) -> EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError | None: """Create Evaluation Criteria Create new step evaluation settings for an agent. @@ -232,7 +244,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationCriteriaResponse | HTTPValidationError + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/create_evaluation_result_api_agents_evaluation_criteria_criteria_id_results_post.py b/seclai/_generated/api/agent_evaluations/create_evaluation_result_api_agents_evaluation_criteria_criteria_id_results_post.py index 9aa25c5..ccbe549 100644 --- a/seclai/_generated/api/agent_evaluations/create_evaluation_result_api_agents_evaluation_criteria_criteria_id_results_post.py +++ b/seclai/_generated/api/agent_evaluations/create_evaluation_result_api_agents_evaluation_criteria_criteria_id_results_post.py @@ -10,6 +10,7 @@ from ...models.create_evaluation_result_request import CreateEvaluationResultRequest from ...models.evaluation_result_response import EvaluationResultResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EvaluationResultResponse | HTTPValidationError | None: +) -> EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 201: response_201 = EvaluationResultResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EvaluationResultResponse | HTTPValidationError]: +) -> Response[EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: CreateEvaluationResultRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationResultResponse | HTTPValidationError]: +) -> Response[EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError]: """Create Evaluation Result Record an evaluation result for a criteria. @@ -99,7 +105,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationResultResponse | HTTPValidationError] + Response[EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -123,7 +129,7 @@ def sync( body: CreateEvaluationResultRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationResultResponse | HTTPValidationError | None: +) -> EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError | None: """Create Evaluation Result Record an evaluation result for a criteria. @@ -143,7 +149,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationResultResponse | HTTPValidationError + EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -162,7 +168,7 @@ async def asyncio_detailed( body: CreateEvaluationResultRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationResultResponse | HTTPValidationError]: +) -> Response[EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError]: """Create Evaluation Result Record an evaluation result for a criteria. @@ -182,7 +188,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationResultResponse | HTTPValidationError] + Response[EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -204,7 +210,7 @@ async def asyncio( body: CreateEvaluationResultRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationResultResponse | HTTPValidationError | None: +) -> EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError | None: """Create Evaluation Result Record an evaluation result for a criteria. @@ -224,7 +230,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationResultResponse | HTTPValidationError + EvaluationResultResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/delete_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_delete.py b/seclai/_generated/api/agent_evaluations/delete_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_delete.py index cd2cf4c..f6c57f6 100644 --- a/seclai/_generated/api/agent_evaluations/delete_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_delete.py +++ b/seclai/_generated/api/agent_evaluations/delete_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Evaluation Criteria Delete an evaluation criteria and all associated evaluation results. @@ -88,7 +94,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -110,7 +116,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Evaluation Criteria Delete an evaluation criteria and all associated evaluation results. @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Evaluation Criteria Delete an evaluation criteria and all associated evaluation results. @@ -163,7 +169,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Evaluation Criteria Delete an evaluation criteria and all associated evaluation results. @@ -201,7 +207,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/get_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_get.py b/seclai/_generated/api/agent_evaluations/get_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_get.py index a2a92ba..ae2315c 100644 --- a/seclai/_generated/api/agent_evaluations/get_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_get.py +++ b/seclai/_generated/api/agent_evaluations/get_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.evaluation_criteria_response import EvaluationCriteriaResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EvaluationCriteriaResponse | HTTPValidationError | None: +) -> EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = EvaluationCriteriaResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EvaluationCriteriaResponse | HTTPValidationError]: +) -> Response[ + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +80,9 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationCriteriaResponse | HTTPValidationError]: +) -> Response[ + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError +]: """Get Evaluation Criteria Get a single evaluation criteria by ID. @@ -90,7 +100,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationCriteriaResponse | HTTPValidationError] + Response[EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -112,7 +122,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationCriteriaResponse | HTTPValidationError | None: +) -> EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError | None: """Get Evaluation Criteria Get a single evaluation criteria by ID. @@ -130,7 +140,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationCriteriaResponse | HTTPValidationError + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -147,7 +157,9 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationCriteriaResponse | HTTPValidationError]: +) -> Response[ + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError +]: """Get Evaluation Criteria Get a single evaluation criteria by ID. @@ -165,7 +177,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationCriteriaResponse | HTTPValidationError] + Response[EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -185,7 +197,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationCriteriaResponse | HTTPValidationError | None: +) -> EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError | None: """Get Evaluation Criteria Get a single evaluation criteria by ID. @@ -203,7 +215,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationCriteriaResponse | HTTPValidationError + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/get_evaluation_summary_api_agents_evaluation_criteria_criteria_id_summary_get.py b/seclai/_generated/api/agent_evaluations/get_evaluation_summary_api_agents_evaluation_criteria_criteria_id_summary_get.py index 0c24f4c..7a9f366 100644 --- a/seclai/_generated/api/agent_evaluations/get_evaluation_summary_api_agents_evaluation_criteria_criteria_id_summary_get.py +++ b/seclai/_generated/api/agent_evaluations/get_evaluation_summary_api_agents_evaluation_criteria_criteria_id_summary_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.evaluation_result_summary_response import EvaluationResultSummaryResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EvaluationResultSummaryResponse | HTTPValidationError | None: +) -> ( + EvaluationResultSummaryResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = EvaluationResultSummaryResponse.from_dict(response.json()) @@ -49,6 +55,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +68,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EvaluationResultSummaryResponse | HTTPValidationError]: +) -> Response[ + EvaluationResultSummaryResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +85,9 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationResultSummaryResponse | HTTPValidationError]: +) -> Response[ + EvaluationResultSummaryResponse | HTTPValidationError | ServiceUnavailableError +]: """Get Evaluation Summary Get an aggregated summary of evaluation results for a criteria. @@ -90,7 +105,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationResultSummaryResponse | HTTPValidationError] + Response[EvaluationResultSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -112,7 +127,12 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationResultSummaryResponse | HTTPValidationError | None: +) -> ( + EvaluationResultSummaryResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Get Evaluation Summary Get an aggregated summary of evaluation results for a criteria. @@ -130,7 +150,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationResultSummaryResponse | HTTPValidationError + EvaluationResultSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -147,7 +167,9 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationResultSummaryResponse | HTTPValidationError]: +) -> Response[ + EvaluationResultSummaryResponse | HTTPValidationError | ServiceUnavailableError +]: """Get Evaluation Summary Get an aggregated summary of evaluation results for a criteria. @@ -165,7 +187,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationResultSummaryResponse | HTTPValidationError] + Response[EvaluationResultSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -185,7 +207,12 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationResultSummaryResponse | HTTPValidationError | None: +) -> ( + EvaluationResultSummaryResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Get Evaluation Summary Get an aggregated summary of evaluation results for a criteria. @@ -203,7 +230,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationResultSummaryResponse | HTTPValidationError + EvaluationResultSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/get_non_manual_evaluation_summary_api_agents_evaluation_results_non_manual_summary_get.py b/seclai/_generated/api/agent_evaluations/get_non_manual_evaluation_summary_api_agents_evaluation_results_non_manual_summary_get.py index a6d81bd..9bd990a 100644 --- a/seclai/_generated/api/agent_evaluations/get_non_manual_evaluation_summary_api_agents_evaluation_results_non_manual_summary_get.py +++ b/seclai/_generated/api/agent_evaluations/get_non_manual_evaluation_summary_api_agents_evaluation_results_non_manual_summary_get.py @@ -10,6 +10,7 @@ from ...models.non_manual_evaluation_summary_response import ( NonManualEvaluationSummaryResponse, ) +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -68,7 +69,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | NonManualEvaluationSummaryResponse | None: +) -> ( + HTTPValidationError + | NonManualEvaluationSummaryResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = NonManualEvaluationSummaryResponse.from_dict(response.json()) @@ -79,6 +85,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -87,7 +98,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | NonManualEvaluationSummaryResponse]: +) -> Response[ + HTTPValidationError | NonManualEvaluationSummaryResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -105,7 +118,9 @@ def sync_detailed( end_date: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | NonManualEvaluationSummaryResponse]: +) -> Response[ + HTTPValidationError | NonManualEvaluationSummaryResponse | ServiceUnavailableError +]: """Get Non Manual Evaluation Summary Get an evaluation summary for API key clients. @@ -132,7 +147,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | NonManualEvaluationSummaryResponse] + Response[HTTPValidationError | NonManualEvaluationSummaryResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -160,7 +175,12 @@ def sync( end_date: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | NonManualEvaluationSummaryResponse | None: +) -> ( + HTTPValidationError + | NonManualEvaluationSummaryResponse + | ServiceUnavailableError + | None +): """Get Non Manual Evaluation Summary Get an evaluation summary for API key clients. @@ -187,7 +207,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | NonManualEvaluationSummaryResponse + HTTPValidationError | NonManualEvaluationSummaryResponse | ServiceUnavailableError """ return sync_detailed( @@ -210,7 +230,9 @@ async def asyncio_detailed( end_date: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | NonManualEvaluationSummaryResponse]: +) -> Response[ + HTTPValidationError | NonManualEvaluationSummaryResponse | ServiceUnavailableError +]: """Get Non Manual Evaluation Summary Get an evaluation summary for API key clients. @@ -237,7 +259,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | NonManualEvaluationSummaryResponse] + Response[HTTPValidationError | NonManualEvaluationSummaryResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -263,7 +285,12 @@ async def asyncio( end_date: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | NonManualEvaluationSummaryResponse | None: +) -> ( + HTTPValidationError + | NonManualEvaluationSummaryResponse + | ServiceUnavailableError + | None +): """Get Non Manual Evaluation Summary Get an evaluation summary for API key clients. @@ -290,7 +317,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | NonManualEvaluationSummaryResponse + HTTPValidationError | NonManualEvaluationSummaryResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/list_agent_evaluation_results_api_agents_agent_id_evaluation_results_get.py b/seclai/_generated/api/agent_evaluations/list_agent_evaluation_results_api_agents_agent_id_evaluation_results_get.py index 2c5a561..9bdcdc3 100644 --- a/seclai/_generated/api/agent_evaluations/list_agent_evaluation_results_api_agents_agent_id_evaluation_results_get.py +++ b/seclai/_generated/api/agent_evaluations/list_agent_evaluation_results_api_agents_agent_id_evaluation_results_get.py @@ -11,6 +11,7 @@ EvaluationResultWithCriteriaListResponse, ) from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -86,7 +87,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EvaluationResultWithCriteriaListResponse | HTTPValidationError | None: +) -> ( + EvaluationResultWithCriteriaListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = EvaluationResultWithCriteriaListResponse.from_dict( response.json() @@ -99,6 +105,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -107,7 +118,11 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EvaluationResultWithCriteriaListResponse | HTTPValidationError]: +) -> Response[ + EvaluationResultWithCriteriaListResponse + | HTTPValidationError + | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -129,7 +144,11 @@ def sync_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationResultWithCriteriaListResponse | HTTPValidationError]: +) -> Response[ + EvaluationResultWithCriteriaListResponse + | HTTPValidationError + | ServiceUnavailableError +]: """List Agent Evaluation Results List evaluation results across all criteria configured on an agent. @@ -154,7 +173,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationResultWithCriteriaListResponse | HTTPValidationError] + Response[EvaluationResultWithCriteriaListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -190,7 +209,12 @@ def sync( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationResultWithCriteriaListResponse | HTTPValidationError | None: +) -> ( + EvaluationResultWithCriteriaListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """List Agent Evaluation Results List evaluation results across all criteria configured on an agent. @@ -215,7 +239,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationResultWithCriteriaListResponse | HTTPValidationError + EvaluationResultWithCriteriaListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -246,7 +270,11 @@ async def asyncio_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationResultWithCriteriaListResponse | HTTPValidationError]: +) -> Response[ + EvaluationResultWithCriteriaListResponse + | HTTPValidationError + | ServiceUnavailableError +]: """List Agent Evaluation Results List evaluation results across all criteria configured on an agent. @@ -271,7 +299,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationResultWithCriteriaListResponse | HTTPValidationError] + Response[EvaluationResultWithCriteriaListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -305,7 +333,12 @@ async def asyncio( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationResultWithCriteriaListResponse | HTTPValidationError | None: +) -> ( + EvaluationResultWithCriteriaListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """List Agent Evaluation Results List evaluation results across all criteria configured on an agent. @@ -330,7 +363,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationResultWithCriteriaListResponse | HTTPValidationError + EvaluationResultWithCriteriaListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/list_compatible_runs_api_agents_evaluation_criteria_criteria_id_compatible_runs_get.py b/seclai/_generated/api/agent_evaluations/list_compatible_runs_api_agents_evaluation_criteria_criteria_id_compatible_runs_get.py index c3bf3dc..5db08d3 100644 --- a/seclai/_generated/api/agent_evaluations/list_compatible_runs_api_agents_evaluation_criteria_criteria_id_compatible_runs_get.py +++ b/seclai/_generated/api/agent_evaluations/list_compatible_runs_api_agents_evaluation_criteria_criteria_id_compatible_runs_get.py @@ -10,6 +10,7 @@ from ...client import AuthenticatedClient, Client from ...models.compatible_run_list_response import CompatibleRunListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -60,7 +61,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> CompatibleRunListResponse | HTTPValidationError | None: +) -> CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = CompatibleRunListResponse.from_dict(response.json()) @@ -71,6 +72,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -79,7 +85,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[CompatibleRunListResponse | HTTPValidationError]: +) -> Response[ + CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -97,7 +105,9 @@ def sync_detailed( started_after: datetime.datetime | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CompatibleRunListResponse | HTTPValidationError]: +) -> Response[ + CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError +]: """List Compatible Runs List agent runs that have a completed step matching the criteria's target step. @@ -118,7 +128,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CompatibleRunListResponse | HTTPValidationError] + Response[CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -146,7 +156,7 @@ def sync( started_after: datetime.datetime | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CompatibleRunListResponse | HTTPValidationError | None: +) -> CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError | None: """List Compatible Runs List agent runs that have a completed step matching the criteria's target step. @@ -167,7 +177,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CompatibleRunListResponse | HTTPValidationError + CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -190,7 +200,9 @@ async def asyncio_detailed( started_after: datetime.datetime | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CompatibleRunListResponse | HTTPValidationError]: +) -> Response[ + CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError +]: """List Compatible Runs List agent runs that have a completed step matching the criteria's target step. @@ -211,7 +223,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CompatibleRunListResponse | HTTPValidationError] + Response[CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -237,7 +249,7 @@ async def asyncio( started_after: datetime.datetime | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CompatibleRunListResponse | HTTPValidationError | None: +) -> CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError | None: """List Compatible Runs List agent runs that have a completed step matching the criteria's target step. @@ -258,7 +270,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CompatibleRunListResponse | HTTPValidationError + CompatibleRunListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/list_evaluation_criteria_api_agents_agent_id_evaluation_criteria_get.py b/seclai/_generated/api/agent_evaluations/list_evaluation_criteria_api_agents_agent_id_evaluation_criteria_get.py index 6b73a46..9588c72 100644 --- a/seclai/_generated/api/agent_evaluations/list_evaluation_criteria_api_agents_agent_id_evaluation_criteria_get.py +++ b/seclai/_generated/api/agent_evaluations/list_evaluation_criteria_api_agents_agent_id_evaluation_criteria_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.evaluation_criteria_response import EvaluationCriteriaResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -49,7 +50,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | list[EvaluationCriteriaResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[EvaluationCriteriaResponse] + | None +): if response.status_code == 200: response_200 = [] _response_200 = response.json() @@ -67,6 +73,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -75,7 +86,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | list[EvaluationCriteriaResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[EvaluationCriteriaResponse] +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -92,7 +105,9 @@ def sync_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[EvaluationCriteriaResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[EvaluationCriteriaResponse] +]: """List Evaluation Criteria List evaluation criteria configured for an agent. @@ -121,7 +136,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[EvaluationCriteriaResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[EvaluationCriteriaResponse]] """ kwargs = _get_kwargs( @@ -147,7 +162,12 @@ def sync( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[EvaluationCriteriaResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[EvaluationCriteriaResponse] + | None +): """List Evaluation Criteria List evaluation criteria configured for an agent. @@ -176,7 +196,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[EvaluationCriteriaResponse] + HTTPValidationError | ServiceUnavailableError | list[EvaluationCriteriaResponse] """ return sync_detailed( @@ -197,7 +217,9 @@ async def asyncio_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[EvaluationCriteriaResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[EvaluationCriteriaResponse] +]: """List Evaluation Criteria List evaluation criteria configured for an agent. @@ -226,7 +248,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[EvaluationCriteriaResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[EvaluationCriteriaResponse]] """ kwargs = _get_kwargs( @@ -250,7 +272,12 @@ async def asyncio( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[EvaluationCriteriaResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[EvaluationCriteriaResponse] + | None +): """List Evaluation Criteria List evaluation criteria configured for an agent. @@ -279,7 +306,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[EvaluationCriteriaResponse] + HTTPValidationError | ServiceUnavailableError | list[EvaluationCriteriaResponse] """ return ( diff --git a/seclai/_generated/api/agent_evaluations/list_evaluation_results_api_agents_evaluation_criteria_criteria_id_results_get.py b/seclai/_generated/api/agent_evaluations/list_evaluation_results_api_agents_evaluation_criteria_criteria_id_results_get.py index 18c8999..25d951c 100644 --- a/seclai/_generated/api/agent_evaluations/list_evaluation_results_api_agents_evaluation_criteria_criteria_id_results_get.py +++ b/seclai/_generated/api/agent_evaluations/list_evaluation_results_api_agents_evaluation_criteria_criteria_id_results_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.evaluation_result_list_response import EvaluationResultListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -76,7 +77,9 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EvaluationResultListResponse | HTTPValidationError | None: +) -> ( + EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError | None +): if response.status_code == 200: response_200 = EvaluationResultListResponse.from_dict(response.json()) @@ -87,6 +90,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -95,7 +103,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EvaluationResultListResponse | HTTPValidationError]: +) -> Response[ + EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -116,7 +126,9 @@ def sync_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationResultListResponse | HTTPValidationError]: +) -> Response[ + EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError +]: """List Evaluation Results List evaluation results for a criteria with optional filtering. @@ -141,7 +153,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationResultListResponse | HTTPValidationError] + Response[EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -175,7 +187,9 @@ def sync( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationResultListResponse | HTTPValidationError | None: +) -> ( + EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError | None +): """List Evaluation Results List evaluation results for a criteria with optional filtering. @@ -200,7 +214,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationResultListResponse | HTTPValidationError + EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -229,7 +243,9 @@ async def asyncio_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationResultListResponse | HTTPValidationError]: +) -> Response[ + EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError +]: """List Evaluation Results List evaluation results for a criteria with optional filtering. @@ -254,7 +270,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationResultListResponse | HTTPValidationError] + Response[EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -286,7 +302,9 @@ async def asyncio( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationResultListResponse | HTTPValidationError | None: +) -> ( + EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError | None +): """List Evaluation Results List evaluation results for a criteria with optional filtering. @@ -311,7 +329,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationResultListResponse | HTTPValidationError + EvaluationResultListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/list_evaluation_runs_api_agents_agent_id_evaluation_runs_get.py b/seclai/_generated/api/agent_evaluations/list_evaluation_runs_api_agents_agent_id_evaluation_runs_get.py index 68f8ea3..8516f41 100644 --- a/seclai/_generated/api/agent_evaluations/list_evaluation_runs_api_agents_agent_id_evaluation_runs_get.py +++ b/seclai/_generated/api/agent_evaluations/list_evaluation_runs_api_agents_agent_id_evaluation_runs_get.py @@ -11,6 +11,7 @@ EvaluationRunSummaryListResponse, ) from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -83,7 +84,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EvaluationRunSummaryListResponse | HTTPValidationError | None: +) -> ( + EvaluationRunSummaryListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = EvaluationRunSummaryListResponse.from_dict(response.json()) @@ -94,6 +100,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -102,7 +113,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EvaluationRunSummaryListResponse | HTTPValidationError]: +) -> Response[ + EvaluationRunSummaryListResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -123,7 +136,9 @@ def sync_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationRunSummaryListResponse | HTTPValidationError]: +) -> Response[ + EvaluationRunSummaryListResponse | HTTPValidationError | ServiceUnavailableError +]: """List Evaluation Runs List evaluation results grouped by agent run. @@ -147,7 +162,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationRunSummaryListResponse | HTTPValidationError] + Response[EvaluationRunSummaryListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -181,7 +196,12 @@ def sync( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationRunSummaryListResponse | HTTPValidationError | None: +) -> ( + EvaluationRunSummaryListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """List Evaluation Runs List evaluation results grouped by agent run. @@ -205,7 +225,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationRunSummaryListResponse | HTTPValidationError + EvaluationRunSummaryListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -234,7 +254,9 @@ async def asyncio_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationRunSummaryListResponse | HTTPValidationError]: +) -> Response[ + EvaluationRunSummaryListResponse | HTTPValidationError | ServiceUnavailableError +]: """List Evaluation Runs List evaluation results grouped by agent run. @@ -258,7 +280,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationRunSummaryListResponse | HTTPValidationError] + Response[EvaluationRunSummaryListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -290,7 +312,12 @@ async def asyncio( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationRunSummaryListResponse | HTTPValidationError | None: +) -> ( + EvaluationRunSummaryListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """List Evaluation Runs List evaluation results grouped by agent run. @@ -314,7 +341,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationRunSummaryListResponse | HTTPValidationError + EvaluationRunSummaryListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_evaluations/list_run_evaluation_results_api_agents_agent_id_runs_run_id_evaluation_results_get.py b/seclai/_generated/api/agent_evaluations/list_run_evaluation_results_api_agents_agent_id_runs_run_id_evaluation_results_get.py index 38485cc..44131b3 100644 --- a/seclai/_generated/api/agent_evaluations/list_run_evaluation_results_api_agents_agent_id_runs_run_id_evaluation_results_get.py +++ b/seclai/_generated/api/agent_evaluations/list_run_evaluation_results_api_agents_agent_id_runs_run_id_evaluation_results_get.py @@ -11,6 +11,7 @@ EvaluationResultWithCriteriaResponse, ) from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -53,7 +54,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | list[EvaluationResultWithCriteriaResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[EvaluationResultWithCriteriaResponse] + | None +): if response.status_code == 200: response_200 = [] _response_200 = response.json() @@ -71,6 +77,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -79,7 +90,11 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | list[EvaluationResultWithCriteriaResponse]]: +) -> Response[ + HTTPValidationError + | ServiceUnavailableError + | list[EvaluationResultWithCriteriaResponse] +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -97,7 +112,11 @@ def sync_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[EvaluationResultWithCriteriaResponse]]: +) -> Response[ + HTTPValidationError + | ServiceUnavailableError + | list[EvaluationResultWithCriteriaResponse] +]: """List Run Evaluation Results List evaluation results recorded for a specific agent run. @@ -126,7 +145,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[EvaluationResultWithCriteriaResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[EvaluationResultWithCriteriaResponse]] """ kwargs = _get_kwargs( @@ -154,7 +173,12 @@ def sync( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[EvaluationResultWithCriteriaResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[EvaluationResultWithCriteriaResponse] + | None +): """List Run Evaluation Results List evaluation results recorded for a specific agent run. @@ -183,7 +207,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[EvaluationResultWithCriteriaResponse] + HTTPValidationError | ServiceUnavailableError | list[EvaluationResultWithCriteriaResponse] """ return sync_detailed( @@ -206,7 +230,11 @@ async def asyncio_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[EvaluationResultWithCriteriaResponse]]: +) -> Response[ + HTTPValidationError + | ServiceUnavailableError + | list[EvaluationResultWithCriteriaResponse] +]: """List Run Evaluation Results List evaluation results recorded for a specific agent run. @@ -235,7 +263,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[EvaluationResultWithCriteriaResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[EvaluationResultWithCriteriaResponse]] """ kwargs = _get_kwargs( @@ -261,7 +289,12 @@ async def asyncio( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[EvaluationResultWithCriteriaResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[EvaluationResultWithCriteriaResponse] + | None +): """List Run Evaluation Results List evaluation results recorded for a specific agent run. @@ -290,7 +323,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[EvaluationResultWithCriteriaResponse] + HTTPValidationError | ServiceUnavailableError | list[EvaluationResultWithCriteriaResponse] """ return ( diff --git a/seclai/_generated/api/agent_evaluations/test_draft_evaluation_api_agents_agent_id_evaluation_criteria_test_draft_post.py b/seclai/_generated/api/agent_evaluations/test_draft_evaluation_api_agents_agent_id_evaluation_criteria_test_draft_post.py index 085008e..63b845d 100644 --- a/seclai/_generated/api/agent_evaluations/test_draft_evaluation_api_agents_agent_id_evaluation_criteria_test_draft_post.py +++ b/seclai/_generated/api/agent_evaluations/test_draft_evaluation_api_agents_agent_id_evaluation_criteria_test_draft_post.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.test_draft_evaluation_request import TestDraftEvaluationRequest from ...models.test_draft_evaluation_response import TestDraftEvaluationResponse from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | TestDraftEvaluationResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse | None: if response.status_code == 200: response_200 = TestDraftEvaluationResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | TestDraftEvaluationResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,14 +87,16 @@ def sync_detailed( body: TestDraftEvaluationRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | TestDraftEvaluationResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse +]: """Test Draft Evaluation Run an ephemeral evaluation against provided step output without persisting results. Use this to interactively test evaluation prompts and expectation - configurations while editing criteria. No credits are consumed because - the result is not recorded. + configurations while editing criteria. The evaluation is a billed LLM + call; only its result goes unrecorded. Args: agent_id (str): @@ -103,7 +113,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | TestDraftEvaluationResponse] + Response[HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse] """ kwargs = _get_kwargs( @@ -127,14 +137,14 @@ def sync( body: TestDraftEvaluationRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | TestDraftEvaluationResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse | None: """Test Draft Evaluation Run an ephemeral evaluation against provided step output without persisting results. Use this to interactively test evaluation prompts and expectation - configurations while editing criteria. No credits are consumed because - the result is not recorded. + configurations while editing criteria. The evaluation is a billed LLM + call; only its result goes unrecorded. Args: agent_id (str): @@ -151,7 +161,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | TestDraftEvaluationResponse + HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse """ return sync_detailed( @@ -170,14 +180,16 @@ async def asyncio_detailed( body: TestDraftEvaluationRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | TestDraftEvaluationResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse +]: """Test Draft Evaluation Run an ephemeral evaluation against provided step output without persisting results. Use this to interactively test evaluation prompts and expectation - configurations while editing criteria. No credits are consumed because - the result is not recorded. + configurations while editing criteria. The evaluation is a billed LLM + call; only its result goes unrecorded. Args: agent_id (str): @@ -194,7 +206,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | TestDraftEvaluationResponse] + Response[HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse] """ kwargs = _get_kwargs( @@ -216,14 +228,14 @@ async def asyncio( body: TestDraftEvaluationRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | TestDraftEvaluationResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse | None: """Test Draft Evaluation Run an ephemeral evaluation against provided step output without persisting results. Use this to interactively test evaluation prompts and expectation - configurations while editing criteria. No credits are consumed because - the result is not recorded. + configurations while editing criteria. The evaluation is a billed LLM + call; only its result goes unrecorded. Args: agent_id (str): @@ -240,7 +252,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | TestDraftEvaluationResponse + HTTPValidationError | ServiceUnavailableError | TestDraftEvaluationResponse """ return ( diff --git a/seclai/_generated/api/agent_evaluations/update_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_patch.py b/seclai/_generated/api/agent_evaluations/update_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_patch.py index 3d55150..4b4c456 100644 --- a/seclai/_generated/api/agent_evaluations/update_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_patch.py +++ b/seclai/_generated/api/agent_evaluations/update_evaluation_criteria_api_agents_evaluation_criteria_criteria_id_patch.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.evaluation_criteria_response import EvaluationCriteriaResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.update_evaluation_criteria_request import UpdateEvaluationCriteriaRequest from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EvaluationCriteriaResponse | HTTPValidationError | None: +) -> EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = EvaluationCriteriaResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EvaluationCriteriaResponse | HTTPValidationError]: +) -> Response[ + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +87,9 @@ def sync_detailed( body: UpdateEvaluationCriteriaRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationCriteriaResponse | HTTPValidationError]: +) -> Response[ + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError +]: """Update Evaluation Criteria Update an evaluation criteria. @@ -101,7 +111,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationCriteriaResponse | HTTPValidationError] + Response[EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -125,7 +135,7 @@ def sync( body: UpdateEvaluationCriteriaRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationCriteriaResponse | HTTPValidationError | None: +) -> EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError | None: """Update Evaluation Criteria Update an evaluation criteria. @@ -147,7 +157,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationCriteriaResponse | HTTPValidationError + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -166,7 +176,9 @@ async def asyncio_detailed( body: UpdateEvaluationCriteriaRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EvaluationCriteriaResponse | HTTPValidationError]: +) -> Response[ + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError +]: """Update Evaluation Criteria Update an evaluation criteria. @@ -188,7 +200,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EvaluationCriteriaResponse | HTTPValidationError] + Response[EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -210,7 +222,7 @@ async def asyncio( body: UpdateEvaluationCriteriaRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EvaluationCriteriaResponse | HTTPValidationError | None: +) -> EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError | None: """Update Evaluation Criteria Update an evaluation criteria. @@ -232,7 +244,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EvaluationCriteriaResponse | HTTPValidationError + EvaluationCriteriaResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agent_run_attachments/serve_agent_run_attachment_api_v2_agent_runs_run_id_attachments_attachment_id_get.py b/seclai/_generated/api/agent_run_attachments/serve_agent_run_attachment_api_v2_agent_runs_run_id_attachments_attachment_id_get.py index e232195..b6b0f94 100644 --- a/seclai/_generated/api/agent_run_attachments/serve_agent_run_attachment_api_v2_agent_runs_run_id_attachments_attachment_id_get.py +++ b/seclai/_generated/api/agent_run_attachments/serve_agent_run_attachment_api_v2_agent_runs_run_id_attachments_attachment_id_get.py @@ -9,6 +9,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, File, Response, Unset @@ -53,7 +54,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> File | HTTPValidationError | None: +) -> File | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = File(payload=BytesIO(response.content)) @@ -64,6 +65,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -72,7 +78,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[File | HTTPValidationError]: +) -> Response[File | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -89,18 +95,18 @@ def sync_detailed( download_name: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[File | HTTPValidationError]: +) -> Response[File | HTTPValidationError | ServiceUnavailableError]: """Download an agent-run attachment Streams the bytes of an attachment emitted by a step in the given agent run. ``attachment_id`` is - the URL-safe-base64-encoded ``storage_key`` (use the encoder shared by webhook + email payload - builders). + the ``id`` of an entry in the run's or a step's ``attachments``, or the URL-safe-base64-encoded + storage key, which webhook and email links carry. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. - The calling account must own ``run_id``; lookup failures (missing run, cross-account run, soft- - deleted agent, unreferenced storage_key) all collapse to a single 404 to prevent cross-tenant - existence enumeration. + deleted agent, a run whose trace was purged, a file not in the run) all collapse to a single 404 to + prevent cross-tenant existence enumeration. MIME handling: - Inline-safe MIMEs (image/*, audio/*, video/*, application/pdf, text/plain, @@ -120,7 +126,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[File | HTTPValidationError] + Response[File | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -146,18 +152,18 @@ def sync( download_name: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> File | HTTPValidationError | None: +) -> File | HTTPValidationError | ServiceUnavailableError | None: """Download an agent-run attachment Streams the bytes of an attachment emitted by a step in the given agent run. ``attachment_id`` is - the URL-safe-base64-encoded ``storage_key`` (use the encoder shared by webhook + email payload - builders). + the ``id`` of an entry in the run's or a step's ``attachments``, or the URL-safe-base64-encoded + storage key, which webhook and email links carry. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. - The calling account must own ``run_id``; lookup failures (missing run, cross-account run, soft- - deleted agent, unreferenced storage_key) all collapse to a single 404 to prevent cross-tenant - existence enumeration. + deleted agent, a run whose trace was purged, a file not in the run) all collapse to a single 404 to + prevent cross-tenant existence enumeration. MIME handling: - Inline-safe MIMEs (image/*, audio/*, video/*, application/pdf, text/plain, @@ -177,7 +183,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - File | HTTPValidationError + File | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -198,18 +204,18 @@ async def asyncio_detailed( download_name: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[File | HTTPValidationError]: +) -> Response[File | HTTPValidationError | ServiceUnavailableError]: """Download an agent-run attachment Streams the bytes of an attachment emitted by a step in the given agent run. ``attachment_id`` is - the URL-safe-base64-encoded ``storage_key`` (use the encoder shared by webhook + email payload - builders). + the ``id`` of an entry in the run's or a step's ``attachments``, or the URL-safe-base64-encoded + storage key, which webhook and email links carry. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. - The calling account must own ``run_id``; lookup failures (missing run, cross-account run, soft- - deleted agent, unreferenced storage_key) all collapse to a single 404 to prevent cross-tenant - existence enumeration. + deleted agent, a run whose trace was purged, a file not in the run) all collapse to a single 404 to + prevent cross-tenant existence enumeration. MIME handling: - Inline-safe MIMEs (image/*, audio/*, video/*, application/pdf, text/plain, @@ -229,7 +235,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[File | HTTPValidationError] + Response[File | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -253,18 +259,18 @@ async def asyncio( download_name: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> File | HTTPValidationError | None: +) -> File | HTTPValidationError | ServiceUnavailableError | None: """Download an agent-run attachment Streams the bytes of an attachment emitted by a step in the given agent run. ``attachment_id`` is - the URL-safe-base64-encoded ``storage_key`` (use the encoder shared by webhook + email payload - builders). + the ``id`` of an entry in the run's or a step's ``attachments``, or the URL-safe-base64-encoded + storage key, which webhook and email links carry. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. - The calling account must own ``run_id``; lookup failures (missing run, cross-account run, soft- - deleted agent, unreferenced storage_key) all collapse to a single 404 to prevent cross-tenant - existence enumeration. + deleted agent, a run whose trace was purged, a file not in the run) all collapse to a single 404 to + prevent cross-tenant existence enumeration. MIME handling: - Inline-safe MIMEs (image/*, audio/*, video/*, application/pdf, text/plain, @@ -284,7 +290,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - File | HTTPValidationError + File | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/api_get_agent_attachment_references_api_agents_agent_id_attachment_references_get.py b/seclai/_generated/api/agents/api_get_agent_attachment_references_api_agents_agent_id_attachment_references_get.py index 80625a3..8a21071 100644 --- a/seclai/_generated/api/agents/api_get_agent_attachment_references_api_agents_agent_id_attachment_references_get.py +++ b/seclai/_generated/api/agents/api_get_agent_attachment_references_api_agents_agent_id_attachment_references_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_attachment_refs_api_response import AgentAttachmentRefsApiResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentAttachmentRefsApiResponse | HTTPValidationError | None: +) -> ( + AgentAttachmentRefsApiResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = AgentAttachmentRefsApiResponse.from_dict(response.json()) @@ -49,6 +55,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +68,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentAttachmentRefsApiResponse | HTTPValidationError]: +) -> Response[ + AgentAttachmentRefsApiResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +85,9 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentAttachmentRefsApiResponse | HTTPValidationError]: +) -> Response[ + AgentAttachmentRefsApiResponse | HTTPValidationError | ServiceUnavailableError +]: """Get agent attachment-reference contract Return the static attachment-reference contract for an agent — what files the agent's definition @@ -92,7 +107,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentAttachmentRefsApiResponse | HTTPValidationError] + Response[AgentAttachmentRefsApiResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +129,12 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentAttachmentRefsApiResponse | HTTPValidationError | None: +) -> ( + AgentAttachmentRefsApiResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Get agent attachment-reference contract Return the static attachment-reference contract for an agent — what files the agent's definition @@ -134,7 +154,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentAttachmentRefsApiResponse | HTTPValidationError + AgentAttachmentRefsApiResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -151,7 +171,9 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentAttachmentRefsApiResponse | HTTPValidationError]: +) -> Response[ + AgentAttachmentRefsApiResponse | HTTPValidationError | ServiceUnavailableError +]: """Get agent attachment-reference contract Return the static attachment-reference contract for an agent — what files the agent's definition @@ -171,7 +193,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentAttachmentRefsApiResponse | HTTPValidationError] + Response[AgentAttachmentRefsApiResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -191,7 +213,12 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentAttachmentRefsApiResponse | HTTPValidationError | None: +) -> ( + AgentAttachmentRefsApiResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Get agent attachment-reference contract Return the static attachment-reference contract for an agent — what files the agent's definition @@ -211,7 +238,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentAttachmentRefsApiResponse | HTTPValidationError + AgentAttachmentRefsApiResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/api_get_agent_input_upload_status_api_agents_agent_id_input_uploads_upload_id_get.py b/seclai/_generated/api/agents/api_get_agent_input_upload_status_api_agents_agent_id_input_uploads_upload_id_get.py index fbc5296..fda68c6 100644 --- a/seclai/_generated/api/agents/api_get_agent_input_upload_status_api_agents_agent_id_input_uploads_upload_id_get.py +++ b/seclai/_generated/api/agents/api_get_agent_input_upload_status_api_agents_agent_id_input_uploads_upload_id_get.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.upload_agent_input_api_response import UploadAgentInputApiResponse from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | UploadAgentInputApiResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse | None: if response.status_code == 200: response_200 = UploadAgentInputApiResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | UploadAgentInputApiResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -75,7 +83,9 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | UploadAgentInputApiResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse +]: """Get upload status Poll the processing status of a file upload created via `POST /agents/{agent_id}/upload-input`. @@ -97,7 +107,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | UploadAgentInputApiResponse] + Response[HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse] """ kwargs = _get_kwargs( @@ -121,7 +131,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | UploadAgentInputApiResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse | None: """Get upload status Poll the processing status of a file upload created via `POST /agents/{agent_id}/upload-input`. @@ -143,7 +153,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | UploadAgentInputApiResponse + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse """ return sync_detailed( @@ -162,7 +172,9 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | UploadAgentInputApiResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse +]: """Get upload status Poll the processing status of a file upload created via `POST /agents/{agent_id}/upload-input`. @@ -184,7 +196,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | UploadAgentInputApiResponse] + Response[HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse] """ kwargs = _get_kwargs( @@ -206,7 +218,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | UploadAgentInputApiResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse | None: """Get upload status Poll the processing status of a file upload created via `POST /agents/{agent_id}/upload-input`. @@ -228,7 +240,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | UploadAgentInputApiResponse + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse """ return ( diff --git a/seclai/_generated/api/agents/api_upload_agent_input_api_agents_agent_id_upload_input_post.py b/seclai/_generated/api/agents/api_upload_agent_input_api_agents_agent_id_upload_input_post.py index 13d2be3..a37b599 100644 --- a/seclai/_generated/api/agents/api_upload_agent_input_api_agents_agent_id_upload_input_post.py +++ b/seclai/_generated/api/agents/api_upload_agent_input_api_agents_agent_id_upload_input_post.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.upload_agent_input_api_response import UploadAgentInputApiResponse from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | UploadAgentInputApiResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse | None: if response.status_code == 202: response_202 = UploadAgentInputApiResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | UploadAgentInputApiResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +80,9 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | UploadAgentInputApiResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse +]: """Upload file input Upload a file to use as input for a `dynamic_input` agent run. @@ -109,7 +119,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | UploadAgentInputApiResponse] + Response[HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse] """ kwargs = _get_kwargs( @@ -131,7 +141,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | UploadAgentInputApiResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse | None: """Upload file input Upload a file to use as input for a `dynamic_input` agent run. @@ -168,7 +178,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | UploadAgentInputApiResponse + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse """ return sync_detailed( @@ -185,7 +195,9 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | UploadAgentInputApiResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse +]: """Upload file input Upload a file to use as input for a `dynamic_input` agent run. @@ -222,7 +234,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | UploadAgentInputApiResponse] + Response[HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse] """ kwargs = _get_kwargs( @@ -242,7 +254,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | UploadAgentInputApiResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse | None: """Upload file input Upload a file to use as input for a `dynamic_input` agent run. @@ -279,7 +291,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | UploadAgentInputApiResponse + HTTPValidationError | ServiceUnavailableError | UploadAgentInputApiResponse """ return ( diff --git a/seclai/_generated/api/agents/block_email_sender_api_api_agents_blocked_email_senders_post.py b/seclai/_generated/api/agents/block_email_sender_api_api_agents_blocked_email_senders_post.py index ca6e931..de4ad04 100644 --- a/seclai/_generated/api/agents/block_email_sender_api_api_agents_blocked_email_senders_post.py +++ b/seclai/_generated/api/agents/block_email_sender_api_api_agents_blocked_email_senders_post.py @@ -9,6 +9,7 @@ from ...models.block_email_sender_request import BlockEmailSenderRequest from ...models.blocked_email_sender_response import BlockedEmailSenderResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> BlockedEmailSenderResponse | HTTPValidationError | None: +) -> BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 201: response_201 = BlockedEmailSenderResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[BlockedEmailSenderResponse | HTTPValidationError]: +) -> Response[ + BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +82,9 @@ def sync_detailed( body: BlockEmailSenderRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[BlockedEmailSenderResponse | HTTPValidationError]: +) -> Response[ + BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError +]: """Block an inbound email sender or domain Add a sender address or a whole domain to the account blocklist (idempotent; `match_type` is @@ -94,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[BlockedEmailSenderResponse | HTTPValidationError] + Response[BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -116,7 +126,7 @@ def sync( body: BlockEmailSenderRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> BlockedEmailSenderResponse | HTTPValidationError | None: +) -> BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError | None: """Block an inbound email sender or domain Add a sender address or a whole domain to the account blocklist (idempotent; `match_type` is @@ -136,7 +146,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - BlockedEmailSenderResponse | HTTPValidationError + BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -153,7 +163,9 @@ async def asyncio_detailed( body: BlockEmailSenderRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[BlockedEmailSenderResponse | HTTPValidationError]: +) -> Response[ + BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError +]: """Block an inbound email sender or domain Add a sender address or a whole domain to the account blocklist (idempotent; `match_type` is @@ -173,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[BlockedEmailSenderResponse | HTTPValidationError] + Response[BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -193,7 +205,7 @@ async def asyncio( body: BlockEmailSenderRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> BlockedEmailSenderResponse | HTTPValidationError | None: +) -> BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError | None: """Block an inbound email sender or domain Add a sender address or a whole domain to the account blocklist (idempotent; `match_type` is @@ -213,7 +225,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - BlockedEmailSenderResponse | HTTPValidationError + BlockedEmailSenderResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/cancel_queued_email_runs_api_api_agents_inbound_email_status_cancel_queued_post.py b/seclai/_generated/api/agents/cancel_queued_email_runs_api_api_agents_inbound_email_status_cancel_queued_post.py index dcc7889..0d4b57a 100644 --- a/seclai/_generated/api/agents/cancel_queued_email_runs_api_api_agents_inbound_email_status_cancel_queued_post.py +++ b/seclai/_generated/api/agents/cancel_queued_email_runs_api_api_agents_inbound_email_status_cancel_queued_post.py @@ -7,6 +7,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.cancel_queued_runs_response import CancelQueuedRunsResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -33,12 +34,17 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> CancelQueuedRunsResponse | None: +) -> CancelQueuedRunsResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = CancelQueuedRunsResponse.from_dict(response.json()) return response_200 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -47,7 +53,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[CancelQueuedRunsResponse]: +) -> Response[CancelQueuedRunsResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -61,11 +67,11 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CancelQueuedRunsResponse]: +) -> Response[CancelQueuedRunsResponse | ServiceUnavailableError]: """Cancel all queued inbound-email runs - Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run - consumed no quota or credits at queue time, so this merely fails them. Returns the count cancelled. + Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run has + consumed no quota, so this merely fails them. Returns the count cancelled. Auth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account. @@ -79,7 +85,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CancelQueuedRunsResponse] + Response[CancelQueuedRunsResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -99,11 +105,11 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CancelQueuedRunsResponse | None: +) -> CancelQueuedRunsResponse | ServiceUnavailableError | None: """Cancel all queued inbound-email runs - Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run - consumed no quota or credits at queue time, so this merely fails them. Returns the count cancelled. + Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run has + consumed no quota, so this merely fails them. Returns the count cancelled. Auth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account. @@ -117,7 +123,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CancelQueuedRunsResponse + CancelQueuedRunsResponse | ServiceUnavailableError """ return sync_detailed( @@ -132,11 +138,11 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CancelQueuedRunsResponse]: +) -> Response[CancelQueuedRunsResponse | ServiceUnavailableError]: """Cancel all queued inbound-email runs - Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run - consumed no quota or credits at queue time, so this merely fails them. Returns the count cancelled. + Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run has + consumed no quota, so this merely fails them. Returns the count cancelled. Auth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account. @@ -150,7 +156,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CancelQueuedRunsResponse] + Response[CancelQueuedRunsResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -168,11 +174,11 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CancelQueuedRunsResponse | None: +) -> CancelQueuedRunsResponse | ServiceUnavailableError | None: """Cancel all queued inbound-email runs - Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run - consumed no quota or credits at queue time, so this merely fails them. Returns the count cancelled. + Fail all of the account's QUEUED (over-quota parked) inbound-email runs at once. A queued run has + consumed no quota, so this merely fails them. Returns the count cancelled. Auth & scoping: requires `X-API-Key` header or OAuth Bearer token for an account owner/admin; scoped to the key's account. @@ -186,7 +192,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CancelQueuedRunsResponse + CancelQueuedRunsResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/create_agent_api_agents_post.py b/seclai/_generated/api/agents/create_agent_api_agents_post.py index a978912..88f706c 100644 --- a/seclai/_generated/api/agents/create_agent_api_agents_post.py +++ b/seclai/_generated/api/agents/create_agent_api_agents_post.py @@ -11,6 +11,7 @@ ) from ...models.agent_summary_response import AgentSummaryResponse from ...models.create_agent_request import CreateAgentRequest +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -42,7 +43,13 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any | None: +) -> ( + AgentDefinitionImportErrorResponse + | AgentSummaryResponse + | Any + | ServiceUnavailableError + | None +): if response.status_code == 201: response_201 = AgentSummaryResponse.from_dict(response.json()) @@ -57,6 +64,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +77,12 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any]: +) -> Response[ + AgentDefinitionImportErrorResponse + | AgentSummaryResponse + | Any + | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -80,7 +97,12 @@ def sync_detailed( body: CreateAgentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any]: +) -> Response[ + AgentDefinitionImportErrorResponse + | AgentSummaryResponse + | Any + | ServiceUnavailableError +]: """Create an agent Create a new agent. @@ -117,7 +139,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any] + Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -139,7 +161,13 @@ def sync( body: CreateAgentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any | None: +) -> ( + AgentDefinitionImportErrorResponse + | AgentSummaryResponse + | Any + | ServiceUnavailableError + | None +): """Create an agent Create a new agent. @@ -176,7 +204,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any + AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any | ServiceUnavailableError """ return sync_detailed( @@ -193,7 +221,12 @@ async def asyncio_detailed( body: CreateAgentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any]: +) -> Response[ + AgentDefinitionImportErrorResponse + | AgentSummaryResponse + | Any + | ServiceUnavailableError +]: """Create an agent Create a new agent. @@ -230,7 +263,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any] + Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -250,7 +283,13 @@ async def asyncio( body: CreateAgentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any | None: +) -> ( + AgentDefinitionImportErrorResponse + | AgentSummaryResponse + | Any + | ServiceUnavailableError + | None +): """Create an agent Create a new agent. @@ -287,7 +326,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any + AgentDefinitionImportErrorResponse | AgentSummaryResponse | Any | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/delete_agent_api_agents_agent_id_delete.py b/seclai/_generated/api/agents/delete_agent_api_agents_agent_id_delete.py index 9e82f92..42f5e66 100644 --- a/seclai/_generated/api/agents/delete_agent_api_agents_agent_id_delete.py +++ b/seclai/_generated/api/agents/delete_agent_api_agents_agent_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete an agent Soft-delete an agent. The agent will no longer appear in listings or be accessible via the API. @@ -89,7 +95,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -111,7 +117,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete an agent Soft-delete an agent. The agent will no longer appear in listings or be accessible via the API. @@ -130,7 +136,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -147,7 +153,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete an agent Soft-delete an agent. The agent will no longer appear in listings or be accessible via the API. @@ -166,7 +172,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -186,7 +192,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete an agent Soft-delete an agent. The agent will no longer appear in listings or be accessible via the API. @@ -205,7 +211,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/delete_agent_run_api_agents_runs_run_id_delete.py b/seclai/_generated/api/agents/delete_agent_run_api_agents_runs_run_id_delete.py index 29e6391..e0f23c2 100644 --- a/seclai/_generated/api/agents/delete_agent_run_api_agents_runs_run_id_delete.py +++ b/seclai/_generated/api/agents/delete_agent_run_api_agents_runs_run_id_delete.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_run_response import AgentRunResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentRunResponse | HTTPValidationError | None: +) -> AgentRunResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentRunResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentRunResponse | HTTPValidationError]: +) -> Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,13 +78,13 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentRunResponse | HTTPValidationError]: +) -> Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError]: """Cancel an agent run Cancel an in-flight (`processing`) or queued (`queued`) agent run. A `queued` run is an inbound-email run parked by the per-plan rate quota that has not yet been - dispatched; cancelling it consumes no quota or credits. + dispatched; it has consumed no quota. If the run is already in a terminal state (`completed` or `failed`), cancellation will be rejected. @@ -96,7 +102,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentRunResponse | HTTPValidationError] + Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -118,13 +124,13 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentRunResponse | HTTPValidationError | None: +) -> AgentRunResponse | HTTPValidationError | ServiceUnavailableError | None: """Cancel an agent run Cancel an in-flight (`processing`) or queued (`queued`) agent run. A `queued` run is an inbound-email run parked by the per-plan rate quota that has not yet been - dispatched; cancelling it consumes no quota or credits. + dispatched; it has consumed no quota. If the run is already in a terminal state (`completed` or `failed`), cancellation will be rejected. @@ -142,7 +148,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentRunResponse | HTTPValidationError + AgentRunResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -159,13 +165,13 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentRunResponse | HTTPValidationError]: +) -> Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError]: """Cancel an agent run Cancel an in-flight (`processing`) or queued (`queued`) agent run. A `queued` run is an inbound-email run parked by the per-plan rate quota that has not yet been - dispatched; cancelling it consumes no quota or credits. + dispatched; it has consumed no quota. If the run is already in a terminal state (`completed` or `failed`), cancellation will be rejected. @@ -183,7 +189,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentRunResponse | HTTPValidationError] + Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -203,13 +209,13 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentRunResponse | HTTPValidationError | None: +) -> AgentRunResponse | HTTPValidationError | ServiceUnavailableError | None: """Cancel an agent run Cancel an in-flight (`processing`) or queued (`queued`) agent run. A `queued` run is an inbound-email run parked by the per-plan rate quota that has not yet been - dispatched; cancelling it consumes no quota or credits. + dispatched; it has consumed no quota. If the run is already in a terminal state (`completed` or `failed`), cancellation will be rejected. @@ -227,7 +233,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentRunResponse | HTTPValidationError + AgentRunResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/disable_agent_api_api_agents_agent_id_disable_post.py b/seclai/_generated/api/agents/disable_agent_api_api_agents_agent_id_disable_post.py index eaa360b..0f0ad5e 100644 --- a/seclai/_generated/api/agents/disable_agent_api_api_agents_agent_id_disable_post.py +++ b/seclai/_generated/api/agents/disable_agent_api_api_agents_agent_id_disable_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_summary_response import AgentSummaryResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentSummaryResponse | HTTPValidationError | None: +) -> AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentSummaryResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentSummaryResponse | HTTPValidationError]: +) -> Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentSummaryResponse | HTTPValidationError]: +) -> Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError]: """Pause (disable) an agent Disable an agent so it stops firing from every trigger path (API runs return 409, inbound email is @@ -94,7 +100,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentSummaryResponse | HTTPValidationError] + Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -116,7 +122,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentSummaryResponse | HTTPValidationError | None: +) -> AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: """Pause (disable) an agent Disable an agent so it stops firing from every trigger path (API runs return 409, inbound email is @@ -138,7 +144,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentSummaryResponse | HTTPValidationError + AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -155,7 +161,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentSummaryResponse | HTTPValidationError]: +) -> Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError]: """Pause (disable) an agent Disable an agent so it stops firing from every trigger path (API runs return 409, inbound email is @@ -177,7 +183,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentSummaryResponse | HTTPValidationError] + Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -197,7 +203,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentSummaryResponse | HTTPValidationError | None: +) -> AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: """Pause (disable) an agent Disable an agent so it stops firing from every trigger path (API runs return 409, inbound email is @@ -219,7 +225,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentSummaryResponse | HTTPValidationError + AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/enable_agent_api_api_agents_agent_id_enable_post.py b/seclai/_generated/api/agents/enable_agent_api_api_agents_agent_id_enable_post.py index 1820aa6..dd3c8de 100644 --- a/seclai/_generated/api/agents/enable_agent_api_api_agents_agent_id_enable_post.py +++ b/seclai/_generated/api/agents/enable_agent_api_api_agents_agent_id_enable_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_summary_response import AgentSummaryResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentSummaryResponse | HTTPValidationError | None: +) -> AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentSummaryResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentSummaryResponse | HTTPValidationError]: +) -> Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentSummaryResponse | HTTPValidationError]: +) -> Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError]: """Resume (enable) a paused agent Re-enable a paused agent (clears the disable state, whether it was paused manually or auto-paused by @@ -91,7 +97,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentSummaryResponse | HTTPValidationError] + Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -113,7 +119,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentSummaryResponse | HTTPValidationError | None: +) -> AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: """Resume (enable) a paused agent Re-enable a paused agent (clears the disable state, whether it was paused manually or auto-paused by @@ -132,7 +138,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentSummaryResponse | HTTPValidationError + AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +155,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentSummaryResponse | HTTPValidationError]: +) -> Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError]: """Resume (enable) a paused agent Re-enable a paused agent (clears the disable state, whether it was paused manually or auto-paused by @@ -168,7 +174,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentSummaryResponse | HTTPValidationError] + Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -188,7 +194,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentSummaryResponse | HTTPValidationError | None: +) -> AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: """Resume (enable) a paused agent Re-enable a paused agent (clears the disable state, whether it was paused manually or auto-paused by @@ -207,7 +213,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentSummaryResponse | HTTPValidationError + AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/export_agent_api_agents_agent_id_export_get.py b/seclai/_generated/api/agents/export_agent_api_agents_agent_id_export_get.py index a42e34d..546fbf9 100644 --- a/seclai/_generated/api/agents/export_agent_api_agents_agent_id_export_get.py +++ b/seclai/_generated/api/agents/export_agent_api_agents_agent_id_export_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_export_response import AgentExportResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -46,7 +47,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentExportResponse | HTTPValidationError | None: +) -> AgentExportResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentExportResponse.from_dict(response.json()) @@ -57,6 +58,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +71,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentExportResponse | HTTPValidationError]: +) -> Response[AgentExportResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -81,7 +87,7 @@ def sync_detailed( download: bool | Unset = True, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentExportResponse | HTTPValidationError]: +) -> Response[AgentExportResponse | HTTPValidationError | ServiceUnavailableError]: r"""Export agent definition Export an agent definition as a portable JSON snapshot. @@ -91,7 +97,7 @@ def sync_detailed( every referenced external entity UUID to its human-readable name. Response shape: - - `export_version`: schema version (currently `\"2\"`) + - `export_version`: schema version (currently `\"5\"`) - `exported_at`: ISO-8601 timestamp - `agent`: name, description, schema_version, definition, timestamps - `trigger`: trigger type, input template, schedules @@ -118,7 +124,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentExportResponse | HTTPValidationError] + Response[AgentExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -142,7 +148,7 @@ def sync( download: bool | Unset = True, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentExportResponse | HTTPValidationError | None: +) -> AgentExportResponse | HTTPValidationError | ServiceUnavailableError | None: r"""Export agent definition Export an agent definition as a portable JSON snapshot. @@ -152,7 +158,7 @@ def sync( every referenced external entity UUID to its human-readable name. Response shape: - - `export_version`: schema version (currently `\"2\"`) + - `export_version`: schema version (currently `\"5\"`) - `exported_at`: ISO-8601 timestamp - `agent`: name, description, schema_version, definition, timestamps - `trigger`: trigger type, input template, schedules @@ -179,7 +185,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentExportResponse | HTTPValidationError + AgentExportResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -198,7 +204,7 @@ async def asyncio_detailed( download: bool | Unset = True, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentExportResponse | HTTPValidationError]: +) -> Response[AgentExportResponse | HTTPValidationError | ServiceUnavailableError]: r"""Export agent definition Export an agent definition as a portable JSON snapshot. @@ -208,7 +214,7 @@ async def asyncio_detailed( every referenced external entity UUID to its human-readable name. Response shape: - - `export_version`: schema version (currently `\"2\"`) + - `export_version`: schema version (currently `\"5\"`) - `exported_at`: ISO-8601 timestamp - `agent`: name, description, schema_version, definition, timestamps - `trigger`: trigger type, input template, schedules @@ -235,7 +241,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentExportResponse | HTTPValidationError] + Response[AgentExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -257,7 +263,7 @@ async def asyncio( download: bool | Unset = True, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentExportResponse | HTTPValidationError | None: +) -> AgentExportResponse | HTTPValidationError | ServiceUnavailableError | None: r"""Export agent definition Export an agent definition as a portable JSON snapshot. @@ -267,7 +273,7 @@ async def asyncio( every referenced external entity UUID to its human-readable name. Response shape: - - `export_version`: schema version (currently `\"2\"`) + - `export_version`: schema version (currently `\"5\"`) - `exported_at`: ISO-8601 timestamp - `agent`: name, description, schema_version, definition, timestamps - `trigger`: trigger type, input template, schedules @@ -294,7 +300,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentExportResponse | HTTPValidationError + AgentExportResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/generate_agent_steps_api_agents_agent_id_ai_assistant_generate_steps_post.py b/seclai/_generated/api/agents/generate_agent_steps_api_agents_agent_id_ai_assistant_generate_steps_post.py index ca2dfa0..1576721 100644 --- a/seclai/_generated/api/agents/generate_agent_steps_api_agents_agent_id_ai_assistant_generate_steps_post.py +++ b/seclai/_generated/api/agents/generate_agent_steps_api_agents_agent_id_ai_assistant_generate_steps_post.py @@ -10,6 +10,7 @@ from ...models.generate_agent_steps_request import GenerateAgentStepsRequest from ...models.generate_agent_steps_response import GenerateAgentStepsResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> GenerateAgentStepsResponse | HTTPValidationError | None: +) -> GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = GenerateAgentStepsResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[GenerateAgentStepsResponse | HTTPValidationError]: +) -> Response[ + GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +87,9 @@ def sync_detailed( body: GenerateAgentStepsRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[GenerateAgentStepsResponse | HTTPValidationError]: +) -> Response[ + GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate agent workflow Use the AI assistant to generate a full agent step workflow from a natural language description. @@ -103,7 +113,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[GenerateAgentStepsResponse | HTTPValidationError] + Response[GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -127,7 +137,7 @@ def sync( body: GenerateAgentStepsRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> GenerateAgentStepsResponse | HTTPValidationError | None: +) -> GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate agent workflow Use the AI assistant to generate a full agent step workflow from a natural language description. @@ -151,7 +161,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - GenerateAgentStepsResponse | HTTPValidationError + GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -170,7 +180,9 @@ async def asyncio_detailed( body: GenerateAgentStepsRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[GenerateAgentStepsResponse | HTTPValidationError]: +) -> Response[ + GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate agent workflow Use the AI assistant to generate a full agent step workflow from a natural language description. @@ -194,7 +206,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[GenerateAgentStepsResponse | HTTPValidationError] + Response[GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -216,7 +228,7 @@ async def asyncio( body: GenerateAgentStepsRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> GenerateAgentStepsResponse | HTTPValidationError | None: +) -> GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate agent workflow Use the AI assistant to generate a full agent step workflow from a natural language description. @@ -240,7 +252,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - GenerateAgentStepsResponse | HTTPValidationError + GenerateAgentStepsResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/generate_step_config_api_agents_agent_id_ai_assistant_step_config_post.py b/seclai/_generated/api/agents/generate_step_config_api_agents_agent_id_ai_assistant_step_config_post.py index 50165af..4095bad 100644 --- a/seclai/_generated/api/agents/generate_step_config_api_agents_agent_id_ai_assistant_step_config_post.py +++ b/seclai/_generated/api/agents/generate_step_config_api_agents_agent_id_ai_assistant_step_config_post.py @@ -10,6 +10,7 @@ from ...models.generate_step_config_request import GenerateStepConfigRequest from ...models.generate_step_config_response import GenerateStepConfigResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> GenerateStepConfigResponse | HTTPValidationError | None: +) -> GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = GenerateStepConfigResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[GenerateStepConfigResponse | HTTPValidationError]: +) -> Response[ + GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +87,9 @@ def sync_detailed( body: GenerateStepConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[GenerateStepConfigResponse | HTTPValidationError]: +) -> Response[ + GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate step configuration Use the AI assistant to generate or refine a single step's configuration. @@ -103,7 +113,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[GenerateStepConfigResponse | HTTPValidationError] + Response[GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -127,7 +137,7 @@ def sync( body: GenerateStepConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> GenerateStepConfigResponse | HTTPValidationError | None: +) -> GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate step configuration Use the AI assistant to generate or refine a single step's configuration. @@ -151,7 +161,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - GenerateStepConfigResponse | HTTPValidationError + GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -170,7 +180,9 @@ async def asyncio_detailed( body: GenerateStepConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[GenerateStepConfigResponse | HTTPValidationError]: +) -> Response[ + GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate step configuration Use the AI assistant to generate or refine a single step's configuration. @@ -194,7 +206,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[GenerateStepConfigResponse | HTTPValidationError] + Response[GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -216,7 +228,7 @@ async def asyncio( body: GenerateStepConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> GenerateStepConfigResponse | HTTPValidationError | None: +) -> GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate step configuration Use the AI assistant to generate or refine a single step's configuration. @@ -240,7 +252,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - GenerateStepConfigResponse | HTTPValidationError + GenerateStepConfigResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/get_agent_callers_api_api_agents_agent_id_callers_get.py b/seclai/_generated/api/agents/get_agent_callers_api_api_agents_agent_id_callers_get.py index a92d5ca..37b8c84 100644 --- a/seclai/_generated/api/agents/get_agent_callers_api_api_agents_agent_id_callers_get.py +++ b/seclai/_generated/api/agents/get_agent_callers_api_api_agents_agent_id_callers_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_caller_api_response import AgentCallerApiResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,9 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | list[AgentCallerApiResponse] | None: +) -> ( + HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse] | None +): if response.status_code == 200: response_200 = [] _response_200 = response.json() @@ -54,6 +57,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -62,7 +70,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | list[AgentCallerApiResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse] +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -77,7 +87,9 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[AgentCallerApiResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse] +]: """List agents that call this agent List the live agents that call this agent via a `call_agent` step. They must be disabled before this @@ -96,7 +108,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[AgentCallerApiResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse]] """ kwargs = _get_kwargs( @@ -118,7 +130,9 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[AgentCallerApiResponse] | None: +) -> ( + HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse] | None +): """List agents that call this agent List the live agents that call this agent via a `call_agent` step. They must be disabled before this @@ -137,7 +151,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[AgentCallerApiResponse] + HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse] """ return sync_detailed( @@ -154,7 +168,9 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[AgentCallerApiResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse] +]: """List agents that call this agent List the live agents that call this agent via a `call_agent` step. They must be disabled before this @@ -173,7 +189,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[AgentCallerApiResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse]] """ kwargs = _get_kwargs( @@ -193,7 +209,9 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[AgentCallerApiResponse] | None: +) -> ( + HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse] | None +): """List agents that call this agent List the live agents that call this agent via a `call_agent` step. They must be disabled before this @@ -212,7 +230,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[AgentCallerApiResponse] + HTTPValidationError | ServiceUnavailableError | list[AgentCallerApiResponse] """ return ( diff --git a/seclai/_generated/api/agents/get_agent_definition_api_agents_agent_id_definition_get.py b/seclai/_generated/api/agents/get_agent_definition_api_agents_agent_id_definition_get.py index e521176..6eba31f 100644 --- a/seclai/_generated/api/agents/get_agent_definition_api_agents_agent_id_definition_get.py +++ b/seclai/_generated/api/agents/get_agent_definition_api_agents_agent_id_definition_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_definition_response import AgentDefinitionResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentDefinitionResponse | HTTPValidationError | None: +) -> AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentDefinitionResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentDefinitionResponse | HTTPValidationError]: +) -> Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,8 +78,8 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionResponse | HTTPValidationError]: - """Get agent definition +) -> Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError]: + r"""Get agent definition Fetch the current agent definition from the main branch. @@ -112,7 +118,10 @@ def sync_detailed( optional) - `streaming_result`: Stream LLM tokens in real-time via SSE (must be a direct child of `prompt_call`; requires `dynamic_input` or `template_input` trigger; `priority: true` enables real- - time streaming) + time streaming). To stream **and** return a schema-validated payload, add a sibling branch + `extract_content` (`expected_format: \"json\"` + `json_schema`) → `display_result` under the same + `prompt_call` — a `display_result` takes precedence over the stream regardless of which finishes + first, so its validated output becomes the run's result while the tokens act as a progress channel - `display_result`: Show output to the user - `join`: Merge parallel branches - `merge`: Combine multiple inputs into a single templated output @@ -145,7 +154,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionResponse | HTTPValidationError] + Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -167,8 +176,8 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionResponse | HTTPValidationError | None: - """Get agent definition +) -> AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError | None: + r"""Get agent definition Fetch the current agent definition from the main branch. @@ -207,7 +216,10 @@ def sync( optional) - `streaming_result`: Stream LLM tokens in real-time via SSE (must be a direct child of `prompt_call`; requires `dynamic_input` or `template_input` trigger; `priority: true` enables real- - time streaming) + time streaming). To stream **and** return a schema-validated payload, add a sibling branch + `extract_content` (`expected_format: \"json\"` + `json_schema`) → `display_result` under the same + `prompt_call` — a `display_result` takes precedence over the stream regardless of which finishes + first, so its validated output becomes the run's result while the tokens act as a progress channel - `display_result`: Show output to the user - `join`: Merge parallel branches - `merge`: Combine multiple inputs into a single templated output @@ -240,7 +252,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionResponse | HTTPValidationError + AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -257,8 +269,8 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionResponse | HTTPValidationError]: - """Get agent definition +) -> Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError]: + r"""Get agent definition Fetch the current agent definition from the main branch. @@ -297,7 +309,10 @@ async def asyncio_detailed( optional) - `streaming_result`: Stream LLM tokens in real-time via SSE (must be a direct child of `prompt_call`; requires `dynamic_input` or `template_input` trigger; `priority: true` enables real- - time streaming) + time streaming). To stream **and** return a schema-validated payload, add a sibling branch + `extract_content` (`expected_format: \"json\"` + `json_schema`) → `display_result` under the same + `prompt_call` — a `display_result` takes precedence over the stream regardless of which finishes + first, so its validated output becomes the run's result while the tokens act as a progress channel - `display_result`: Show output to the user - `join`: Merge parallel branches - `merge`: Combine multiple inputs into a single templated output @@ -330,7 +345,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionResponse | HTTPValidationError] + Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -350,8 +365,8 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionResponse | HTTPValidationError | None: - """Get agent definition +) -> AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError | None: + r"""Get agent definition Fetch the current agent definition from the main branch. @@ -390,7 +405,10 @@ async def asyncio( optional) - `streaming_result`: Stream LLM tokens in real-time via SSE (must be a direct child of `prompt_call`; requires `dynamic_input` or `template_input` trigger; `priority: true` enables real- - time streaming) + time streaming). To stream **and** return a schema-validated payload, add a sibling branch + `extract_content` (`expected_format: \"json\"` + `json_schema`) → `display_result` under the same + `prompt_call` — a `display_result` takes precedence over the stream regardless of which finishes + first, so its validated output becomes the run's result while the tokens act as a progress channel - `display_result`: Show output to the user - `join`: Merge parallel branches - `merge`: Combine multiple inputs into a single templated output @@ -423,7 +441,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionResponse | HTTPValidationError + AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/get_agent_metadata_api_agents_agent_id_get.py b/seclai/_generated/api/agents/get_agent_metadata_api_agents_agent_id_get.py index d482020..713533a 100644 --- a/seclai/_generated/api/agents/get_agent_metadata_api_agents_agent_id_get.py +++ b/seclai/_generated/api/agents/get_agent_metadata_api_agents_agent_id_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_summary_response import AgentSummaryResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentSummaryResponse | HTTPValidationError | None: +) -> AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentSummaryResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentSummaryResponse | HTTPValidationError]: +) -> Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentSummaryResponse | HTTPValidationError]: +) -> Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError]: """Get an agent Fetch an agent's metadata (name, description, trigger type, timestamps). @@ -91,7 +97,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentSummaryResponse | HTTPValidationError] + Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -113,7 +119,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentSummaryResponse | HTTPValidationError | None: +) -> AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: """Get an agent Fetch an agent's metadata (name, description, trigger type, timestamps). @@ -132,7 +138,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentSummaryResponse | HTTPValidationError + AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +155,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentSummaryResponse | HTTPValidationError]: +) -> Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError]: """Get an agent Fetch an agent's metadata (name, description, trigger type, timestamps). @@ -168,7 +174,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentSummaryResponse | HTTPValidationError] + Response[AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -188,7 +194,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentSummaryResponse | HTTPValidationError | None: +) -> AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: """Get an agent Fetch an agent's metadata (name, description, trigger type, timestamps). @@ -207,7 +213,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentSummaryResponse | HTTPValidationError + AgentSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/get_agent_run_api_agents_runs_run_id_get.py b/seclai/_generated/api/agents/get_agent_run_api_agents_runs_run_id_get.py index 2dc985c..42efd6e 100644 --- a/seclai/_generated/api/agents/get_agent_run_api_agents_runs_run_id_get.py +++ b/seclai/_generated/api/agents/get_agent_run_api_agents_runs_run_id_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_run_response import AgentRunResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -46,7 +47,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentRunResponse | HTTPValidationError | None: +) -> AgentRunResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentRunResponse.from_dict(response.json()) @@ -57,6 +58,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +71,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentRunResponse | HTTPValidationError]: +) -> Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -81,7 +87,7 @@ def sync_detailed( include_step_outputs: bool | Unset = False, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentRunResponse | HTTPValidationError]: +) -> Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError]: """Get an agent run Fetch the latest snapshot for an agent run created by `POST /agents/{agent_id}/runs` or `POST @@ -106,7 +112,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentRunResponse | HTTPValidationError] + Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -130,7 +136,7 @@ def sync( include_step_outputs: bool | Unset = False, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentRunResponse | HTTPValidationError | None: +) -> AgentRunResponse | HTTPValidationError | ServiceUnavailableError | None: """Get an agent run Fetch the latest snapshot for an agent run created by `POST /agents/{agent_id}/runs` or `POST @@ -155,7 +161,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentRunResponse | HTTPValidationError + AgentRunResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -174,7 +180,7 @@ async def asyncio_detailed( include_step_outputs: bool | Unset = False, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentRunResponse | HTTPValidationError]: +) -> Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError]: """Get an agent run Fetch the latest snapshot for an agent run created by `POST /agents/{agent_id}/runs` or `POST @@ -199,7 +205,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentRunResponse | HTTPValidationError] + Response[AgentRunResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -221,7 +227,7 @@ async def asyncio( include_step_outputs: bool | Unset = False, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentRunResponse | HTTPValidationError | None: +) -> AgentRunResponse | HTTPValidationError | ServiceUnavailableError | None: """Get an agent run Fetch the latest snapshot for an agent run created by `POST /agents/{agent_id}/runs` or `POST @@ -246,7 +252,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentRunResponse | HTTPValidationError + AgentRunResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/get_ai_conversation_history_api_agents_agent_id_ai_assistant_conversations_get.py b/seclai/_generated/api/agents/get_ai_conversation_history_api_agents_agent_id_ai_assistant_conversations_get.py index 32bddca..6fd0614 100644 --- a/seclai/_generated/api/agents/get_ai_conversation_history_api_agents_agent_id_ai_assistant_conversations_get.py +++ b/seclai/_generated/api/agents/get_ai_conversation_history_api_agents_agent_id_ai_assistant_conversations_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.ai_conversation_history_response import AiConversationHistoryResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -60,7 +61,9 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiConversationHistoryResponse | HTTPValidationError | None: +) -> ( + AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError | None +): if response.status_code == 200: response_200 = AiConversationHistoryResponse.from_dict(response.json()) @@ -71,6 +74,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -79,7 +87,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiConversationHistoryResponse | HTTPValidationError]: +) -> Response[ + AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -98,7 +108,9 @@ def sync_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiConversationHistoryResponse | HTTPValidationError]: +) -> Response[ + AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError +]: """Get AI conversation history Fetch the AI assistant conversation history for a specific step of an agent. @@ -125,7 +137,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiConversationHistoryResponse | HTTPValidationError] + Response[AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -155,7 +167,9 @@ def sync( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiConversationHistoryResponse | HTTPValidationError | None: +) -> ( + AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError | None +): """Get AI conversation history Fetch the AI assistant conversation history for a specific step of an agent. @@ -182,7 +196,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiConversationHistoryResponse | HTTPValidationError + AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -207,7 +221,9 @@ async def asyncio_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiConversationHistoryResponse | HTTPValidationError]: +) -> Response[ + AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError +]: """Get AI conversation history Fetch the AI assistant conversation history for a specific step of an agent. @@ -234,7 +250,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiConversationHistoryResponse | HTTPValidationError] + Response[AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -262,7 +278,9 @@ async def asyncio( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiConversationHistoryResponse | HTTPValidationError | None: +) -> ( + AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError | None +): """Get AI conversation history Fetch the AI assistant conversation history for a specific step of an agent. @@ -289,7 +307,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiConversationHistoryResponse | HTTPValidationError + AiConversationHistoryResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/get_inbound_email_status_api_api_agents_inbound_email_status_get.py b/seclai/_generated/api/agents/get_inbound_email_status_api_api_agents_inbound_email_status_get.py index cb167ff..d50b8ad 100644 --- a/seclai/_generated/api/agents/get_inbound_email_status_api_api_agents_inbound_email_status_get.py +++ b/seclai/_generated/api/agents/get_inbound_email_status_api_api_agents_inbound_email_status_get.py @@ -7,6 +7,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.inbound_email_status_response import InboundEmailStatusResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -33,12 +34,17 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> InboundEmailStatusResponse | None: +) -> InboundEmailStatusResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = InboundEmailStatusResponse.from_dict(response.json()) return response_200 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -47,7 +53,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[InboundEmailStatusResponse]: +) -> Response[InboundEmailStatusResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -61,7 +67,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[InboundEmailStatusResponse]: +) -> Response[InboundEmailStatusResponse | ServiceUnavailableError]: """Account inbound-email overload status Whether the account-wide overload circuit breaker has currently paused new inbound email (all @@ -80,7 +86,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[InboundEmailStatusResponse] + Response[InboundEmailStatusResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -100,7 +106,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> InboundEmailStatusResponse | None: +) -> InboundEmailStatusResponse | ServiceUnavailableError | None: """Account inbound-email overload status Whether the account-wide overload circuit breaker has currently paused new inbound email (all @@ -119,7 +125,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - InboundEmailStatusResponse + InboundEmailStatusResponse | ServiceUnavailableError """ return sync_detailed( @@ -134,7 +140,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[InboundEmailStatusResponse]: +) -> Response[InboundEmailStatusResponse | ServiceUnavailableError]: """Account inbound-email overload status Whether the account-wide overload circuit breaker has currently paused new inbound email (all @@ -153,7 +159,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[InboundEmailStatusResponse] + Response[InboundEmailStatusResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -171,7 +177,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> InboundEmailStatusResponse | None: +) -> InboundEmailStatusResponse | ServiceUnavailableError | None: """Account inbound-email overload status Whether the account-wide overload circuit breaker has currently paused new inbound email (all @@ -190,7 +196,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - InboundEmailStatusResponse + InboundEmailStatusResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/list_agent_email_optouts_api_api_agents_agent_email_optouts_get.py b/seclai/_generated/api/agents/list_agent_email_optouts_api_api_agents_agent_email_optouts_get.py index b6ba477..c9a3fb1 100644 --- a/seclai/_generated/api/agents/list_agent_email_optouts_api_api_agents_agent_email_optouts_get.py +++ b/seclai/_generated/api/agents/list_agent_email_optouts_api_api_agents_agent_email_optouts_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_email_opt_out_list_response import AgentEmailOptOutListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -53,7 +54,9 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentEmailOptOutListResponse | HTTPValidationError | None: +) -> ( + AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError | None +): if response.status_code == 200: response_200 = AgentEmailOptOutListResponse.from_dict(response.json()) @@ -64,6 +67,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -72,7 +80,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentEmailOptOutListResponse | HTTPValidationError]: +) -> Response[ + AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -89,7 +99,9 @@ def sync_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentEmailOptOutListResponse | HTTPValidationError]: +) -> Response[ + AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError +]: """List agent-email opt-outs List recipients who have opted out of this account's agent emails (filter to one agent via @@ -111,7 +123,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentEmailOptOutListResponse | HTTPValidationError] + Response[AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -137,7 +149,9 @@ def sync( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentEmailOptOutListResponse | HTTPValidationError | None: +) -> ( + AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError | None +): """List agent-email opt-outs List recipients who have opted out of this account's agent emails (filter to one agent via @@ -159,7 +173,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentEmailOptOutListResponse | HTTPValidationError + AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -180,7 +194,9 @@ async def asyncio_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentEmailOptOutListResponse | HTTPValidationError]: +) -> Response[ + AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError +]: """List agent-email opt-outs List recipients who have opted out of this account's agent emails (filter to one agent via @@ -202,7 +218,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentEmailOptOutListResponse | HTTPValidationError] + Response[AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -226,7 +242,9 @@ async def asyncio( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentEmailOptOutListResponse | HTTPValidationError | None: +) -> ( + AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError | None +): """List agent-email opt-outs List recipients who have opted out of this account's agent emails (filter to one agent via @@ -248,7 +266,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentEmailOptOutListResponse | HTTPValidationError + AgentEmailOptOutListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/list_agent_runs_api_agents_agent_id_runs_get.py b/seclai/_generated/api/agents/list_agent_runs_api_agents_agent_id_runs_get.py index d5d9f0d..be1c2e7 100644 --- a/seclai/_generated/api/agents/list_agent_runs_api_agents_agent_id_runs_get.py +++ b/seclai/_generated/api/agents/list_agent_runs_api_agents_agent_id_runs_get.py @@ -12,6 +12,7 @@ from ...models.pending_processing_completed_failed_status import ( PendingProcessingCompletedFailedStatus, ) +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -62,7 +63,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentRunListResponse | HTTPValidationError | None: +) -> AgentRunListResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentRunListResponse.from_dict(response.json()) @@ -73,6 +74,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -81,7 +87,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentRunListResponse | HTTPValidationError]: +) -> Response[AgentRunListResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -99,7 +105,7 @@ def sync_detailed( status: None | PendingProcessingCompletedFailedStatus | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentRunListResponse | HTTPValidationError]: +) -> Response[AgentRunListResponse | HTTPValidationError | ServiceUnavailableError]: """List agent runs List runs for a specific agent (most recent first), with pagination. @@ -128,7 +134,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentRunListResponse | HTTPValidationError] + Response[AgentRunListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -156,7 +162,7 @@ def sync( status: None | PendingProcessingCompletedFailedStatus | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentRunListResponse | HTTPValidationError | None: +) -> AgentRunListResponse | HTTPValidationError | ServiceUnavailableError | None: """List agent runs List runs for a specific agent (most recent first), with pagination. @@ -185,7 +191,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentRunListResponse | HTTPValidationError + AgentRunListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -208,7 +214,7 @@ async def asyncio_detailed( status: None | PendingProcessingCompletedFailedStatus | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentRunListResponse | HTTPValidationError]: +) -> Response[AgentRunListResponse | HTTPValidationError | ServiceUnavailableError]: """List agent runs List runs for a specific agent (most recent first), with pagination. @@ -237,7 +243,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentRunListResponse | HTTPValidationError] + Response[AgentRunListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -263,7 +269,7 @@ async def asyncio( status: None | PendingProcessingCompletedFailedStatus | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentRunListResponse | HTTPValidationError | None: +) -> AgentRunListResponse | HTTPValidationError | ServiceUnavailableError | None: """List agent runs List runs for a specific agent (most recent first), with pagination. @@ -292,7 +298,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentRunListResponse | HTTPValidationError + AgentRunListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/list_agents_api_agents_get.py b/seclai/_generated/api/agents/list_agents_api_agents_get.py index e82202e..5daa324 100644 --- a/seclai/_generated/api/agents/list_agents_api_agents_get.py +++ b/seclai/_generated/api/agents/list_agents_api_agents_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_list_response import AgentListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -45,7 +46,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentListResponse | HTTPValidationError | None: +) -> AgentListResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentListResponse.from_dict(response.json()) @@ -56,6 +57,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -64,7 +70,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentListResponse | HTTPValidationError]: +) -> Response[AgentListResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -80,7 +86,7 @@ def sync_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentListResponse | HTTPValidationError]: +) -> Response[AgentListResponse | HTTPValidationError | ServiceUnavailableError]: """List agents List agents for the account with pagination. @@ -100,7 +106,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentListResponse | HTTPValidationError] + Response[AgentListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -124,7 +130,7 @@ def sync( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentListResponse | HTTPValidationError | None: +) -> AgentListResponse | HTTPValidationError | ServiceUnavailableError | None: """List agents List agents for the account with pagination. @@ -144,7 +150,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentListResponse | HTTPValidationError + AgentListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -163,7 +169,7 @@ async def asyncio_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentListResponse | HTTPValidationError]: +) -> Response[AgentListResponse | HTTPValidationError | ServiceUnavailableError]: """List agents List agents for the account with pagination. @@ -183,7 +189,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentListResponse | HTTPValidationError] + Response[AgentListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -205,7 +211,7 @@ async def asyncio( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentListResponse | HTTPValidationError | None: +) -> AgentListResponse | HTTPValidationError | ServiceUnavailableError | None: """List agents List agents for the account with pagination. @@ -225,7 +231,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentListResponse | HTTPValidationError + AgentListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/list_blocked_email_senders_api_api_agents_blocked_email_senders_get.py b/seclai/_generated/api/agents/list_blocked_email_senders_api_api_agents_blocked_email_senders_get.py index 8b82c95..d58fe6c 100644 --- a/seclai/_generated/api/agents/list_blocked_email_senders_api_api_agents_blocked_email_senders_get.py +++ b/seclai/_generated/api/agents/list_blocked_email_senders_api_api_agents_blocked_email_senders_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.blocked_email_sender_list_response import BlockedEmailSenderListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -45,7 +46,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> BlockedEmailSenderListResponse | HTTPValidationError | None: +) -> ( + BlockedEmailSenderListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = BlockedEmailSenderListResponse.from_dict(response.json()) @@ -56,6 +62,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -64,7 +75,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[BlockedEmailSenderListResponse | HTTPValidationError]: +) -> Response[ + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -80,7 +93,9 @@ def sync_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[BlockedEmailSenderListResponse | HTTPValidationError]: +) -> Response[ + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError +]: """List blocked inbound email senders + the auto-block mode List the account's blocked inbound email senders (newest first, paginated via `limit`/`offset`) plus @@ -100,7 +115,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[BlockedEmailSenderListResponse | HTTPValidationError] + Response[BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -124,7 +139,12 @@ def sync( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> BlockedEmailSenderListResponse | HTTPValidationError | None: +) -> ( + BlockedEmailSenderListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """List blocked inbound email senders + the auto-block mode List the account's blocked inbound email senders (newest first, paginated via `limit`/`offset`) plus @@ -144,7 +164,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - BlockedEmailSenderListResponse | HTTPValidationError + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -163,7 +183,9 @@ async def asyncio_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[BlockedEmailSenderListResponse | HTTPValidationError]: +) -> Response[ + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError +]: """List blocked inbound email senders + the auto-block mode List the account's blocked inbound email senders (newest first, paginated via `limit`/`offset`) plus @@ -183,7 +205,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[BlockedEmailSenderListResponse | HTTPValidationError] + Response[BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -205,7 +227,12 @@ async def asyncio( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> BlockedEmailSenderListResponse | HTTPValidationError | None: +) -> ( + BlockedEmailSenderListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """List blocked inbound email senders + the auto-block mode List the account's blocked inbound email senders (newest first, paginated via `limit`/`offset`) plus @@ -225,7 +252,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - BlockedEmailSenderListResponse | HTTPValidationError + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/list_inbound_email_rejections_api_api_agents_inbound_email_rejections_get.py b/seclai/_generated/api/agents/list_inbound_email_rejections_api_api_agents_inbound_email_rejections_get.py index 877629a..7789044 100644 --- a/seclai/_generated/api/agents/list_inbound_email_rejections_api_api_agents_inbound_email_rejections_get.py +++ b/seclai/_generated/api/agents/list_inbound_email_rejections_api_api_agents_inbound_email_rejections_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.inbound_email_rejection_response import InboundEmailRejectionResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -50,7 +51,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | list[InboundEmailRejectionResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[InboundEmailRejectionResponse] + | None +): if response.status_code == 200: response_200 = [] _response_200 = response.json() @@ -68,6 +74,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -76,7 +87,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | list[InboundEmailRejectionResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[InboundEmailRejectionResponse] +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -92,7 +105,9 @@ def sync_detailed( limit: int | Unset = 50, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[InboundEmailRejectionResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[InboundEmailRejectionResponse] +]: """List discarded inbound emails List recent inbound emails that were quietly discarded before running an agent (unauthorized sender, @@ -112,7 +127,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[InboundEmailRejectionResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[InboundEmailRejectionResponse]] """ kwargs = _get_kwargs( @@ -136,7 +151,12 @@ def sync( limit: int | Unset = 50, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[InboundEmailRejectionResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[InboundEmailRejectionResponse] + | None +): """List discarded inbound emails List recent inbound emails that were quietly discarded before running an agent (unauthorized sender, @@ -156,7 +176,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[InboundEmailRejectionResponse] + HTTPValidationError | ServiceUnavailableError | list[InboundEmailRejectionResponse] """ return sync_detailed( @@ -175,7 +195,9 @@ async def asyncio_detailed( limit: int | Unset = 50, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[InboundEmailRejectionResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[InboundEmailRejectionResponse] +]: """List discarded inbound emails List recent inbound emails that were quietly discarded before running an agent (unauthorized sender, @@ -195,7 +217,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[InboundEmailRejectionResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[InboundEmailRejectionResponse]] """ kwargs = _get_kwargs( @@ -217,7 +239,12 @@ async def asyncio( limit: int | Unset = 50, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[InboundEmailRejectionResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[InboundEmailRejectionResponse] + | None +): """List discarded inbound emails List recent inbound emails that were quietly discarded before running an agent (unauthorized sender, @@ -237,7 +264,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[InboundEmailRejectionResponse] + HTTPValidationError | ServiceUnavailableError | list[InboundEmailRejectionResponse] """ return ( diff --git a/seclai/_generated/api/agents/mark_ai_suggestion_api_agents_agent_id_ai_assistant_conversation_id_patch.py b/seclai/_generated/api/agents/mark_ai_suggestion_api_agents_agent_id_ai_assistant_conversation_id_patch.py index 5ae944b..01eff07 100644 --- a/seclai/_generated/api/agents/mark_ai_suggestion_api_agents_agent_id_ai_assistant_conversation_id_patch.py +++ b/seclai/_generated/api/agents/mark_ai_suggestion_api_agents_agent_id_ai_assistant_conversation_id_patch.py @@ -10,6 +10,7 @@ from ...models.http_validation_error import HTTPValidationError from ...models.mark_ai_suggestion_request import MarkAiSuggestionRequest from ...models.ok_response import OkResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -46,7 +47,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | OkResponse | None: +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = OkResponse.from_dict(response.json()) @@ -57,6 +58,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +71,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | OkResponse]: +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -82,7 +88,7 @@ def sync_detailed( body: MarkAiSuggestionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OkResponse]: +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: """Accept or decline suggestion Accept or decline a proposed AI assistant configuration for a conversation turn. @@ -106,7 +112,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OkResponse] + Response[HTTPValidationError | OkResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -132,7 +138,7 @@ def sync( body: MarkAiSuggestionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OkResponse | None: +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: """Accept or decline suggestion Accept or decline a proposed AI assistant configuration for a conversation turn. @@ -156,7 +162,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OkResponse + HTTPValidationError | OkResponse | ServiceUnavailableError """ return sync_detailed( @@ -177,7 +183,7 @@ async def asyncio_detailed( body: MarkAiSuggestionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OkResponse]: +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: """Accept or decline suggestion Accept or decline a proposed AI assistant configuration for a conversation turn. @@ -201,7 +207,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OkResponse] + Response[HTTPValidationError | OkResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -225,7 +231,7 @@ async def asyncio( body: MarkAiSuggestionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OkResponse | None: +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: """Accept or decline suggestion Accept or decline a proposed AI assistant configuration for a conversation turn. @@ -249,7 +255,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OkResponse + HTTPValidationError | OkResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/preview_import_agent_api_agents_preview_import_post.py b/seclai/_generated/api/agents/preview_import_agent_api_agents_preview_import_post.py index 3e15d4e..fa98cc8 100644 --- a/seclai/_generated/api/agents/preview_import_agent_api_agents_preview_import_post.py +++ b/seclai/_generated/api/agents/preview_import_agent_api_agents_preview_import_post.py @@ -11,6 +11,7 @@ ) from ...models.agent_import_preview_request import AgentImportPreviewRequest from ...models.agent_import_preview_response import AgentImportPreviewResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -42,7 +43,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentDefinitionImportErrorResponse | AgentImportPreviewResponse | None: +) -> ( + AgentDefinitionImportErrorResponse + | AgentImportPreviewResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = AgentImportPreviewResponse.from_dict(response.json()) @@ -53,6 +59,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -61,7 +72,11 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentDefinitionImportErrorResponse | AgentImportPreviewResponse]: +) -> Response[ + AgentDefinitionImportErrorResponse + | AgentImportPreviewResponse + | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -76,7 +91,11 @@ def sync_detailed( body: AgentImportPreviewRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionImportErrorResponse | AgentImportPreviewResponse]: +) -> Response[ + AgentDefinitionImportErrorResponse + | AgentImportPreviewResponse + | ServiceUnavailableError +]: """Preview an agent_definition import Validate an `agent_definition` payload (the same shape produced by `GET /agents/{agent_id}/export`) @@ -85,6 +104,12 @@ def sync_detailed( failure returns the same 422 body shape used by `POST /agents` and `PUT /agents/{id}` so callers can render line/column-anchored errors. + Coverage: everything decidable from the payload itself — schema, step ids, nesting depth, text + lengths, attachment references, prompt-tool declarations, step-graph cycles, racing step references, + and `for_each` aggregation. Rules that depend on account state (email recipients, memory-bank types, + cloud-drive connections, the agent's own trigger) can only run at save time, so `POST /agents` may + still reject a payload this endpoint accepts. + Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. No DB writes. @@ -99,7 +124,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionImportErrorResponse | AgentImportPreviewResponse] + Response[AgentDefinitionImportErrorResponse | AgentImportPreviewResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -121,7 +146,12 @@ def sync( body: AgentImportPreviewRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionImportErrorResponse | AgentImportPreviewResponse | None: +) -> ( + AgentDefinitionImportErrorResponse + | AgentImportPreviewResponse + | ServiceUnavailableError + | None +): """Preview an agent_definition import Validate an `agent_definition` payload (the same shape produced by `GET /agents/{agent_id}/export`) @@ -130,6 +160,12 @@ def sync( failure returns the same 422 body shape used by `POST /agents` and `PUT /agents/{id}` so callers can render line/column-anchored errors. + Coverage: everything decidable from the payload itself — schema, step ids, nesting depth, text + lengths, attachment references, prompt-tool declarations, step-graph cycles, racing step references, + and `for_each` aggregation. Rules that depend on account state (email recipients, memory-bank types, + cloud-drive connections, the agent's own trigger) can only run at save time, so `POST /agents` may + still reject a payload this endpoint accepts. + Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. No DB writes. @@ -144,7 +180,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionImportErrorResponse | AgentImportPreviewResponse + AgentDefinitionImportErrorResponse | AgentImportPreviewResponse | ServiceUnavailableError """ return sync_detailed( @@ -161,7 +197,11 @@ async def asyncio_detailed( body: AgentImportPreviewRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionImportErrorResponse | AgentImportPreviewResponse]: +) -> Response[ + AgentDefinitionImportErrorResponse + | AgentImportPreviewResponse + | ServiceUnavailableError +]: """Preview an agent_definition import Validate an `agent_definition` payload (the same shape produced by `GET /agents/{agent_id}/export`) @@ -170,6 +210,12 @@ async def asyncio_detailed( failure returns the same 422 body shape used by `POST /agents` and `PUT /agents/{id}` so callers can render line/column-anchored errors. + Coverage: everything decidable from the payload itself — schema, step ids, nesting depth, text + lengths, attachment references, prompt-tool declarations, step-graph cycles, racing step references, + and `for_each` aggregation. Rules that depend on account state (email recipients, memory-bank types, + cloud-drive connections, the agent's own trigger) can only run at save time, so `POST /agents` may + still reject a payload this endpoint accepts. + Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. No DB writes. @@ -184,7 +230,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionImportErrorResponse | AgentImportPreviewResponse] + Response[AgentDefinitionImportErrorResponse | AgentImportPreviewResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -204,7 +250,12 @@ async def asyncio( body: AgentImportPreviewRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionImportErrorResponse | AgentImportPreviewResponse | None: +) -> ( + AgentDefinitionImportErrorResponse + | AgentImportPreviewResponse + | ServiceUnavailableError + | None +): """Preview an agent_definition import Validate an `agent_definition` payload (the same shape produced by `GET /agents/{agent_id}/export`) @@ -213,6 +264,12 @@ async def asyncio( failure returns the same 422 body shape used by `POST /agents` and `PUT /agents/{id}` so callers can render line/column-anchored errors. + Coverage: everything decidable from the payload itself — schema, step ids, nesting depth, text + lengths, attachment references, prompt-tool declarations, step-graph cycles, racing step references, + and `for_each` aggregation. Rules that depend on account state (email recipients, memory-bank types, + cloud-drive connections, the agent's own trigger) can only run at save time, so `POST /agents` may + still reject a payload this endpoint accepts. + Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. No DB writes. @@ -227,7 +284,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionImportErrorResponse | AgentImportPreviewResponse + AgentDefinitionImportErrorResponse | AgentImportPreviewResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/remove_agent_email_optout_api_api_agents_agent_email_optouts_optout_id_delete.py b/seclai/_generated/api/agents/remove_agent_email_optout_api_api_agents_agent_email_optouts_optout_id_delete.py index 0cd5f06..0695d27 100644 --- a/seclai/_generated/api/agents/remove_agent_email_optout_api_api_agents_agent_email_optouts_optout_id_delete.py +++ b/seclai/_generated/api/agents/remove_agent_email_optout_api_api_agents_agent_email_optouts_optout_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Revoke an agent-email opt-out Revoke an opt-out (opt the recipient back in to agent emails). @@ -88,7 +94,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -110,7 +116,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Revoke an agent-email opt-out Revoke an opt-out (opt the recipient back in to agent emails). @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Revoke an agent-email opt-out Revoke an opt-out (opt the recipient back in to agent emails). @@ -163,7 +169,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Revoke an agent-email opt-out Revoke an opt-out (opt the recipient back in to agent emails). @@ -201,7 +207,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/resume_inbound_email_api_api_agents_inbound_email_status_resume_post.py b/seclai/_generated/api/agents/resume_inbound_email_api_api_agents_inbound_email_status_resume_post.py index d31e861..b968072 100644 --- a/seclai/_generated/api/agents/resume_inbound_email_api_api_agents_inbound_email_status_resume_post.py +++ b/seclai/_generated/api/agents/resume_inbound_email_api_api_agents_inbound_email_status_resume_post.py @@ -7,6 +7,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.resume_inbound_response import ResumeInboundResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -33,12 +34,17 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ResumeInboundResponse | None: +) -> ResumeInboundResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ResumeInboundResponse.from_dict(response.json()) return response_200 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -47,7 +53,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ResumeInboundResponse]: +) -> Response[ResumeInboundResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -61,7 +67,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ResumeInboundResponse]: +) -> Response[ResumeInboundResponse | ServiceUnavailableError]: """Manually resume paused inbound email Manually lift the account-wide inbound pause. If the queued backlog is still above the ceiling the @@ -79,7 +85,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ResumeInboundResponse] + Response[ResumeInboundResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -99,7 +105,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ResumeInboundResponse | None: +) -> ResumeInboundResponse | ServiceUnavailableError | None: """Manually resume paused inbound email Manually lift the account-wide inbound pause. If the queued backlog is still above the ceiling the @@ -117,7 +123,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ResumeInboundResponse + ResumeInboundResponse | ServiceUnavailableError """ return sync_detailed( @@ -132,7 +138,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ResumeInboundResponse]: +) -> Response[ResumeInboundResponse | ServiceUnavailableError]: """Manually resume paused inbound email Manually lift the account-wide inbound pause. If the queued backlog is still above the ceiling the @@ -150,7 +156,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ResumeInboundResponse] + Response[ResumeInboundResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -168,7 +174,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ResumeInboundResponse | None: +) -> ResumeInboundResponse | ServiceUnavailableError | None: """Manually resume paused inbound email Manually lift the account-wide inbound pause. If the queued backlog is still above the ceiling the @@ -186,7 +192,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ResumeInboundResponse + ResumeInboundResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/run_agent_api_agents_agent_id_runs_post.py b/seclai/_generated/api/agents/run_agent_api_agents_agent_id_runs_post.py index 720b5c0..f01bd90 100644 --- a/seclai/_generated/api/agents/run_agent_api_agents_agent_id_runs_post.py +++ b/seclai/_generated/api/agents/run_agent_api_agents_agent_id_runs_post.py @@ -11,6 +11,7 @@ from ...models.agent_run_response import AgentRunResponse from ...models.http_validation_error import HTTPValidationError from ...models.insufficient_credits_response import InsufficientCreditsResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -45,7 +46,13 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse | None: +) -> ( + AgentRunResponse + | HTTPValidationError + | InsufficientCreditsResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = AgentRunResponse.from_dict(response.json()) @@ -61,6 +68,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -69,7 +81,12 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse]: +) -> Response[ + AgentRunResponse + | HTTPValidationError + | InsufficientCreditsResponse + | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -85,7 +102,12 @@ def sync_detailed( body: AgentRunRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse]: +) -> Response[ + AgentRunResponse + | HTTPValidationError + | InsufficientCreditsResponse + | ServiceUnavailableError +]: """Run an agent Start an agent run. @@ -100,8 +122,10 @@ def sync_detailed( Key fields: - `input`: text input for agents with a `dynamic_input` trigger. - - `input_upload_id`: alternatively, reference a file previously uploaded via `POST - /agents/{agent_id}/upload-input` (mutually exclusive with `input`). + - `input_upload_id` / `input_upload_ids`: reference one or more files previously uploaded via `POST + /agents/{agent_id}/upload-input`. Send them **with** `input` to pair prompt text with the files (the + text leads, each file's extracted text follows); only the two upload fields are mutually exclusive + with each other. - `priority`: set true for latency-sensitive, user-facing work. For agents with a `streaming_result` step, set `priority=true` to enable real-time token streaming; otherwise the run still proceeds, but without live token streaming. @@ -126,7 +150,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse] + Response[AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -150,7 +174,13 @@ def sync( body: AgentRunRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse | None: +) -> ( + AgentRunResponse + | HTTPValidationError + | InsufficientCreditsResponse + | ServiceUnavailableError + | None +): """Run an agent Start an agent run. @@ -165,8 +195,10 @@ def sync( Key fields: - `input`: text input for agents with a `dynamic_input` trigger. - - `input_upload_id`: alternatively, reference a file previously uploaded via `POST - /agents/{agent_id}/upload-input` (mutually exclusive with `input`). + - `input_upload_id` / `input_upload_ids`: reference one or more files previously uploaded via `POST + /agents/{agent_id}/upload-input`. Send them **with** `input` to pair prompt text with the files (the + text leads, each file's extracted text follows); only the two upload fields are mutually exclusive + with each other. - `priority`: set true for latency-sensitive, user-facing work. For agents with a `streaming_result` step, set `priority=true` to enable real-time token streaming; otherwise the run still proceeds, but without live token streaming. @@ -191,7 +223,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse + AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError """ return sync_detailed( @@ -210,7 +242,12 @@ async def asyncio_detailed( body: AgentRunRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse]: +) -> Response[ + AgentRunResponse + | HTTPValidationError + | InsufficientCreditsResponse + | ServiceUnavailableError +]: """Run an agent Start an agent run. @@ -225,8 +262,10 @@ async def asyncio_detailed( Key fields: - `input`: text input for agents with a `dynamic_input` trigger. - - `input_upload_id`: alternatively, reference a file previously uploaded via `POST - /agents/{agent_id}/upload-input` (mutually exclusive with `input`). + - `input_upload_id` / `input_upload_ids`: reference one or more files previously uploaded via `POST + /agents/{agent_id}/upload-input`. Send them **with** `input` to pair prompt text with the files (the + text leads, each file's extracted text follows); only the two upload fields are mutually exclusive + with each other. - `priority`: set true for latency-sensitive, user-facing work. For agents with a `streaming_result` step, set `priority=true` to enable real-time token streaming; otherwise the run still proceeds, but without live token streaming. @@ -251,7 +290,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse] + Response[AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -273,7 +312,13 @@ async def asyncio( body: AgentRunRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse | None: +) -> ( + AgentRunResponse + | HTTPValidationError + | InsufficientCreditsResponse + | ServiceUnavailableError + | None +): """Run an agent Start an agent run. @@ -288,8 +333,10 @@ async def asyncio( Key fields: - `input`: text input for agents with a `dynamic_input` trigger. - - `input_upload_id`: alternatively, reference a file previously uploaded via `POST - /agents/{agent_id}/upload-input` (mutually exclusive with `input`). + - `input_upload_id` / `input_upload_ids`: reference one or more files previously uploaded via `POST + /agents/{agent_id}/upload-input`. Send them **with** `input` to pair prompt text with the files (the + text leads, each file's extracted text follows); only the two upload fields are mutually exclusive + with each other. - `priority`: set true for latency-sensitive, user-facing work. For agents with a `streaming_result` step, set `priority=true` to enable real-time token streaming; otherwise the run still proceeds, but without live token streaming. @@ -314,7 +361,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse + AgentRunResponse | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/run_streaming_agent_api_agents_agent_id_runs_stream_post.py b/seclai/_generated/api/agents/run_streaming_agent_api_agents_agent_id_runs_stream_post.py index 73f7476..c9582ba 100644 --- a/seclai/_generated/api/agents/run_streaming_agent_api_agents_agent_id_runs_stream_post.py +++ b/seclai/_generated/api/agents/run_streaming_agent_api_agents_agent_id_runs_stream_post.py @@ -10,6 +10,7 @@ from ...models.agent_run_stream_request import AgentRunStreamRequest from ...models.http_validation_error import HTTPValidationError from ...models.insufficient_credits_response import InsufficientCreditsResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,13 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | InsufficientCreditsResponse | None: +) -> ( + Any + | HTTPValidationError + | InsufficientCreditsResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = response.json() return response_200 @@ -59,6 +66,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -67,7 +79,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError | InsufficientCreditsResponse]: +) -> Response[ + Any | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -83,7 +97,9 @@ def sync_detailed( body: AgentRunStreamRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | InsufficientCreditsResponse]: +) -> Response[ + Any | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError +]: """Run an agent (stream events) Start a **priority** agent run and stream run events using Server-Sent Events (SSE). @@ -100,13 +116,20 @@ def sync_detailed( Input options (for `dynamic_input` triggers): - `input`: text input passed directly. - - `input_upload_id`: reference a file uploaded via `POST /agents/{agent_id}/upload-input` (mutually - exclusive with `input`). + - `input_upload_id` / `input_upload_ids`: reference one or more files uploaded via `POST + /agents/{agent_id}/upload-input`. Combine either with `input` to send prompt text alongside the + files; only the two upload fields are mutually exclusive with each other. Client guidance: - Keep the connection open and handle keepalive comments. - On `timeout` or `error`, the payload includes `run_id` so clients can resume by polling `GET /agents/runs/{run_id}`. + - `stream_token` events carry the model's raw output. When the agent pairs `streaming_result` with a + sibling `extract_content`/`display_result` branch, that branch's `display_result` takes precedence + over the stream, so the `done` snapshot's `output` is the validated payload and the tokens are a + progress channel — render tokens live, but read the result from `done`. Check `done.status` first: + the streamed text is already the run's output when the stream ends, so a run that FAILED its + validation step still carries that raw text in `output`. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's @@ -123,7 +146,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | InsufficientCreditsResponse] + Response[Any | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -147,7 +170,13 @@ def sync( body: AgentRunStreamRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | InsufficientCreditsResponse | None: +) -> ( + Any + | HTTPValidationError + | InsufficientCreditsResponse + | ServiceUnavailableError + | None +): """Run an agent (stream events) Start a **priority** agent run and stream run events using Server-Sent Events (SSE). @@ -164,13 +193,20 @@ def sync( Input options (for `dynamic_input` triggers): - `input`: text input passed directly. - - `input_upload_id`: reference a file uploaded via `POST /agents/{agent_id}/upload-input` (mutually - exclusive with `input`). + - `input_upload_id` / `input_upload_ids`: reference one or more files uploaded via `POST + /agents/{agent_id}/upload-input`. Combine either with `input` to send prompt text alongside the + files; only the two upload fields are mutually exclusive with each other. Client guidance: - Keep the connection open and handle keepalive comments. - On `timeout` or `error`, the payload includes `run_id` so clients can resume by polling `GET /agents/runs/{run_id}`. + - `stream_token` events carry the model's raw output. When the agent pairs `streaming_result` with a + sibling `extract_content`/`display_result` branch, that branch's `display_result` takes precedence + over the stream, so the `done` snapshot's `output` is the validated payload and the tokens are a + progress channel — render tokens live, but read the result from `done`. Check `done.status` first: + the streamed text is already the run's output when the stream ends, so a run that FAILED its + validation step still carries that raw text in `output`. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's @@ -187,7 +223,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | InsufficientCreditsResponse + Any | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError """ return sync_detailed( @@ -206,7 +242,9 @@ async def asyncio_detailed( body: AgentRunStreamRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | InsufficientCreditsResponse]: +) -> Response[ + Any | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError +]: """Run an agent (stream events) Start a **priority** agent run and stream run events using Server-Sent Events (SSE). @@ -223,13 +261,20 @@ async def asyncio_detailed( Input options (for `dynamic_input` triggers): - `input`: text input passed directly. - - `input_upload_id`: reference a file uploaded via `POST /agents/{agent_id}/upload-input` (mutually - exclusive with `input`). + - `input_upload_id` / `input_upload_ids`: reference one or more files uploaded via `POST + /agents/{agent_id}/upload-input`. Combine either with `input` to send prompt text alongside the + files; only the two upload fields are mutually exclusive with each other. Client guidance: - Keep the connection open and handle keepalive comments. - On `timeout` or `error`, the payload includes `run_id` so clients can resume by polling `GET /agents/runs/{run_id}`. + - `stream_token` events carry the model's raw output. When the agent pairs `streaming_result` with a + sibling `extract_content`/`display_result` branch, that branch's `display_result` takes precedence + over the stream, so the `done` snapshot's `output` is the validated payload and the tokens are a + progress channel — render tokens live, but read the result from `done`. Check `done.status` first: + the streamed text is already the run's output when the stream ends, so a run that FAILED its + validation step still carries that raw text in `output`. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's @@ -246,7 +291,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | InsufficientCreditsResponse] + Response[Any | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -268,7 +313,13 @@ async def asyncio( body: AgentRunStreamRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | InsufficientCreditsResponse | None: +) -> ( + Any + | HTTPValidationError + | InsufficientCreditsResponse + | ServiceUnavailableError + | None +): """Run an agent (stream events) Start a **priority** agent run and stream run events using Server-Sent Events (SSE). @@ -285,13 +336,20 @@ async def asyncio( Input options (for `dynamic_input` triggers): - `input`: text input passed directly. - - `input_upload_id`: reference a file uploaded via `POST /agents/{agent_id}/upload-input` (mutually - exclusive with `input`). + - `input_upload_id` / `input_upload_ids`: reference one or more files uploaded via `POST + /agents/{agent_id}/upload-input`. Combine either with `input` to send prompt text alongside the + files; only the two upload fields are mutually exclusive with each other. Client guidance: - Keep the connection open and handle keepalive comments. - On `timeout` or `error`, the payload includes `run_id` so clients can resume by polling `GET /agents/runs/{run_id}`. + - `stream_token` events carry the model's raw output. When the agent pairs `streaming_result` with a + sibling `extract_content`/`display_result` branch, that branch's `display_result` takes precedence + over the stream, so the `done` snapshot's `output` is the validated payload and the tokens are a + progress channel — render tokens live, but read the result from `done`. Check `done.status` first: + the streamed text is already the run's output when the stream ends, so a run that FAILED its + validation step still carries that raw text in `output`. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's @@ -308,7 +366,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | InsufficientCreditsResponse + Any | HTTPValidationError | InsufficientCreditsResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/search_agent_runs_api_agents_runs_search_post.py b/seclai/_generated/api/agents/search_agent_runs_api_agents_runs_search_post.py index 8b03e67..1ae3416 100644 --- a/seclai/_generated/api/agents/search_agent_runs_api_agents_runs_search_post.py +++ b/seclai/_generated/api/agents/search_agent_runs_api_agents_runs_search_post.py @@ -9,6 +9,7 @@ from ...models.agent_trace_search_request import AgentTraceSearchRequest from ...models.agent_trace_search_response import AgentTraceSearchResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentTraceSearchResponse | HTTPValidationError | None: +) -> AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentTraceSearchResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentTraceSearchResponse | HTTPValidationError]: +) -> Response[AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +80,7 @@ def sync_detailed( body: AgentTraceSearchRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentTraceSearchResponse | HTTPValidationError]: +) -> Response[AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError]: """Search agent traces Search agent traces using semantic similarity. @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentTraceSearchResponse | HTTPValidationError] + Response[AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -120,7 +126,7 @@ def sync( body: AgentTraceSearchRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentTraceSearchResponse | HTTPValidationError | None: +) -> AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError | None: """Search agent traces Search agent traces using semantic similarity. @@ -144,7 +150,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentTraceSearchResponse | HTTPValidationError + AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -161,7 +167,7 @@ async def asyncio_detailed( body: AgentTraceSearchRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentTraceSearchResponse | HTTPValidationError]: +) -> Response[AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError]: """Search agent traces Search agent traces using semantic similarity. @@ -185,7 +191,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentTraceSearchResponse | HTTPValidationError] + Response[AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -205,7 +211,7 @@ async def asyncio( body: AgentTraceSearchRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentTraceSearchResponse | HTTPValidationError | None: +) -> AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError | None: """Search agent traces Search agent traces using semantic similarity. @@ -229,7 +235,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentTraceSearchResponse | HTTPValidationError + AgentTraceSearchResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/set_auto_block_mode_api_api_agents_blocked_email_senders_mode_put.py b/seclai/_generated/api/agents/set_auto_block_mode_api_api_agents_blocked_email_senders_mode_put.py index bd86896..05b6a8a 100644 --- a/seclai/_generated/api/agents/set_auto_block_mode_api_api_agents_blocked_email_senders_mode_put.py +++ b/seclai/_generated/api/agents/set_auto_block_mode_api_api_agents_blocked_email_senders_mode_put.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.blocked_email_sender_list_response import BlockedEmailSenderListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.set_auto_block_mode_request import SetAutoBlockModeRequest from ...types import UNSET, Response, Unset @@ -40,7 +41,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> BlockedEmailSenderListResponse | HTTPValidationError | None: +) -> ( + BlockedEmailSenderListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = BlockedEmailSenderListResponse.from_dict(response.json()) @@ -51,6 +57,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +70,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[BlockedEmailSenderListResponse | HTTPValidationError]: +) -> Response[ + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +87,9 @@ def sync_detailed( body: SetAutoBlockModeRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[BlockedEmailSenderListResponse | HTTPValidationError]: +) -> Response[ + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError +]: """Set the governance auto-block mode Set whether a governance BLOCK on an authenticated inbound email sender auto-adds them to the @@ -94,7 +109,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[BlockedEmailSenderListResponse | HTTPValidationError] + Response[BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -116,7 +131,12 @@ def sync( body: SetAutoBlockModeRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> BlockedEmailSenderListResponse | HTTPValidationError | None: +) -> ( + BlockedEmailSenderListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Set the governance auto-block mode Set whether a governance BLOCK on an authenticated inbound email sender auto-adds them to the @@ -136,7 +156,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - BlockedEmailSenderListResponse | HTTPValidationError + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -153,7 +173,9 @@ async def asyncio_detailed( body: SetAutoBlockModeRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[BlockedEmailSenderListResponse | HTTPValidationError]: +) -> Response[ + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError +]: """Set the governance auto-block mode Set whether a governance BLOCK on an authenticated inbound email sender auto-adds them to the @@ -173,7 +195,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[BlockedEmailSenderListResponse | HTTPValidationError] + Response[BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -193,7 +215,12 @@ async def asyncio( body: SetAutoBlockModeRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> BlockedEmailSenderListResponse | HTTPValidationError | None: +) -> ( + BlockedEmailSenderListResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Set the governance auto-block mode Set whether a governance BLOCK on an authenticated inbound email sender auto-adds them to the @@ -213,7 +240,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - BlockedEmailSenderListResponse | HTTPValidationError + BlockedEmailSenderListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/set_email_trigger_config_api_api_agents_agent_id_triggers_trigger_id_email_config_put.py b/seclai/_generated/api/agents/set_email_trigger_config_api_api_agents_agent_id_triggers_trigger_id_email_config_put.py index 159f2de..5ec9910 100644 --- a/seclai/_generated/api/agents/set_email_trigger_config_api_api_agents_agent_id_triggers_trigger_id_email_config_put.py +++ b/seclai/_generated/api/agents/set_email_trigger_config_api_api_agents_agent_id_triggers_trigger_id_email_config_put.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.email_trigger_config_response import EmailTriggerConfigResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.set_email_trigger_config_request import SetEmailTriggerConfigRequest from ...types import UNSET, Response, Unset @@ -46,7 +47,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EmailTriggerConfigResponse | HTTPValidationError | None: +) -> EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = EmailTriggerConfigResponse.from_dict(response.json()) @@ -57,6 +58,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +71,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EmailTriggerConfigResponse | HTTPValidationError]: +) -> Response[ + EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -82,7 +90,9 @@ def sync_detailed( body: SetEmailTriggerConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailTriggerConfigResponse | HTTPValidationError]: +) -> Response[ + EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError +]: """Configure an EMAIL_RECEIVED trigger Set the custom alias, sender allowlist, and inbound-handling flags (`ignore_auto_generated`, @@ -108,7 +118,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailTriggerConfigResponse | HTTPValidationError] + Response[EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -134,7 +144,7 @@ def sync( body: SetEmailTriggerConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailTriggerConfigResponse | HTTPValidationError | None: +) -> EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Configure an EMAIL_RECEIVED trigger Set the custom alias, sender allowlist, and inbound-handling flags (`ignore_auto_generated`, @@ -160,7 +170,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailTriggerConfigResponse | HTTPValidationError + EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -181,7 +191,9 @@ async def asyncio_detailed( body: SetEmailTriggerConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailTriggerConfigResponse | HTTPValidationError]: +) -> Response[ + EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError +]: """Configure an EMAIL_RECEIVED trigger Set the custom alias, sender allowlist, and inbound-handling flags (`ignore_auto_generated`, @@ -207,7 +219,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailTriggerConfigResponse | HTTPValidationError] + Response[EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -231,7 +243,7 @@ async def asyncio( body: SetEmailTriggerConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailTriggerConfigResponse | HTTPValidationError | None: +) -> EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Configure an EMAIL_RECEIVED trigger Set the custom alias, sender allowlist, and inbound-handling flags (`ignore_auto_generated`, @@ -257,7 +269,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailTriggerConfigResponse | HTTPValidationError + EmailTriggerConfigResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/unblock_email_sender_api_api_agents_blocked_email_senders_blocked_id_delete.py b/seclai/_generated/api/agents/unblock_email_sender_api_api_agents_blocked_email_senders_blocked_id_delete.py index b75fd09..fbc9012 100644 --- a/seclai/_generated/api/agents/unblock_email_sender_api_api_agents_blocked_email_senders_blocked_id_delete.py +++ b/seclai/_generated/api/agents/unblock_email_sender_api_api_agents_blocked_email_senders_blocked_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Unblock an inbound email sender Remove a blocked sender by id. @@ -88,7 +94,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -110,7 +116,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Unblock an inbound email sender Remove a blocked sender by id. @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Unblock an inbound email sender Remove a blocked sender by id. @@ -163,7 +169,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Unblock an inbound email sender Remove a blocked sender by id. @@ -201,7 +207,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/update_agent_api_agents_agent_id_put.py b/seclai/_generated/api/agents/update_agent_api_agents_agent_id_put.py index c290bf9..d3688e3 100644 --- a/seclai/_generated/api/agents/update_agent_api_agents_agent_id_put.py +++ b/seclai/_generated/api/agents/update_agent_api_agents_agent_id_put.py @@ -11,6 +11,7 @@ AgentDefinitionImportErrorResponse, ) from ...models.agent_summary_response import AgentSummaryResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.update_agent_request import UpdateAgentRequest from ...types import UNSET, Response, Unset @@ -46,7 +47,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentDefinitionImportErrorResponse | AgentSummaryResponse | None: +) -> ( + AgentDefinitionImportErrorResponse + | AgentSummaryResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = AgentSummaryResponse.from_dict(response.json()) @@ -57,6 +63,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +76,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse]: +) -> Response[ + AgentDefinitionImportErrorResponse | AgentSummaryResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -81,7 +94,9 @@ def sync_detailed( body: UpdateAgentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse]: +) -> Response[ + AgentDefinitionImportErrorResponse | AgentSummaryResponse | ServiceUnavailableError +]: """Update agent metadata Update an agent's name, description, evaluation settings, and model lifecycle settings. @@ -120,7 +135,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse] + Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -144,7 +159,12 @@ def sync( body: UpdateAgentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionImportErrorResponse | AgentSummaryResponse | None: +) -> ( + AgentDefinitionImportErrorResponse + | AgentSummaryResponse + | ServiceUnavailableError + | None +): """Update agent metadata Update an agent's name, description, evaluation settings, and model lifecycle settings. @@ -183,7 +203,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionImportErrorResponse | AgentSummaryResponse + AgentDefinitionImportErrorResponse | AgentSummaryResponse | ServiceUnavailableError """ return sync_detailed( @@ -202,7 +222,9 @@ async def asyncio_detailed( body: UpdateAgentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse]: +) -> Response[ + AgentDefinitionImportErrorResponse | AgentSummaryResponse | ServiceUnavailableError +]: """Update agent metadata Update an agent's name, description, evaluation settings, and model lifecycle settings. @@ -241,7 +263,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse] + Response[AgentDefinitionImportErrorResponse | AgentSummaryResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -263,7 +285,12 @@ async def asyncio( body: UpdateAgentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionImportErrorResponse | AgentSummaryResponse | None: +) -> ( + AgentDefinitionImportErrorResponse + | AgentSummaryResponse + | ServiceUnavailableError + | None +): """Update agent metadata Update an agent's name, description, evaluation settings, and model lifecycle settings. @@ -302,7 +329,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionImportErrorResponse | AgentSummaryResponse + AgentDefinitionImportErrorResponse | AgentSummaryResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/agents/update_agent_definition_api_agents_agent_id_definition_put.py b/seclai/_generated/api/agents/update_agent_definition_api_agents_agent_id_definition_put.py index 9eb265f..460f9d6 100644 --- a/seclai/_generated/api/agents/update_agent_definition_api_agents_agent_id_definition_put.py +++ b/seclai/_generated/api/agents/update_agent_definition_api_agents_agent_id_definition_put.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.agent_definition_response import AgentDefinitionResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.update_agent_definition_request import UpdateAgentDefinitionRequest from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentDefinitionResponse | HTTPValidationError | None: +) -> AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AgentDefinitionResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentDefinitionResponse | HTTPValidationError]: +) -> Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: UpdateAgentDefinitionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionResponse | HTTPValidationError]: +) -> Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError]: """Update agent definition Update the agent's definition on the main branch. @@ -124,7 +130,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionResponse | HTTPValidationError] + Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -148,7 +154,7 @@ def sync( body: UpdateAgentDefinitionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionResponse | HTTPValidationError | None: +) -> AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError | None: """Update agent definition Update the agent's definition on the main branch. @@ -193,7 +199,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionResponse | HTTPValidationError + AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -212,7 +218,7 @@ async def asyncio_detailed( body: UpdateAgentDefinitionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AgentDefinitionResponse | HTTPValidationError]: +) -> Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError]: """Update agent definition Update the agent's definition on the main branch. @@ -257,7 +263,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AgentDefinitionResponse | HTTPValidationError] + Response[AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -279,7 +285,7 @@ async def asyncio( body: UpdateAgentDefinitionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AgentDefinitionResponse | HTTPValidationError | None: +) -> AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError | None: """Update agent definition Update the agent's definition on the main branch. @@ -324,7 +330,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AgentDefinitionResponse | HTTPValidationError + AgentDefinitionResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/ai_assistant/api_ai_accept_api_ai_assistant_conversation_id_accept_post.py b/seclai/_generated/api/ai_assistant/api_ai_accept_api_ai_assistant_conversation_id_accept_post.py index 752f224..6ec4404 100644 --- a/seclai/_generated/api/ai_assistant/api_ai_accept_api_ai_assistant_conversation_id_accept_post.py +++ b/seclai/_generated/api/ai_assistant/api_ai_accept_api_ai_assistant_conversation_id_accept_post.py @@ -10,6 +10,7 @@ from ...models.ai_assistant_accept_request import AiAssistantAcceptRequest from ...models.ai_assistant_accept_response import AiAssistantAcceptResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiAssistantAcceptResponse | HTTPValidationError | None: +) -> AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AiAssistantAcceptResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiAssistantAcceptResponse | HTTPValidationError]: +) -> Response[ + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +87,9 @@ def sync_detailed( body: AiAssistantAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantAcceptResponse | HTTPValidationError]: +) -> Response[ + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError +]: """Accept and execute a standalone plan Accept and execute a previously proposed standalone plan. If the plan contains destructive actions @@ -98,7 +108,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantAcceptResponse | HTTPValidationError] + Response[AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -122,7 +132,7 @@ def sync( body: AiAssistantAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantAcceptResponse | HTTPValidationError | None: +) -> AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError | None: """Accept and execute a standalone plan Accept and execute a previously proposed standalone plan. If the plan contains destructive actions @@ -141,7 +151,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantAcceptResponse | HTTPValidationError + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -160,7 +170,9 @@ async def asyncio_detailed( body: AiAssistantAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantAcceptResponse | HTTPValidationError]: +) -> Response[ + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError +]: """Accept and execute a standalone plan Accept and execute a previously proposed standalone plan. If the plan contains destructive actions @@ -179,7 +191,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantAcceptResponse | HTTPValidationError] + Response[AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -201,7 +213,7 @@ async def asyncio( body: AiAssistantAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantAcceptResponse | HTTPValidationError | None: +) -> AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError | None: """Accept and execute a standalone plan Accept and execute a previously proposed standalone plan. If the plan contains destructive actions @@ -220,7 +232,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantAcceptResponse | HTTPValidationError + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/ai_assistant/api_ai_decline_api_ai_assistant_conversation_id_decline_post.py b/seclai/_generated/api/ai_assistant/api_ai_decline_api_ai_assistant_conversation_id_decline_post.py index f366512..aac5502 100644 --- a/seclai/_generated/api/ai_assistant/api_ai_decline_api_ai_assistant_conversation_id_decline_post.py +++ b/seclai/_generated/api/ai_assistant/api_ai_decline_api_ai_assistant_conversation_id_decline_post.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Decline a standalone plan Decline a previously proposed standalone plan. No resources are modified. The conversation is marked @@ -88,7 +94,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -110,7 +116,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Decline a standalone plan Decline a previously proposed standalone plan. No resources are modified. The conversation is marked @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Decline a standalone plan Decline a previously proposed standalone plan. No resources are modified. The conversation is marked @@ -163,7 +169,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Decline a standalone plan Decline a previously proposed standalone plan. No resources are modified. The conversation is marked @@ -201,7 +207,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/ai_assistant/api_ai_feedback_api_ai_assistant_feedback_post.py b/seclai/_generated/api/ai_assistant/api_ai_feedback_api_ai_assistant_feedback_post.py index 1dcb576..099170c 100644 --- a/seclai/_generated/api/ai_assistant/api_ai_feedback_api_ai_assistant_feedback_post.py +++ b/seclai/_generated/api/ai_assistant/api_ai_feedback_api_ai_assistant_feedback_post.py @@ -9,6 +9,7 @@ from ...models.ai_assistant_feedback_request import AiAssistantFeedbackRequest from ...models.ai_assistant_feedback_response import AiAssistantFeedbackResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiAssistantFeedbackResponse | HTTPValidationError | None: +) -> AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AiAssistantFeedbackResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiAssistantFeedbackResponse | HTTPValidationError]: +) -> Response[ + AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +82,9 @@ def sync_detailed( body: AiAssistantFeedbackRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantFeedbackResponse | HTTPValidationError]: +) -> Response[ + AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError +]: """Submit AI assistant feedback Submit thumbs-up/down feedback on any AI assistant interaction. Negative feedback with a comment is @@ -92,7 +102,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantFeedbackResponse | HTTPValidationError] + Response[AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +124,7 @@ def sync( body: AiAssistantFeedbackRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantFeedbackResponse | HTTPValidationError | None: +) -> AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError | None: """Submit AI assistant feedback Submit thumbs-up/down feedback on any AI assistant interaction. Negative feedback with a comment is @@ -132,7 +142,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantFeedbackResponse | HTTPValidationError + AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +159,9 @@ async def asyncio_detailed( body: AiAssistantFeedbackRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantFeedbackResponse | HTTPValidationError]: +) -> Response[ + AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError +]: """Submit AI assistant feedback Submit thumbs-up/down feedback on any AI assistant interaction. Negative feedback with a comment is @@ -167,7 +179,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantFeedbackResponse | HTTPValidationError] + Response[AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -187,7 +199,7 @@ async def asyncio( body: AiAssistantFeedbackRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantFeedbackResponse | HTTPValidationError | None: +) -> AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError | None: """Submit AI assistant feedback Submit thumbs-up/down feedback on any AI assistant interaction. Negative feedback with a comment is @@ -205,7 +217,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantFeedbackResponse | HTTPValidationError + AiAssistantFeedbackResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/ai_assistant/api_ai_knowledge_base_api_ai_assistant_knowledge_base_post.py b/seclai/_generated/api/ai_assistant/api_ai_knowledge_base_api_ai_assistant_knowledge_base_post.py index 3e391c6..eef51f1 100644 --- a/seclai/_generated/api/ai_assistant/api_ai_knowledge_base_api_ai_assistant_knowledge_base_post.py +++ b/seclai/_generated/api/ai_assistant/api_ai_knowledge_base_api_ai_assistant_knowledge_base_post.py @@ -9,6 +9,7 @@ from ...models.ai_assistant_generate_request import AiAssistantGenerateRequest from ...models.ai_assistant_generate_response import AiAssistantGenerateResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AiAssistantGenerateResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +82,9 @@ def sync_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate a knowledge base plan (standalone) Generate a knowledge base creation/modification plan without requiring an existing solution. May @@ -92,7 +102,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +124,7 @@ def sync( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate a knowledge base plan (standalone) Generate a knowledge base creation/modification plan without requiring an existing solution. May @@ -132,7 +142,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +159,9 @@ async def asyncio_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate a knowledge base plan (standalone) Generate a knowledge base creation/modification plan without requiring an existing solution. May @@ -167,7 +179,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -187,7 +199,7 @@ async def asyncio( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate a knowledge base plan (standalone) Generate a knowledge base creation/modification plan without requiring an existing solution. May @@ -205,7 +217,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/ai_assistant/api_ai_memory_bank_accept_api_ai_assistant_memory_bank_conversation_id_patch.py b/seclai/_generated/api/ai_assistant/api_ai_memory_bank_accept_api_ai_assistant_memory_bank_conversation_id_patch.py index cc3674f..64c2ba4 100644 --- a/seclai/_generated/api/ai_assistant/api_ai_memory_bank_accept_api_ai_assistant_memory_bank_conversation_id_patch.py +++ b/seclai/_generated/api/ai_assistant/api_ai_memory_bank_accept_api_ai_assistant_memory_bank_conversation_id_patch.py @@ -10,6 +10,7 @@ from ...models.http_validation_error import HTTPValidationError from ...models.memory_bank_accept_request import MemoryBankAcceptRequest from ...models.ok_response import OkResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | OkResponse | None: +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = OkResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | OkResponse]: +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: MemoryBankAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OkResponse]: +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: """Accept or decline a memory bank AI suggestion Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to @@ -99,7 +105,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OkResponse] + Response[HTTPValidationError | OkResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -123,7 +129,7 @@ def sync( body: MemoryBankAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OkResponse | None: +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: """Accept or decline a memory bank AI suggestion Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to @@ -143,7 +149,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OkResponse + HTTPValidationError | OkResponse | ServiceUnavailableError """ return sync_detailed( @@ -162,7 +168,7 @@ async def asyncio_detailed( body: MemoryBankAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OkResponse]: +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: """Accept or decline a memory bank AI suggestion Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to @@ -182,7 +188,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OkResponse] + Response[HTTPValidationError | OkResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -204,7 +210,7 @@ async def asyncio( body: MemoryBankAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OkResponse | None: +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: """Accept or decline a memory bank AI suggestion Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to @@ -224,7 +230,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OkResponse + HTTPValidationError | OkResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/ai_assistant/api_ai_memory_bank_api_ai_assistant_memory_bank_post.py b/seclai/_generated/api/ai_assistant/api_ai_memory_bank_api_ai_assistant_memory_bank_post.py index 1d9e8c1..6ed26fd 100644 --- a/seclai/_generated/api/ai_assistant/api_ai_memory_bank_api_ai_assistant_memory_bank_post.py +++ b/seclai/_generated/api/ai_assistant/api_ai_memory_bank_api_ai_assistant_memory_bank_post.py @@ -9,6 +9,7 @@ from ...models.http_validation_error import HTTPValidationError from ...models.memory_bank_ai_assistant_request import MemoryBankAiAssistantRequest from ...models.memory_bank_ai_assistant_response import MemoryBankAiAssistantResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,9 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | MemoryBankAiAssistantResponse | None: +) -> ( + HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError | None +): if response.status_code == 200: response_200 = MemoryBankAiAssistantResponse.from_dict(response.json()) @@ -51,6 +54,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +67,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | MemoryBankAiAssistantResponse]: +) -> Response[ + HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +84,9 @@ def sync_detailed( body: MemoryBankAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBankAiAssistantResponse]: +) -> Response[ + HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError +]: """Generate a memory bank configuration (standalone) Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, @@ -92,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBankAiAssistantResponse] + Response[HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +126,9 @@ def sync( body: MemoryBankAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBankAiAssistantResponse | None: +) -> ( + HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError | None +): """Generate a memory bank configuration (standalone) Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, @@ -132,7 +146,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBankAiAssistantResponse + HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +163,9 @@ async def asyncio_detailed( body: MemoryBankAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBankAiAssistantResponse]: +) -> Response[ + HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError +]: """Generate a memory bank configuration (standalone) Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, @@ -167,7 +183,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBankAiAssistantResponse] + Response[HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -187,7 +203,9 @@ async def asyncio( body: MemoryBankAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBankAiAssistantResponse | None: +) -> ( + HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError | None +): """Generate a memory bank configuration (standalone) Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, @@ -205,7 +223,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBankAiAssistantResponse + HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/ai_assistant/api_ai_memory_bank_history_api_ai_assistant_memory_bank_last_conversation_get.py b/seclai/_generated/api/ai_assistant/api_ai_memory_bank_history_api_ai_assistant_memory_bank_last_conversation_get.py index eadc152..3df1051 100644 --- a/seclai/_generated/api/ai_assistant/api_ai_memory_bank_history_api_ai_assistant_memory_bank_last_conversation_get.py +++ b/seclai/_generated/api/ai_assistant/api_ai_memory_bank_history_api_ai_assistant_memory_bank_last_conversation_get.py @@ -10,6 +10,7 @@ from ...models.memory_bank_last_conversation_response import ( MemoryBankLastConversationResponse, ) +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -47,7 +48,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | MemoryBankLastConversationResponse | None: +) -> ( + HTTPValidationError + | MemoryBankLastConversationResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = MemoryBankLastConversationResponse.from_dict(response.json()) @@ -58,6 +64,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -66,7 +77,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | MemoryBankLastConversationResponse]: +) -> Response[ + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -82,7 +95,9 @@ def sync_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBankLastConversationResponse]: +) -> Response[ + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError +]: """Fetch memory bank AI conversation history Fetch the most recent memory bank AI assistant conversation turns for the authenticated user. @@ -102,7 +117,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBankLastConversationResponse] + Response[HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -126,7 +141,12 @@ def sync( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBankLastConversationResponse | None: +) -> ( + HTTPValidationError + | MemoryBankLastConversationResponse + | ServiceUnavailableError + | None +): """Fetch memory bank AI conversation history Fetch the most recent memory bank AI assistant conversation turns for the authenticated user. @@ -146,7 +166,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBankLastConversationResponse + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError """ return sync_detailed( @@ -165,7 +185,9 @@ async def asyncio_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBankLastConversationResponse]: +) -> Response[ + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError +]: """Fetch memory bank AI conversation history Fetch the most recent memory bank AI assistant conversation turns for the authenticated user. @@ -185,7 +207,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBankLastConversationResponse] + Response[HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -207,7 +229,12 @@ async def asyncio( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBankLastConversationResponse | None: +) -> ( + HTTPValidationError + | MemoryBankLastConversationResponse + | ServiceUnavailableError + | None +): """Fetch memory bank AI conversation history Fetch the most recent memory bank AI assistant conversation turns for the authenticated user. @@ -227,7 +254,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBankLastConversationResponse + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/ai_assistant/api_ai_solution_api_ai_assistant_solution_post.py b/seclai/_generated/api/ai_assistant/api_ai_solution_api_ai_assistant_solution_post.py index f82288e..f45736e 100644 --- a/seclai/_generated/api/ai_assistant/api_ai_solution_api_ai_assistant_solution_post.py +++ b/seclai/_generated/api/ai_assistant/api_ai_solution_api_ai_assistant_solution_post.py @@ -9,6 +9,7 @@ from ...models.ai_assistant_generate_request import AiAssistantGenerateRequest from ...models.ai_assistant_generate_response import AiAssistantGenerateResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AiAssistantGenerateResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +82,9 @@ def sync_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate a solution plan (standalone) Generate a complete solution plan covering sources, knowledge bases, and agents without requiring an @@ -92,7 +102,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +124,7 @@ def sync( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate a solution plan (standalone) Generate a complete solution plan covering sources, knowledge bases, and agents without requiring an @@ -132,7 +142,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +159,9 @@ async def asyncio_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate a solution plan (standalone) Generate a complete solution plan covering sources, knowledge bases, and agents without requiring an @@ -167,7 +179,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -187,7 +199,7 @@ async def asyncio( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate a solution plan (standalone) Generate a complete solution plan covering sources, knowledge bases, and agents without requiring an @@ -205,7 +217,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/ai_assistant/api_ai_source_api_ai_assistant_source_post.py b/seclai/_generated/api/ai_assistant/api_ai_source_api_ai_assistant_source_post.py index b26f986..6922856 100644 --- a/seclai/_generated/api/ai_assistant/api_ai_source_api_ai_assistant_source_post.py +++ b/seclai/_generated/api/ai_assistant/api_ai_source_api_ai_assistant_source_post.py @@ -9,6 +9,7 @@ from ...models.ai_assistant_generate_request import AiAssistantGenerateRequest from ...models.ai_assistant_generate_response import AiAssistantGenerateResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AiAssistantGenerateResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +82,9 @@ def sync_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate a source plan (standalone) Generate a content source creation/modification plan without requiring an existing solution. The AI @@ -92,7 +102,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +124,7 @@ def sync( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate a source plan (standalone) Generate a content source creation/modification plan without requiring an existing solution. The AI @@ -132,7 +142,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +159,9 @@ async def asyncio_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate a source plan (standalone) Generate a content source creation/modification plan without requiring an existing solution. The AI @@ -167,7 +179,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -187,7 +199,7 @@ async def asyncio( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate a source plan (standalone) Generate a content source creation/modification plan without requiring an existing solution. The AI @@ -205,7 +217,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/add_alert_comment_api_alerts_alert_id_comments_post.py b/seclai/_generated/api/alerts/add_alert_comment_api_alerts_alert_id_comments_post.py index a4ea912..2425942 100644 --- a/seclai/_generated/api/alerts/add_alert_comment_api_alerts_alert_id_comments_post.py +++ b/seclai/_generated/api/alerts/add_alert_comment_api_alerts_alert_id_comments_post.py @@ -10,6 +10,7 @@ from ...models.add_comment_request import AddCommentRequest from ...models.alert_detail_response import AlertDetailResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AlertDetailResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: AddCommentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Add alert comment Add a comment to an alert. Comments are visible to all subscribers and are included in the alert @@ -99,7 +105,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -123,7 +129,7 @@ def sync( body: AddCommentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Add alert comment Add a comment to an alert. Comments are visible to all subscribers and are included in the alert @@ -143,7 +149,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -162,7 +168,7 @@ async def asyncio_detailed( body: AddCommentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Add alert comment Add a comment to an alert. Comments are visible to all subscribers and are included in the alert @@ -182,7 +188,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -204,7 +210,7 @@ async def asyncio( body: AddCommentRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Add alert comment Add a comment to an alert. Comments are visible to all subscribers and are included in the alert @@ -224,7 +230,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/change_alert_status_api_alerts_alert_id_status_post.py b/seclai/_generated/api/alerts/change_alert_status_api_alerts_alert_id_status_post.py index d779479..807b0f7 100644 --- a/seclai/_generated/api/alerts/change_alert_status_api_alerts_alert_id_status_post.py +++ b/seclai/_generated/api/alerts/change_alert_status_api_alerts_alert_id_status_post.py @@ -10,6 +10,7 @@ from ...models.alert_detail_response import AlertDetailResponse from ...models.change_status_request import ChangeStatusRequest from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AlertDetailResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: ChangeStatusRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Change alert status Change the status of an alert. Valid statuses: triggered, acknowledged, resolved, dismissed. @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -122,7 +128,7 @@ def sync( body: ChangeStatusRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Change alert status Change the status of an alert. Valid statuses: triggered, acknowledged, resolved, dismissed. @@ -141,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -160,7 +166,7 @@ async def asyncio_detailed( body: ChangeStatusRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Change alert status Change the status of an alert. Valid statuses: triggered, acknowledged, resolved, dismissed. @@ -179,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -201,7 +207,7 @@ async def asyncio( body: ChangeStatusRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Change alert status Change the status of an alert. Valid statuses: triggered, acknowledged, resolved, dismissed. @@ -220,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/create_alert_config_api_alerts_configs_post.py b/seclai/_generated/api/alerts/create_alert_config_api_alerts_configs_post.py index c441edf..0e6ba13 100644 --- a/seclai/_generated/api/alerts/create_alert_config_api_alerts_configs_post.py +++ b/seclai/_generated/api/alerts/create_alert_config_api_alerts_configs_post.py @@ -9,6 +9,7 @@ from ...models.alert_config_response import AlertConfigResponse from ...models.create_alert_config_request import CreateAlertConfigRequest from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertConfigResponse | HTTPValidationError | None: +) -> AlertConfigResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 201: response_201 = AlertConfigResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertConfigResponse | HTTPValidationError]: +) -> Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +80,7 @@ def sync_detailed( body: CreateAlertConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertConfigResponse | HTTPValidationError]: +) -> Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError]: """Create alert config Create a new alert configuration. @@ -101,7 +107,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertConfigResponse | HTTPValidationError] + Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -123,7 +129,7 @@ def sync( body: CreateAlertConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertConfigResponse | HTTPValidationError | None: +) -> AlertConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Create alert config Create a new alert configuration. @@ -150,7 +156,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertConfigResponse | HTTPValidationError + AlertConfigResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -167,7 +173,7 @@ async def asyncio_detailed( body: CreateAlertConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertConfigResponse | HTTPValidationError]: +) -> Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError]: """Create alert config Create a new alert configuration. @@ -194,7 +200,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertConfigResponse | HTTPValidationError] + Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -214,7 +220,7 @@ async def asyncio( body: CreateAlertConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertConfigResponse | HTTPValidationError | None: +) -> AlertConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Create alert config Create a new alert configuration. @@ -241,7 +247,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertConfigResponse | HTTPValidationError + AlertConfigResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/delete_alert_config_api_alerts_configs_config_id_delete.py b/seclai/_generated/api/alerts/delete_alert_config_api_alerts_configs_config_id_delete.py index 43820e9..5002875 100644 --- a/seclai/_generated/api/alerts/delete_alert_config_api_alerts_configs_config_id_delete.py +++ b/seclai/_generated/api/alerts/delete_alert_config_api_alerts_configs_config_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete alert config Delete an alert configuration. This permanently removes the config and stops any future alerts of @@ -89,7 +95,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -111,7 +117,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete alert config Delete an alert configuration. This permanently removes the config and stops any future alerts of @@ -130,7 +136,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -147,7 +153,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete alert config Delete an alert configuration. This permanently removes the config and stops any future alerts of @@ -166,7 +172,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -186,7 +192,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete alert config Delete an alert configuration. This permanently removes the config and stops any future alerts of @@ -205,7 +211,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/get_alert_config_api_alerts_configs_config_id_get.py b/seclai/_generated/api/alerts/get_alert_config_api_alerts_configs_config_id_get.py index 98af202..2d1d896 100644 --- a/seclai/_generated/api/alerts/get_alert_config_api_alerts_configs_config_id_get.py +++ b/seclai/_generated/api/alerts/get_alert_config_api_alerts_configs_config_id_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.alert_config_response import AlertConfigResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertConfigResponse | HTTPValidationError | None: +) -> AlertConfigResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AlertConfigResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertConfigResponse | HTTPValidationError]: +) -> Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertConfigResponse | HTTPValidationError]: +) -> Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError]: """Get alert config Get a specific alert configuration by ID. @@ -93,7 +99,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertConfigResponse | HTTPValidationError] + Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -115,7 +121,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertConfigResponse | HTTPValidationError | None: +) -> AlertConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Get alert config Get a specific alert configuration by ID. @@ -136,7 +142,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertConfigResponse | HTTPValidationError + AlertConfigResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -153,7 +159,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertConfigResponse | HTTPValidationError]: +) -> Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError]: """Get alert config Get a specific alert configuration by ID. @@ -174,7 +180,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertConfigResponse | HTTPValidationError] + Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -194,7 +200,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertConfigResponse | HTTPValidationError | None: +) -> AlertConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Get alert config Get a specific alert configuration by ID. @@ -215,7 +221,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertConfigResponse | HTTPValidationError + AlertConfigResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/get_alert_detail_api_alerts_alert_id_get.py b/seclai/_generated/api/alerts/get_alert_detail_api_alerts_alert_id_get.py index 0420d4e..4771f78 100644 --- a/seclai/_generated/api/alerts/get_alert_detail_api_alerts_alert_id_get.py +++ b/seclai/_generated/api/alerts/get_alert_detail_api_alerts_alert_id_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.alert_detail_response import AlertDetailResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AlertDetailResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Get alert detail Get full alert detail including history, comments, and subscribers. @@ -90,7 +96,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -112,7 +118,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Get alert detail Get full alert detail including history, comments, and subscribers. @@ -130,7 +136,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -147,7 +153,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Get alert detail Get full alert detail including history, comments, and subscribers. @@ -165,7 +171,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -185,7 +191,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Get alert detail Get full alert detail including history, comments, and subscribers. @@ -203,7 +209,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/list_alert_configs_api_alerts_configs_get.py b/seclai/_generated/api/alerts/list_alert_configs_api_alerts_configs_get.py index f09013c..69df1ae 100644 --- a/seclai/_generated/api/alerts/list_alert_configs_api_alerts_configs_get.py +++ b/seclai/_generated/api/alerts/list_alert_configs_api_alerts_configs_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.alert_config_list_response import AlertConfigListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -69,7 +70,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertConfigListResponse | HTTPValidationError | None: +) -> AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AlertConfigListResponse.from_dict(response.json()) @@ -80,6 +81,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -88,7 +94,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertConfigListResponse | HTTPValidationError]: +) -> Response[AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -107,7 +113,7 @@ def sync_detailed( limit: int | Unset = 50, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertConfigListResponse | HTTPValidationError]: +) -> Response[AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError]: """List alert configs List alert configurations. @@ -139,7 +145,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertConfigListResponse | HTTPValidationError] + Response[AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -169,7 +175,7 @@ def sync( limit: int | Unset = 50, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertConfigListResponse | HTTPValidationError | None: +) -> AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError | None: """List alert configs List alert configurations. @@ -201,7 +207,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertConfigListResponse | HTTPValidationError + AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -226,7 +232,7 @@ async def asyncio_detailed( limit: int | Unset = 50, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertConfigListResponse | HTTPValidationError]: +) -> Response[AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError]: """List alert configs List alert configurations. @@ -258,7 +264,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertConfigListResponse | HTTPValidationError] + Response[AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -286,7 +292,7 @@ async def asyncio( limit: int | Unset = 50, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertConfigListResponse | HTTPValidationError | None: +) -> AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError | None: """List alert configs List alert configurations. @@ -318,7 +324,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertConfigListResponse | HTTPValidationError + AlertConfigListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/list_alerts_api_alerts_get.py b/seclai/_generated/api/alerts/list_alerts_api_alerts_get.py index 915e3c9..86a1202 100644 --- a/seclai/_generated/api/alerts/list_alerts_api_alerts_get.py +++ b/seclai/_generated/api/alerts/list_alerts_api_alerts_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.alert_list_response import AlertListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -90,7 +91,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertListResponse | HTTPValidationError | None: +) -> AlertListResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AlertListResponse.from_dict(response.json()) @@ -101,6 +102,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -109,7 +115,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertListResponse | HTTPValidationError]: +) -> Response[AlertListResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -130,7 +136,7 @@ def sync_detailed( time_to: datetime.datetime | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertListResponse | HTTPValidationError]: +) -> Response[AlertListResponse | HTTPValidationError | ServiceUnavailableError]: """List alerts List alerts for the account with optional filters. @@ -160,7 +166,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertListResponse | HTTPValidationError] + Response[AlertListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -194,7 +200,7 @@ def sync( time_to: datetime.datetime | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertListResponse | HTTPValidationError | None: +) -> AlertListResponse | HTTPValidationError | ServiceUnavailableError | None: """List alerts List alerts for the account with optional filters. @@ -224,7 +230,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertListResponse | HTTPValidationError + AlertListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -253,7 +259,7 @@ async def asyncio_detailed( time_to: datetime.datetime | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertListResponse | HTTPValidationError]: +) -> Response[AlertListResponse | HTTPValidationError | ServiceUnavailableError]: """List alerts List alerts for the account with optional filters. @@ -283,7 +289,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertListResponse | HTTPValidationError] + Response[AlertListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -315,7 +321,7 @@ async def asyncio( time_to: datetime.datetime | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertListResponse | HTTPValidationError | None: +) -> AlertListResponse | HTTPValidationError | ServiceUnavailableError | None: """List alerts List alerts for the account with optional filters. @@ -345,7 +351,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertListResponse | HTTPValidationError + AlertListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/list_organization_preferences_api_alerts_organization_preferences_list_get.py b/seclai/_generated/api/alerts/list_organization_preferences_api_alerts_organization_preferences_list_get.py index 98cb70d..e08c2ca 100644 --- a/seclai/_generated/api/alerts/list_organization_preferences_api_alerts_organization_preferences_list_get.py +++ b/seclai/_generated/api/alerts/list_organization_preferences_api_alerts_organization_preferences_list_get.py @@ -10,6 +10,7 @@ from ...models.organization_alert_preference_list_response import ( OrganizationAlertPreferenceListResponse, ) +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -54,7 +55,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | OrganizationAlertPreferenceListResponse | None: +) -> ( + HTTPValidationError + | OrganizationAlertPreferenceListResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = OrganizationAlertPreferenceListResponse.from_dict( response.json() @@ -67,6 +73,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -75,7 +86,11 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | OrganizationAlertPreferenceListResponse]: +) -> Response[ + HTTPValidationError + | OrganizationAlertPreferenceListResponse + | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -91,7 +106,11 @@ def sync_detailed( include_defaults: bool | Unset = False, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OrganizationAlertPreferenceListResponse]: +) -> Response[ + HTTPValidationError + | OrganizationAlertPreferenceListResponse + | ServiceUnavailableError +]: """List organization alert delivery preferences List per-organization alert delivery preferences for the authenticated user. @@ -115,7 +134,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OrganizationAlertPreferenceListResponse] + Response[HTTPValidationError | OrganizationAlertPreferenceListResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -139,7 +158,12 @@ def sync( include_defaults: bool | Unset = False, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OrganizationAlertPreferenceListResponse | None: +) -> ( + HTTPValidationError + | OrganizationAlertPreferenceListResponse + | ServiceUnavailableError + | None +): """List organization alert delivery preferences List per-organization alert delivery preferences for the authenticated user. @@ -163,7 +187,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OrganizationAlertPreferenceListResponse + HTTPValidationError | OrganizationAlertPreferenceListResponse | ServiceUnavailableError """ return sync_detailed( @@ -182,7 +206,11 @@ async def asyncio_detailed( include_defaults: bool | Unset = False, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OrganizationAlertPreferenceListResponse]: +) -> Response[ + HTTPValidationError + | OrganizationAlertPreferenceListResponse + | ServiceUnavailableError +]: """List organization alert delivery preferences List per-organization alert delivery preferences for the authenticated user. @@ -206,7 +234,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OrganizationAlertPreferenceListResponse] + Response[HTTPValidationError | OrganizationAlertPreferenceListResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -228,7 +256,12 @@ async def asyncio( include_defaults: bool | Unset = False, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OrganizationAlertPreferenceListResponse | None: +) -> ( + HTTPValidationError + | OrganizationAlertPreferenceListResponse + | ServiceUnavailableError + | None +): """List organization alert delivery preferences List per-organization alert delivery preferences for the authenticated user. @@ -252,7 +285,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OrganizationAlertPreferenceListResponse + HTTPValidationError | OrganizationAlertPreferenceListResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/subscribe_to_alert_api_alerts_alert_id_subscribe_post.py b/seclai/_generated/api/alerts/subscribe_to_alert_api_alerts_alert_id_subscribe_post.py index cc78bcf..56c699b 100644 --- a/seclai/_generated/api/alerts/subscribe_to_alert_api_alerts_alert_id_subscribe_post.py +++ b/seclai/_generated/api/alerts/subscribe_to_alert_api_alerts_alert_id_subscribe_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.alert_detail_response import AlertDetailResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AlertDetailResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,11 +78,12 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Subscribe to alert Subscribe the current user to an alert. Subscribed users receive email notifications when the alert - status changes or new comments are added. + status changes or new comments are added, for as long as they remain an owner or administrator of + the account. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. @@ -91,7 +98,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -113,11 +120,12 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Subscribe to alert Subscribe the current user to an alert. Subscribed users receive email notifications when the alert - status changes or new comments are added. + status changes or new comments are added, for as long as they remain an owner or administrator of + the account. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. @@ -132,7 +140,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -149,11 +157,12 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Subscribe to alert Subscribe the current user to an alert. Subscribed users receive email notifications when the alert - status changes or new comments are added. + status changes or new comments are added, for as long as they remain an owner or administrator of + the account. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. @@ -168,7 +177,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -188,11 +197,12 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Subscribe to alert Subscribe the current user to an alert. Subscribed users receive email notifications when the alert - status changes or new comments are added. + status changes or new comments are added, for as long as they remain an owner or administrator of + the account. Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. @@ -207,7 +217,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/unsubscribe_from_alert_api_alerts_alert_id_unsubscribe_post.py b/seclai/_generated/api/alerts/unsubscribe_from_alert_api_alerts_alert_id_unsubscribe_post.py index b0e9646..d8ba34a 100644 --- a/seclai/_generated/api/alerts/unsubscribe_from_alert_api_alerts_alert_id_unsubscribe_post.py +++ b/seclai/_generated/api/alerts/unsubscribe_from_alert_api_alerts_alert_id_unsubscribe_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.alert_detail_response import AlertDetailResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AlertDetailResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Unsubscribe from alert Unsubscribe the current user from an alert. The user will no longer receive email notifications for @@ -91,7 +97,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -113,7 +119,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Unsubscribe from alert Unsubscribe the current user from an alert. The user will no longer receive email notifications for @@ -132,7 +138,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +155,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertDetailResponse | HTTPValidationError]: +) -> Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Unsubscribe from alert Unsubscribe the current user from an alert. The user will no longer receive email notifications for @@ -168,7 +174,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertDetailResponse | HTTPValidationError] + Response[AlertDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -188,7 +194,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertDetailResponse | HTTPValidationError | None: +) -> AlertDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Unsubscribe from alert Unsubscribe the current user from an alert. The user will no longer receive email notifications for @@ -207,7 +213,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertDetailResponse | HTTPValidationError + AlertDetailResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/update_alert_config_api_alerts_configs_config_id_patch.py b/seclai/_generated/api/alerts/update_alert_config_api_alerts_configs_config_id_patch.py index 77e9c45..ae218f8 100644 --- a/seclai/_generated/api/alerts/update_alert_config_api_alerts_configs_config_id_patch.py +++ b/seclai/_generated/api/alerts/update_alert_config_api_alerts_configs_config_id_patch.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.alert_config_response import AlertConfigResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.update_alert_config_request import UpdateAlertConfigRequest from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AlertConfigResponse | HTTPValidationError | None: +) -> AlertConfigResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AlertConfigResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AlertConfigResponse | HTTPValidationError]: +) -> Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: UpdateAlertConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertConfigResponse | HTTPValidationError]: +) -> Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError]: """Update alert config Update an alert configuration. Only provided fields are updated. @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertConfigResponse | HTTPValidationError] + Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -122,7 +128,7 @@ def sync( body: UpdateAlertConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertConfigResponse | HTTPValidationError | None: +) -> AlertConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Update alert config Update an alert configuration. Only provided fields are updated. @@ -141,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertConfigResponse | HTTPValidationError + AlertConfigResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -160,7 +166,7 @@ async def asyncio_detailed( body: UpdateAlertConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AlertConfigResponse | HTTPValidationError]: +) -> Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError]: """Update alert config Update an alert configuration. Only provided fields are updated. @@ -179,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AlertConfigResponse | HTTPValidationError] + Response[AlertConfigResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -201,7 +207,7 @@ async def asyncio( body: UpdateAlertConfigRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AlertConfigResponse | HTTPValidationError | None: +) -> AlertConfigResponse | HTTPValidationError | ServiceUnavailableError | None: """Update alert config Update an alert configuration. Only provided fields are updated. @@ -220,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AlertConfigResponse | HTTPValidationError + AlertConfigResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/alerts/update_organization_preference_api_alerts_organization_preferences_organization_id_alert_type_patch.py b/seclai/_generated/api/alerts/update_organization_preference_api_alerts_organization_preferences_organization_id_alert_type_patch.py index 05906ef..20c448d 100644 --- a/seclai/_generated/api/alerts/update_organization_preference_api_alerts_organization_preferences_organization_id_alert_type_patch.py +++ b/seclai/_generated/api/alerts/update_organization_preference_api_alerts_organization_preferences_organization_id_alert_type_patch.py @@ -11,6 +11,7 @@ from ...models.organization_alert_preference_response import ( OrganizationAlertPreferenceResponse, ) +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.update_organization_alert_preference_request import ( UpdateOrganizationAlertPreferenceRequest, ) @@ -50,7 +51,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | OrganizationAlertPreferenceResponse | None: +) -> ( + HTTPValidationError + | OrganizationAlertPreferenceResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = OrganizationAlertPreferenceResponse.from_dict(response.json()) @@ -61,6 +67,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -69,7 +80,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | OrganizationAlertPreferenceResponse]: +) -> Response[ + HTTPValidationError | OrganizationAlertPreferenceResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -86,7 +99,9 @@ def sync_detailed( body: UpdateOrganizationAlertPreferenceRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OrganizationAlertPreferenceResponse]: +) -> Response[ + HTTPValidationError | OrganizationAlertPreferenceResponse | ServiceUnavailableError +]: """Update organization alert delivery preference Update the authenticated user's personal delivery preference for one alert type in one organization. @@ -110,7 +125,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OrganizationAlertPreferenceResponse] + Response[HTTPValidationError | OrganizationAlertPreferenceResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -136,7 +151,12 @@ def sync( body: UpdateOrganizationAlertPreferenceRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OrganizationAlertPreferenceResponse | None: +) -> ( + HTTPValidationError + | OrganizationAlertPreferenceResponse + | ServiceUnavailableError + | None +): """Update organization alert delivery preference Update the authenticated user's personal delivery preference for one alert type in one organization. @@ -160,7 +180,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OrganizationAlertPreferenceResponse + HTTPValidationError | OrganizationAlertPreferenceResponse | ServiceUnavailableError """ return sync_detailed( @@ -181,7 +201,9 @@ async def asyncio_detailed( body: UpdateOrganizationAlertPreferenceRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OrganizationAlertPreferenceResponse]: +) -> Response[ + HTTPValidationError | OrganizationAlertPreferenceResponse | ServiceUnavailableError +]: """Update organization alert delivery preference Update the authenticated user's personal delivery preference for one alert type in one organization. @@ -205,7 +227,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OrganizationAlertPreferenceResponse] + Response[HTTPValidationError | OrganizationAlertPreferenceResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -229,7 +251,12 @@ async def asyncio( body: UpdateOrganizationAlertPreferenceRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OrganizationAlertPreferenceResponse | None: +) -> ( + HTTPValidationError + | OrganizationAlertPreferenceResponse + | ServiceUnavailableError + | None +): """Update organization alert delivery preference Update the authenticated user's personal delivery preference for one alert type in one organization. @@ -253,7 +280,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OrganizationAlertPreferenceResponse + HTTPValidationError | OrganizationAlertPreferenceResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/cloud_drives/__init__.py b/seclai/_generated/api/cloud_drives/__init__.py new file mode 100644 index 0000000..2d7c0b2 --- /dev/null +++ b/seclai/_generated/api/cloud_drives/__init__.py @@ -0,0 +1 @@ +"""Contains endpoint functions for accessing the API""" diff --git a/seclai/_generated/api/cloud_drives/delete_cloud_drive_api_api_cloud_drives_connection_id_delete.py b/seclai/_generated/api/cloud_drives/delete_cloud_drive_api_api_cloud_drives_connection_id_delete.py new file mode 100644 index 0000000..ae17d8b --- /dev/null +++ b/seclai/_generated/api/cloud_drives/delete_cloud_drive_api_api_cloud_drives_connection_id_delete.py @@ -0,0 +1,230 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.http_validation_error import HTTPValidationError +from ...models.ok_response import OkResponse +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + connection_id: UUID, + *, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + _kwargs: dict[str, Any] = { + "method": "delete", + "url": "/cloud-drives/{connection_id}".format( + connection_id=quote(str(connection_id), safe=""), + ), + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: + if response.status_code == 200: + response_200 = OkResponse.from_dict(response.json()) + + return response_200 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[HTTPValidationError | OkResponse | ServiceUnavailableError]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: + """Delete a cloud-drive connection + + Soft-delete a connection and clear its tokens. Refused with **409** while anything still depends on + it — a live agent trigger, or a `cloud_drive` content source ingesting into a knowledge base. `GET + /{connection_id}/agents` shows which agents reference it, but does NOT list content sources, so + treat the 409 as the authoritative check rather than a clean /agents response. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | OkResponse | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: + """Delete a cloud-drive connection + + Soft-delete a connection and clear its tokens. Refused with **409** while anything still depends on + it — a live agent trigger, or a `cloud_drive` content source ingesting into a knowledge base. `GET + /{connection_id}/agents` shows which agents reference it, but does NOT list content sources, so + treat the 409 as the authoritative check rather than a clean /agents response. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | OkResponse | ServiceUnavailableError + """ + + return sync_detailed( + connection_id=connection_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: + """Delete a cloud-drive connection + + Soft-delete a connection and clear its tokens. Refused with **409** while anything still depends on + it — a live agent trigger, or a `cloud_drive` content source ingesting into a knowledge base. `GET + /{connection_id}/agents` shows which agents reference it, but does NOT list content sources, so + treat the 409 as the authoritative check rather than a clean /agents response. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | OkResponse | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: + """Delete a cloud-drive connection + + Soft-delete a connection and clear its tokens. Refused with **409** while anything still depends on + it — a live agent trigger, or a `cloud_drive` content source ingesting into a knowledge base. `GET + /{connection_id}/agents` shows which agents reference it, but does NOT list content sources, so + treat the 409 as the authoritative check rather than a clean /agents response. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | OkResponse | ServiceUnavailableError + """ + + return ( + await asyncio_detailed( + connection_id=connection_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/cloud_drives/disconnect_cloud_drive_api_api_cloud_drives_connection_id_disconnect_post.py b/seclai/_generated/api/cloud_drives/disconnect_cloud_drive_api_api_cloud_drives_connection_id_disconnect_post.py new file mode 100644 index 0000000..47c3803 --- /dev/null +++ b/seclai/_generated/api/cloud_drives/disconnect_cloud_drive_api_api_cloud_drives_connection_id_disconnect_post.py @@ -0,0 +1,222 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.cloud_drive_response_model import CloudDriveResponseModel +from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + connection_id: UUID, + *, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + _kwargs: dict[str, Any] = { + "method": "post", + "url": "/cloud-drives/{connection_id}/disconnect".format( + connection_id=quote(str(connection_id), safe=""), + ), + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError | None: + if response.status_code == 200: + response_200 = CloudDriveResponseModel.from_dict(response.json()) + + return response_200 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError]: + """Disconnect a cloud-drive connection + + Revoke and clear the stored tokens and stop change notifications, keeping the connection row so it + can be reconnected from the app. Agents bound to it stop firing until it is reconnected. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError | None: + """Disconnect a cloud-drive connection + + Revoke and clear the stored tokens and stop change notifications, keeping the connection row so it + can be reconnected from the app. Agents bound to it stop firing until it is reconnected. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError + """ + + return sync_detailed( + connection_id=connection_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError]: + """Disconnect a cloud-drive connection + + Revoke and clear the stored tokens and stop change notifications, keeping the connection row so it + can be reconnected from the app. Agents bound to it stop firing until it is reconnected. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError | None: + """Disconnect a cloud-drive connection + + Revoke and clear the stored tokens and stop change notifications, keeping the connection row so it + can be reconnected from the app. Agents bound to it stop firing until it is reconnected. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError + """ + + return ( + await asyncio_detailed( + connection_id=connection_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/cloud_drives/get_agents_using_cloud_drive_api_api_cloud_drives_connection_id_agents_get.py b/seclai/_generated/api/cloud_drives/get_agents_using_cloud_drive_api_api_cloud_drives_connection_id_agents_get.py new file mode 100644 index 0000000..cb62e18 --- /dev/null +++ b/seclai/_generated/api/cloud_drives/get_agents_using_cloud_drive_api_api_cloud_drives_connection_id_agents_get.py @@ -0,0 +1,258 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.agent_using_cloud_drive_response_model import ( + AgentUsingCloudDriveResponseModel, +) +from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + connection_id: UUID, + *, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/cloud-drives/{connection_id}/agents".format( + connection_id=quote(str(connection_id), safe=""), + ), + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[AgentUsingCloudDriveResponseModel] + | None +): + if response.status_code == 200: + response_200 = [] + _response_200 = response.json() + for response_200_item_data in _response_200: + response_200_item = AgentUsingCloudDriveResponseModel.from_dict( + response_200_item_data + ) + + response_200.append(response_200_item) + + return response_200 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[ + HTTPValidationError + | ServiceUnavailableError + | list[AgentUsingCloudDriveResponseModel] +]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + HTTPValidationError + | ServiceUnavailableError + | list[AgentUsingCloudDriveResponseModel] +]: + """List agents using a cloud-drive connection + + Agents that reference this connection — via a cloud-drive step, a `prompt_call` cloud-drive tool, or + a file-change trigger. Check this before disconnecting or deleting a connection. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | ServiceUnavailableError | list[AgentUsingCloudDriveResponseModel]] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[AgentUsingCloudDriveResponseModel] + | None +): + """List agents using a cloud-drive connection + + Agents that reference this connection — via a cloud-drive step, a `prompt_call` cloud-drive tool, or + a file-change trigger. Check this before disconnecting or deleting a connection. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | ServiceUnavailableError | list[AgentUsingCloudDriveResponseModel] + """ + + return sync_detailed( + connection_id=connection_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + HTTPValidationError + | ServiceUnavailableError + | list[AgentUsingCloudDriveResponseModel] +]: + """List agents using a cloud-drive connection + + Agents that reference this connection — via a cloud-drive step, a `prompt_call` cloud-drive tool, or + a file-change trigger. Check this before disconnecting or deleting a connection. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | ServiceUnavailableError | list[AgentUsingCloudDriveResponseModel]] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[AgentUsingCloudDriveResponseModel] + | None +): + """List agents using a cloud-drive connection + + Agents that reference this connection — via a cloud-drive step, a `prompt_call` cloud-drive tool, or + a file-change trigger. Check this before disconnecting or deleting a connection. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | ServiceUnavailableError | list[AgentUsingCloudDriveResponseModel] + """ + + return ( + await asyncio_detailed( + connection_id=connection_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/cloud_drives/get_cloud_drive_api_api_cloud_drives_connection_id_get.py b/seclai/_generated/api/cloud_drives/get_cloud_drive_api_api_cloud_drives_connection_id_get.py new file mode 100644 index 0000000..653c337 --- /dev/null +++ b/seclai/_generated/api/cloud_drives/get_cloud_drive_api_api_cloud_drives_connection_id_get.py @@ -0,0 +1,218 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.cloud_drive_response_model import CloudDriveResponseModel +from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + connection_id: UUID, + *, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/cloud-drives/{connection_id}".format( + connection_id=quote(str(connection_id), safe=""), + ), + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError | None: + if response.status_code == 200: + response_200 = CloudDriveResponseModel.from_dict(response.json()) + + return response_200 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError]: + """Get a cloud-drive connection + + Fetch a single cloud-drive connection by id. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError | None: + """Get a cloud-drive connection + + Fetch a single cloud-drive connection by id. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError + """ + + return sync_detailed( + connection_id=connection_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError]: + """Get a cloud-drive connection + + Fetch a single cloud-drive connection by id. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError | None: + """Get a cloud-drive connection + + Fetch a single cloud-drive connection by id. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError + """ + + return ( + await asyncio_detailed( + connection_id=connection_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/cloud_drives/list_cloud_drive_providers_api_api_cloud_drives_providers_get.py b/seclai/_generated/api/cloud_drives/list_cloud_drive_providers_api_api_cloud_drives_providers_get.py new file mode 100644 index 0000000..40d7cc4 --- /dev/null +++ b/seclai/_generated/api/cloud_drives/list_cloud_drive_providers_api_api_cloud_drives_providers_get.py @@ -0,0 +1,213 @@ +from http import HTTPStatus +from typing import Any +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.cloud_drive_provider_response_model import ( + CloudDriveProviderResponseModel, +) +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/cloud-drives/providers", + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> ServiceUnavailableError | list[CloudDriveProviderResponseModel] | None: + if response.status_code == 200: + response_200 = [] + _response_200 = response.json() + for response_200_item_data in _response_200: + response_200_item = CloudDriveProviderResponseModel.from_dict( + response_200_item_data + ) + + response_200.append(response_200_item) + + return response_200 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[ServiceUnavailableError | list[CloudDriveProviderResponseModel]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ServiceUnavailableError | list[CloudDriveProviderResponseModel]]: + """List configured cloud-drive providers + + List the cloud-drive providers whose OAuth app is configured on this deployment (e.g. Dropbox, + Google Drive), with the permissions each requests. A provider missing from this list cannot be + connected here. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[ServiceUnavailableError | list[CloudDriveProviderResponseModel]] + """ + + kwargs = _get_kwargs( + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ServiceUnavailableError | list[CloudDriveProviderResponseModel] | None: + """List configured cloud-drive providers + + List the cloud-drive providers whose OAuth app is configured on this deployment (e.g. Dropbox, + Google Drive), with the permissions each requests. A provider missing from this list cannot be + connected here. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + ServiceUnavailableError | list[CloudDriveProviderResponseModel] + """ + + return sync_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ServiceUnavailableError | list[CloudDriveProviderResponseModel]]: + """List configured cloud-drive providers + + List the cloud-drive providers whose OAuth app is configured on this deployment (e.g. Dropbox, + Google Drive), with the permissions each requests. A provider missing from this list cannot be + connected here. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[ServiceUnavailableError | list[CloudDriveProviderResponseModel]] + """ + + kwargs = _get_kwargs( + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ServiceUnavailableError | list[CloudDriveProviderResponseModel] | None: + """List configured cloud-drive providers + + List the cloud-drive providers whose OAuth app is configured on this deployment (e.g. Dropbox, + Google Drive), with the permissions each requests. A provider missing from this list cannot be + connected here. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + ServiceUnavailableError | list[CloudDriveProviderResponseModel] + """ + + return ( + await asyncio_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/cloud_drives/list_cloud_drive_rejections_api_api_cloud_drives_connection_id_rejections_get.py b/seclai/_generated/api/cloud_drives/list_cloud_drive_rejections_api_api_cloud_drives_connection_id_rejections_get.py new file mode 100644 index 0000000..3394556 --- /dev/null +++ b/seclai/_generated/api/cloud_drives/list_cloud_drive_rejections_api_api_cloud_drives_connection_id_rejections_get.py @@ -0,0 +1,294 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.cloud_drive_rejection_response_model import ( + CloudDriveRejectionResponseModel, +) +from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + connection_id: UUID, + *, + limit: int | Unset = 50, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + params: dict[str, Any] = {} + + params["limit"] = limit + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/cloud-drives/{connection_id}/rejections".format( + connection_id=quote(str(connection_id), safe=""), + ), + "params": params, + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[CloudDriveRejectionResponseModel] + | None +): + if response.status_code == 200: + response_200 = [] + _response_200 = response.json() + for response_200_item_data in _response_200: + response_200_item = CloudDriveRejectionResponseModel.from_dict( + response_200_item_data + ) + + response_200.append(response_200_item) + + return response_200 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[ + HTTPValidationError + | ServiceUnavailableError + | list[CloudDriveRejectionResponseModel] +]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + limit: int | Unset = 50, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + HTTPValidationError + | ServiceUnavailableError + | list[CloudDriveRejectionResponseModel] +]: + r"""List files this connection did not process + + Recent files the connection deliberately skipped, newest first, with the reason: `too_large` (above + the size cap), `download_failed` (the provider would not serve the bytes), or `flood` (the per-sync + or per-account run cap was hit, so remaining changes were dropped). + + This is the answer to \"why didn't my agent run for that file?\" — a skipped file fires no trigger + and appears nowhere else. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + limit (int | Unset): Default: 50. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | ServiceUnavailableError | list[CloudDriveRejectionResponseModel]] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + limit=limit, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + limit: int | Unset = 50, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[CloudDriveRejectionResponseModel] + | None +): + r"""List files this connection did not process + + Recent files the connection deliberately skipped, newest first, with the reason: `too_large` (above + the size cap), `download_failed` (the provider would not serve the bytes), or `flood` (the per-sync + or per-account run cap was hit, so remaining changes were dropped). + + This is the answer to \"why didn't my agent run for that file?\" — a skipped file fires no trigger + and appears nowhere else. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + limit (int | Unset): Default: 50. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | ServiceUnavailableError | list[CloudDriveRejectionResponseModel] + """ + + return sync_detailed( + connection_id=connection_id, + client=client, + limit=limit, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + limit: int | Unset = 50, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + HTTPValidationError + | ServiceUnavailableError + | list[CloudDriveRejectionResponseModel] +]: + r"""List files this connection did not process + + Recent files the connection deliberately skipped, newest first, with the reason: `too_large` (above + the size cap), `download_failed` (the provider would not serve the bytes), or `flood` (the per-sync + or per-account run cap was hit, so remaining changes were dropped). + + This is the answer to \"why didn't my agent run for that file?\" — a skipped file fires no trigger + and appears nowhere else. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + limit (int | Unset): Default: 50. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | ServiceUnavailableError | list[CloudDriveRejectionResponseModel]] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + limit=limit, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + limit: int | Unset = 50, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[CloudDriveRejectionResponseModel] + | None +): + r"""List files this connection did not process + + Recent files the connection deliberately skipped, newest first, with the reason: `too_large` (above + the size cap), `download_failed` (the provider would not serve the bytes), or `flood` (the per-sync + or per-account run cap was hit, so remaining changes were dropped). + + This is the answer to \"why didn't my agent run for that file?\" — a skipped file fires no trigger + and appears nowhere else. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + limit (int | Unset): Default: 50. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | ServiceUnavailableError | list[CloudDriveRejectionResponseModel] + """ + + return ( + await asyncio_detailed( + connection_id=connection_id, + client=client, + limit=limit, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/cloud_drives/list_cloud_drives_api_api_cloud_drives_get.py b/seclai/_generated/api/cloud_drives/list_cloud_drives_api_api_cloud_drives_get.py new file mode 100644 index 0000000..7ec149f --- /dev/null +++ b/seclai/_generated/api/cloud_drives/list_cloud_drives_api_api_cloud_drives_get.py @@ -0,0 +1,211 @@ +from http import HTTPStatus +from typing import Any +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.cloud_drive_response_model import CloudDriveResponseModel +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/cloud-drives", + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> ServiceUnavailableError | list[CloudDriveResponseModel] | None: + if response.status_code == 200: + response_200 = [] + _response_200 = response.json() + for response_200_item_data in _response_200: + response_200_item = CloudDriveResponseModel.from_dict( + response_200_item_data + ) + + response_200.append(response_200_item) + + return response_200 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[ServiceUnavailableError | list[CloudDriveResponseModel]]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ServiceUnavailableError | list[CloudDriveResponseModel]]: + """List the account's cloud-drive connections + + List the account's cloud-drive connections. Use a connection's `id` as `cloud_drive_connection_id` + when creating a `cloud_drive` content source or binding a file-change agent trigger. + `realtime_updates` reports whether changes arrive within seconds or on the scheduled backstop sweep. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[ServiceUnavailableError | list[CloudDriveResponseModel]] + """ + + kwargs = _get_kwargs( + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ServiceUnavailableError | list[CloudDriveResponseModel] | None: + """List the account's cloud-drive connections + + List the account's cloud-drive connections. Use a connection's `id` as `cloud_drive_connection_id` + when creating a `cloud_drive` content source or binding a file-change agent trigger. + `realtime_updates` reports whether changes arrive within seconds or on the scheduled backstop sweep. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + ServiceUnavailableError | list[CloudDriveResponseModel] + """ + + return sync_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ServiceUnavailableError | list[CloudDriveResponseModel]]: + """List the account's cloud-drive connections + + List the account's cloud-drive connections. Use a connection's `id` as `cloud_drive_connection_id` + when creating a `cloud_drive` content source or binding a file-change agent trigger. + `realtime_updates` reports whether changes arrive within seconds or on the scheduled backstop sweep. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[ServiceUnavailableError | list[CloudDriveResponseModel]] + """ + + kwargs = _get_kwargs( + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ServiceUnavailableError | list[CloudDriveResponseModel] | None: + """List the account's cloud-drive connections + + List the account's cloud-drive connections. Use a connection's `id` as `cloud_drive_connection_id` + when creating a `cloud_drive` content source or binding a file-change agent trigger. + `realtime_updates` reports whether changes arrive within seconds or on the scheduled backstop sweep. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + ServiceUnavailableError | list[CloudDriveResponseModel] + """ + + return ( + await asyncio_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/cloud_drives/update_cloud_drive_api_api_cloud_drives_connection_id_patch.py b/seclai/_generated/api/cloud_drives/update_cloud_drive_api_api_cloud_drives_connection_id_patch.py new file mode 100644 index 0000000..990997a --- /dev/null +++ b/seclai/_generated/api/cloud_drives/update_cloud_drive_api_api_cloud_drives_connection_id_patch.py @@ -0,0 +1,240 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.cloud_drive_response_model import CloudDriveResponseModel +from ...models.cloud_drive_update_request import CloudDriveUpdateRequest +from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + connection_id: UUID, + *, + body: CloudDriveUpdateRequest, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + _kwargs: dict[str, Any] = { + "method": "patch", + "url": "/cloud-drives/{connection_id}".format( + connection_id=quote(str(connection_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 +) -> CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError | None: + if response.status_code == 200: + response_200 = CloudDriveResponseModel.from_dict(response.json()) + + return response_200 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + body: CloudDriveUpdateRequest, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError]: + """Update a cloud-drive connection + + Rename a connection and/or change the folder it watches. Changing the folder resets the sync cursor, + so existing files in the new folder are not replayed as triggers. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + body (CloudDriveUpdateRequest): + + 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[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + body=body, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + body: CloudDriveUpdateRequest, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError | None: + """Update a cloud-drive connection + + Rename a connection and/or change the folder it watches. Changing the folder resets the sync cursor, + so existing files in the new folder are not replayed as triggers. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + body (CloudDriveUpdateRequest): + + 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: + CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError + """ + + return sync_detailed( + connection_id=connection_id, + client=client, + body=body, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + body: CloudDriveUpdateRequest, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError]: + """Update a cloud-drive connection + + Rename a connection and/or change the folder it watches. Changing the folder resets the sync cursor, + so existing files in the new folder are not replayed as triggers. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + body (CloudDriveUpdateRequest): + + 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[CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + connection_id=connection_id, + body=body, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + connection_id: UUID, + *, + client: AuthenticatedClient | Client, + body: CloudDriveUpdateRequest, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError | None: + """Update a cloud-drive connection + + Rename a connection and/or change the folder it watches. Changing the folder resets the sync cursor, + so existing files in the new folder are not replayed as triggers. + + Requires an API key or OAuth token scoped to the account. Cloud-drive secrets are never returned. + + Args: + connection_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + body (CloudDriveUpdateRequest): + + 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: + CloudDriveResponseModel | HTTPValidationError | ServiceUnavailableError + """ + + return ( + await asyncio_detailed( + connection_id=connection_id, + client=client, + body=body, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/contents/delete_content_api_contents_source_connection_content_version_delete.py b/seclai/_generated/api/contents/delete_content_api_contents_source_connection_content_version_delete.py index d9d83fc..d1667a6 100644 --- a/seclai/_generated/api/contents/delete_content_api_contents_source_connection_content_version_delete.py +++ b/seclai/_generated/api/contents/delete_content_api_contents_source_connection_content_version_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -39,16 +40,25 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 + if response.status_code == 403: + response_403 = cast(Any, None) + return response_403 + if response.status_code == 422: response_422 = HTTPValidationError.from_dict(response.json()) return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +67,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +82,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete content Delete a content item (a `SourceConnectionContentVersion`). @@ -83,6 +93,8 @@ def sync_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. You can only delete content belonging to your account. + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. Args: source_connection_content_version (str): @@ -94,7 +106,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -116,7 +128,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete content Delete a content item (a `SourceConnectionContentVersion`). @@ -127,6 +139,8 @@ def sync( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. You can only delete content belonging to your account. + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. Args: source_connection_content_version (str): @@ -138,7 +152,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -155,7 +169,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete content Delete a content item (a `SourceConnectionContentVersion`). @@ -166,6 +180,8 @@ async def asyncio_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. You can only delete content belonging to your account. + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. Args: source_connection_content_version (str): @@ -177,7 +193,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -197,7 +213,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete content Delete a content item (a `SourceConnectionContentVersion`). @@ -208,6 +224,8 @@ async def asyncio( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. You can only delete content belonging to your account. + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. Args: source_connection_content_version (str): @@ -219,7 +237,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/contents/get_content_detail_api_contents_source_connection_content_version_get.py b/seclai/_generated/api/contents/get_content_detail_api_contents_source_connection_content_version_get.py index 77a085a..76ff684 100644 --- a/seclai/_generated/api/contents/get_content_detail_api_contents_source_connection_content_version_get.py +++ b/seclai/_generated/api/contents/get_content_detail_api_contents_source_connection_content_version_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.content_detail_response import ContentDetailResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -51,7 +52,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ContentDetailResponse | HTTPValidationError | None: +) -> ContentDetailResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ContentDetailResponse.from_dict(response.json()) @@ -62,6 +63,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -70,7 +76,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ContentDetailResponse | HTTPValidationError]: +) -> Response[ContentDetailResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -87,7 +93,7 @@ def sync_detailed( end: int | Unset = 5000, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ContentDetailResponse | HTTPValidationError]: +) -> Response[ContentDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Get content details Get detailed information about a specific content item (a `SourceConnectionContentVersion`). @@ -116,7 +122,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ContentDetailResponse | HTTPValidationError] + Response[ContentDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -142,7 +148,7 @@ def sync( end: int | Unset = 5000, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ContentDetailResponse | HTTPValidationError | None: +) -> ContentDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Get content details Get detailed information about a specific content item (a `SourceConnectionContentVersion`). @@ -171,7 +177,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ContentDetailResponse | HTTPValidationError + ContentDetailResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -192,7 +198,7 @@ async def asyncio_detailed( end: int | Unset = 5000, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ContentDetailResponse | HTTPValidationError]: +) -> Response[ContentDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Get content details Get detailed information about a specific content item (a `SourceConnectionContentVersion`). @@ -221,7 +227,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ContentDetailResponse | HTTPValidationError] + Response[ContentDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -245,7 +251,7 @@ async def asyncio( end: int | Unset = 5000, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ContentDetailResponse | HTTPValidationError | None: +) -> ContentDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Get content details Get detailed information about a specific content item (a `SourceConnectionContentVersion`). @@ -274,7 +280,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ContentDetailResponse | HTTPValidationError + ContentDetailResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/contents/list_content_embeddings_api_contents_source_connection_content_version_embeddings_get.py b/seclai/_generated/api/contents/list_content_embeddings_api_contents_source_connection_content_version_embeddings_get.py index 51993a1..fd50c36 100644 --- a/seclai/_generated/api/contents/list_content_embeddings_api_contents_source_connection_content_version_embeddings_get.py +++ b/seclai/_generated/api/contents/list_content_embeddings_api_contents_source_connection_content_version_embeddings_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.content_embeddings_list_response import ContentEmbeddingsListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -51,7 +52,9 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ContentEmbeddingsListResponse | HTTPValidationError | None: +) -> ( + ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError | None +): if response.status_code == 200: response_200 = ContentEmbeddingsListResponse.from_dict(response.json()) @@ -62,6 +65,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -70,7 +78,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ContentEmbeddingsListResponse | HTTPValidationError]: +) -> Response[ + ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -87,7 +97,9 @@ def sync_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ContentEmbeddingsListResponse | HTTPValidationError]: +) -> Response[ + ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError +]: """List content embeddings List the embeddings (chunk vectors) for a content item, with pagination. @@ -111,7 +123,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ContentEmbeddingsListResponse | HTTPValidationError] + Response[ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -137,7 +149,9 @@ def sync( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ContentEmbeddingsListResponse | HTTPValidationError | None: +) -> ( + ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError | None +): """List content embeddings List the embeddings (chunk vectors) for a content item, with pagination. @@ -161,7 +175,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ContentEmbeddingsListResponse | HTTPValidationError + ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -182,7 +196,9 @@ async def asyncio_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ContentEmbeddingsListResponse | HTTPValidationError]: +) -> Response[ + ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError +]: """List content embeddings List the embeddings (chunk vectors) for a content item, with pagination. @@ -206,7 +222,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ContentEmbeddingsListResponse | HTTPValidationError] + Response[ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -230,7 +246,9 @@ async def asyncio( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ContentEmbeddingsListResponse | HTTPValidationError | None: +) -> ( + ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError | None +): """List content embeddings List the embeddings (chunk vectors) for a content item, with pagination. @@ -254,7 +272,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ContentEmbeddingsListResponse | HTTPValidationError + ContentEmbeddingsListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/contents/replace_content_with_inline_text_api_contents_source_connection_content_version_put.py b/seclai/_generated/api/contents/replace_content_with_inline_text_api_contents_source_connection_content_version_put.py index 6ae15de..7bbcfb4 100644 --- a/seclai/_generated/api/contents/replace_content_with_inline_text_api_contents_source_connection_content_version_put.py +++ b/seclai/_generated/api/contents/replace_content_with_inline_text_api_contents_source_connection_content_version_put.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote from uuid import UUID @@ -10,6 +10,7 @@ from ...models.file_upload_response import FileUploadResponse from ...models.http_validation_error import HTTPValidationError from ...models.inline_text_replace_request import InlineTextReplaceRequest +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -46,17 +47,26 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> FileUploadResponse | HTTPValidationError | None: +) -> Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = FileUploadResponse.from_dict(response.json()) return response_200 + if response.status_code == 403: + response_403 = cast(Any, None) + return response_403 + if response.status_code == 422: response_422 = HTTPValidationError.from_dict(response.json()) return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +75,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[FileUploadResponse | HTTPValidationError]: +) -> Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -81,7 +91,7 @@ def sync_detailed( body: InlineTextReplaceRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[FileUploadResponse | HTTPValidationError]: +) -> Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError]: """Replace a content version with inline text Replace a content version using a small inline text payload. @@ -99,8 +109,13 @@ def sync_detailed( - `text/xml` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - Use this endpoint for small text payloads; larger files should use `/upload`. - `title` is merged into `metadata.title` when not already present. + - The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps + working, and reads return the previous content until indexing finishes; poll + `list_source_content_status` to follow it. The returned `content_version_id` is the new version. Args: source_connection_content_version (str): @@ -113,7 +128,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[FileUploadResponse | HTTPValidationError] + Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -137,7 +152,7 @@ def sync( body: InlineTextReplaceRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> FileUploadResponse | HTTPValidationError | None: +) -> Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError | None: """Replace a content version with inline text Replace a content version using a small inline text payload. @@ -155,8 +170,13 @@ def sync( - `text/xml` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - Use this endpoint for small text payloads; larger files should use `/upload`. - `title` is merged into `metadata.title` when not already present. + - The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps + working, and reads return the previous content until indexing finishes; poll + `list_source_content_status` to follow it. The returned `content_version_id` is the new version. Args: source_connection_content_version (str): @@ -169,7 +189,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - FileUploadResponse | HTTPValidationError + Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -188,7 +208,7 @@ async def asyncio_detailed( body: InlineTextReplaceRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[FileUploadResponse | HTTPValidationError]: +) -> Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError]: """Replace a content version with inline text Replace a content version using a small inline text payload. @@ -206,8 +226,13 @@ async def asyncio_detailed( - `text/xml` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - Use this endpoint for small text payloads; larger files should use `/upload`. - `title` is merged into `metadata.title` when not already present. + - The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps + working, and reads return the previous content until indexing finishes; poll + `list_source_content_status` to follow it. The returned `content_version_id` is the new version. Args: source_connection_content_version (str): @@ -220,7 +245,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[FileUploadResponse | HTTPValidationError] + Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -242,7 +267,7 @@ async def asyncio( body: InlineTextReplaceRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> FileUploadResponse | HTTPValidationError | None: +) -> Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError | None: """Replace a content version with inline text Replace a content version using a small inline text payload. @@ -260,8 +285,13 @@ async def asyncio( - `text/xml` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - Use this endpoint for small text payloads; larger files should use `/upload`. - `title` is merged into `metadata.title` when not already present. + - The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps + working, and reads return the previous content until indexing finishes; poll + `list_source_content_status` to follow it. The returned `content_version_id` is the new version. Args: source_connection_content_version (str): @@ -274,7 +304,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - FileUploadResponse | HTTPValidationError + Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/contents/upload_file_to_content_api_contents_source_connection_content_version_upload_post.py b/seclai/_generated/api/contents/upload_file_to_content_api_contents_source_connection_content_version_upload_post.py index b88a98c..cd8a7ef 100644 --- a/seclai/_generated/api/contents/upload_file_to_content_api_contents_source_connection_content_version_upload_post.py +++ b/seclai/_generated/api/contents/upload_file_to_content_api_contents_source_connection_content_version_upload_post.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote from uuid import UUID @@ -12,6 +12,7 @@ ) from ...models.file_upload_response import FileUploadResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -46,17 +47,26 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> FileUploadResponse | HTTPValidationError | None: +) -> Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = FileUploadResponse.from_dict(response.json()) return response_200 + if response.status_code == 403: + response_403 = cast(Any, None) + return response_403 + if response.status_code == 422: response_422 = HTTPValidationError.from_dict(response.json()) return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +75,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[FileUploadResponse | HTTPValidationError]: +) -> Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -81,7 +91,7 @@ def sync_detailed( body: BodyUploadFileToContentApiContentsSourceConnectionContentVersionUploadPost, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[FileUploadResponse | HTTPValidationError]: +) -> Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError]: r"""Replace a content version with a new upload Upload a new file and replace the content backing an existing `SourceConnectionContentVersion`. @@ -89,7 +99,8 @@ def sync_detailed( This behaves like a source file upload, but it targets an existing content version ID. This is useful when you want to correct or update an uploaded document while keeping references stable. - **Maximum file size:** 209715200 bytes. + **Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized + before it is stored). **Supported MIME types:** - `application/epub+zip` @@ -126,6 +137,11 @@ def sync_detailed( - `video/x-msvideo` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. + - The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps + working, and reads return the previous content until indexing finishes; poll + `list_source_content_status` to follow it. The returned `content_version_id` is the new version. - If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension. - Use `metadata` to attach an arbitrary JSON object of metadata (for example @@ -150,7 +166,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[FileUploadResponse | HTTPValidationError] + Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -174,7 +190,7 @@ def sync( body: BodyUploadFileToContentApiContentsSourceConnectionContentVersionUploadPost, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> FileUploadResponse | HTTPValidationError | None: +) -> Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError | None: r"""Replace a content version with a new upload Upload a new file and replace the content backing an existing `SourceConnectionContentVersion`. @@ -182,7 +198,8 @@ def sync( This behaves like a source file upload, but it targets an existing content version ID. This is useful when you want to correct or update an uploaded document while keeping references stable. - **Maximum file size:** 209715200 bytes. + **Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized + before it is stored). **Supported MIME types:** - `application/epub+zip` @@ -219,6 +236,11 @@ def sync( - `video/x-msvideo` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. + - The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps + working, and reads return the previous content until indexing finishes; poll + `list_source_content_status` to follow it. The returned `content_version_id` is the new version. - If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension. - Use `metadata` to attach an arbitrary JSON object of metadata (for example @@ -243,7 +265,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - FileUploadResponse | HTTPValidationError + Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -262,7 +284,7 @@ async def asyncio_detailed( body: BodyUploadFileToContentApiContentsSourceConnectionContentVersionUploadPost, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[FileUploadResponse | HTTPValidationError]: +) -> Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError]: r"""Replace a content version with a new upload Upload a new file and replace the content backing an existing `SourceConnectionContentVersion`. @@ -270,7 +292,8 @@ async def asyncio_detailed( This behaves like a source file upload, but it targets an existing content version ID. This is useful when you want to correct or update an uploaded document while keeping references stable. - **Maximum file size:** 209715200 bytes. + **Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized + before it is stored). **Supported MIME types:** - `application/epub+zip` @@ -307,6 +330,11 @@ async def asyncio_detailed( - `video/x-msvideo` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. + - The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps + working, and reads return the previous content until indexing finishes; poll + `list_source_content_status` to follow it. The returned `content_version_id` is the new version. - If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension. - Use `metadata` to attach an arbitrary JSON object of metadata (for example @@ -331,7 +359,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[FileUploadResponse | HTTPValidationError] + Response[Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -353,7 +381,7 @@ async def asyncio( body: BodyUploadFileToContentApiContentsSourceConnectionContentVersionUploadPost, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> FileUploadResponse | HTTPValidationError | None: +) -> Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError | None: r"""Replace a content version with a new upload Upload a new file and replace the content backing an existing `SourceConnectionContentVersion`. @@ -361,7 +389,8 @@ async def asyncio( This behaves like a source file upload, but it targets an existing content version ID. This is useful when you want to correct or update an uploaded document while keeping references stable. - **Maximum file size:** 209715200 bytes. + **Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized + before it is stored). **Supported MIME types:** - `application/epub+zip` @@ -398,6 +427,11 @@ async def asyncio( - `video/x-msvideo` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. + - The replacement is indexed in the background. This `SourceConnectionContentVersion` ID keeps + working, and reads return the previous content until indexing finishes; poll + `list_source_content_status` to follow it. The returned `content_version_id` is the new version. - If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension. - Use `metadata` to attach an arbitrary JSON object of metadata (for example @@ -422,7 +456,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - FileUploadResponse | HTTPValidationError + Any | FileUploadResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/email_domains/add_email_domain_api_api_email_domains_post.py b/seclai/_generated/api/email_domains/add_email_domain_api_api_email_domains_post.py index 8abdb0a..55e412d 100644 --- a/seclai/_generated/api/email_domains/add_email_domain_api_api_email_domains_post.py +++ b/seclai/_generated/api/email_domains/add_email_domain_api_api_email_domains_post.py @@ -9,6 +9,7 @@ from ...models.add_email_domain_request import AddEmailDomainRequest from ...models.email_domain_response import EmailDomainResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EmailDomainResponse | HTTPValidationError | None: +) -> EmailDomainResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = EmailDomainResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EmailDomainResponse | HTTPValidationError]: +) -> Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +80,7 @@ def sync_detailed( body: AddEmailDomainRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailDomainResponse | HTTPValidationError]: +) -> Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError]: """Add + provision an email domain Add a new vanity subdomain (`kind=vanity`, `value=`) or custom domain (`kind=custom`, @@ -95,7 +101,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailDomainResponse | HTTPValidationError] + Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -117,7 +123,7 @@ def sync( body: AddEmailDomainRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailDomainResponse | HTTPValidationError | None: +) -> EmailDomainResponse | HTTPValidationError | ServiceUnavailableError | None: """Add + provision an email domain Add a new vanity subdomain (`kind=vanity`, `value=`) or custom domain (`kind=custom`, @@ -138,7 +144,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailDomainResponse | HTTPValidationError + EmailDomainResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -155,7 +161,7 @@ async def asyncio_detailed( body: AddEmailDomainRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailDomainResponse | HTTPValidationError]: +) -> Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError]: """Add + provision an email domain Add a new vanity subdomain (`kind=vanity`, `value=`) or custom domain (`kind=custom`, @@ -176,7 +182,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailDomainResponse | HTTPValidationError] + Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -196,7 +202,7 @@ async def asyncio( body: AddEmailDomainRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailDomainResponse | HTTPValidationError | None: +) -> EmailDomainResponse | HTTPValidationError | ServiceUnavailableError | None: """Add + provision an email domain Add a new vanity subdomain (`kind=vanity`, `value=`) or custom domain (`kind=custom`, @@ -217,7 +223,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailDomainResponse | HTTPValidationError + EmailDomainResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/email_domains/get_dmarc_summary_api_api_email_domains_domain_id_dmarc_get.py b/seclai/_generated/api/email_domains/get_dmarc_summary_api_api_email_domains_domain_id_dmarc_get.py index d9a5537..10f6485 100644 --- a/seclai/_generated/api/email_domains/get_dmarc_summary_api_api_email_domains_domain_id_dmarc_get.py +++ b/seclai/_generated/api/email_domains/get_dmarc_summary_api_api_email_domains_domain_id_dmarc_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.dmarc_summary_response import DmarcSummaryResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -49,7 +50,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> DmarcSummaryResponse | HTTPValidationError | None: +) -> DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = DmarcSummaryResponse.from_dict(response.json()) @@ -60,6 +61,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -68,7 +74,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[DmarcSummaryResponse | HTTPValidationError]: +) -> Response[DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -85,7 +91,7 @@ def sync_detailed( top_sources: int | Unset = 10, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[DmarcSummaryResponse | HTTPValidationError]: +) -> Response[DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError]: """DMARC aggregate-report summary for a domain Pass rate, disposition breakdown (`none`/`quarantine`/`reject`), and top failing source IPs from the @@ -108,7 +114,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[DmarcSummaryResponse | HTTPValidationError] + Response[DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -134,7 +140,7 @@ def sync( top_sources: int | Unset = 10, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> DmarcSummaryResponse | HTTPValidationError | None: +) -> DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: """DMARC aggregate-report summary for a domain Pass rate, disposition breakdown (`none`/`quarantine`/`reject`), and top failing source IPs from the @@ -157,7 +163,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - DmarcSummaryResponse | HTTPValidationError + DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -178,7 +184,7 @@ async def asyncio_detailed( top_sources: int | Unset = 10, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[DmarcSummaryResponse | HTTPValidationError]: +) -> Response[DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError]: """DMARC aggregate-report summary for a domain Pass rate, disposition breakdown (`none`/`quarantine`/`reject`), and top failing source IPs from the @@ -201,7 +207,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[DmarcSummaryResponse | HTTPValidationError] + Response[DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -225,7 +231,7 @@ async def asyncio( top_sources: int | Unset = 10, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> DmarcSummaryResponse | HTTPValidationError | None: +) -> DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError | None: """DMARC aggregate-report summary for a domain Pass rate, disposition breakdown (`none`/`quarantine`/`reject`), and top failing source IPs from the @@ -248,7 +254,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - DmarcSummaryResponse | HTTPValidationError + DmarcSummaryResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/email_domains/list_email_domains_api_api_email_domains_get.py b/seclai/_generated/api/email_domains/list_email_domains_api_api_email_domains_get.py index 27ebc69..c596a43 100644 --- a/seclai/_generated/api/email_domains/list_email_domains_api_api_email_domains_get.py +++ b/seclai/_generated/api/email_domains/list_email_domains_api_api_email_domains_get.py @@ -7,6 +7,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.email_domains_list_response import EmailDomainsListResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -33,12 +34,17 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EmailDomainsListResponse | None: +) -> EmailDomainsListResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = EmailDomainsListResponse.from_dict(response.json()) return response_200 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -47,7 +53,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EmailDomainsListResponse]: +) -> Response[EmailDomainsListResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -61,7 +67,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailDomainsListResponse]: +) -> Response[EmailDomainsListResponse | ServiceUnavailableError]: """List the account's email domains + plan capabilities List the account's vanity (`.seclai.com`) and custom (`agent.mycompany.com`) agent-email @@ -81,7 +87,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailDomainsListResponse] + Response[EmailDomainsListResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -101,7 +107,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailDomainsListResponse | None: +) -> EmailDomainsListResponse | ServiceUnavailableError | None: """List the account's email domains + plan capabilities List the account's vanity (`.seclai.com`) and custom (`agent.mycompany.com`) agent-email @@ -121,7 +127,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailDomainsListResponse + EmailDomainsListResponse | ServiceUnavailableError """ return sync_detailed( @@ -136,7 +142,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailDomainsListResponse]: +) -> Response[EmailDomainsListResponse | ServiceUnavailableError]: """List the account's email domains + plan capabilities List the account's vanity (`.seclai.com`) and custom (`agent.mycompany.com`) agent-email @@ -156,7 +162,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailDomainsListResponse] + Response[EmailDomainsListResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -174,7 +180,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailDomainsListResponse | None: +) -> EmailDomainsListResponse | ServiceUnavailableError | None: """List the account's email domains + plan capabilities List the account's vanity (`.seclai.com`) and custom (`agent.mycompany.com`) agent-email @@ -194,7 +200,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailDomainsListResponse + EmailDomainsListResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/email_domains/remove_email_domain_api_api_email_domains_domain_id_delete.py b/seclai/_generated/api/email_domains/remove_email_domain_api_api_email_domains_domain_id_delete.py index 3e3254b..5c29eec 100644 --- a/seclai/_generated/api/email_domains/remove_email_domain_api_api_email_domains_domain_id_delete.py +++ b/seclai/_generated/api/email_domains/remove_email_domain_api_api_email_domains_domain_id_delete.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.remove_email_domain_response import RemoveEmailDomainResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | RemoveEmailDomainResponse | None: +) -> HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = RemoveEmailDomainResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | RemoveEmailDomainResponse]: +) -> Response[ + HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +80,9 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | RemoveEmailDomainResponse]: +) -> Response[ + HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError +]: """Remove an email domain Remove a domain and tear down its SES identity + DNS / receipt-rule recipient. Returns a @@ -93,7 +103,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | RemoveEmailDomainResponse] + Response[HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -115,7 +125,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | RemoveEmailDomainResponse | None: +) -> HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError | None: """Remove an email domain Remove a domain and tear down its SES identity + DNS / receipt-rule recipient. Returns a @@ -136,7 +146,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | RemoveEmailDomainResponse + HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError """ return sync_detailed( @@ -153,7 +163,9 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | RemoveEmailDomainResponse]: +) -> Response[ + HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError +]: """Remove an email domain Remove a domain and tear down its SES identity + DNS / receipt-rule recipient. Returns a @@ -174,7 +186,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | RemoveEmailDomainResponse] + Response[HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -194,7 +206,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | RemoveEmailDomainResponse | None: +) -> HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError | None: """Remove an email domain Remove a domain and tear down its SES identity + DNS / receipt-rule recipient. Returns a @@ -215,7 +227,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | RemoveEmailDomainResponse + HTTPValidationError | RemoveEmailDomainResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/email_domains/send_test_email_api_api_email_domains_domain_id_test_email_post.py b/seclai/_generated/api/email_domains/send_test_email_api_api_email_domains_domain_id_test_email_post.py index 9717401..8c0f350 100644 --- a/seclai/_generated/api/email_domains/send_test_email_api_api_email_domains_domain_id_test_email_post.py +++ b/seclai/_generated/api/email_domains/send_test_email_api_api_email_domains_domain_id_test_email_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.send_test_email_response import SendTestEmailResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SendTestEmailResponse | None: +) -> HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = SendTestEmailResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SendTestEmailResponse]: +) -> Response[HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SendTestEmailResponse]: +) -> Response[HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError]: """Send a test email from a verified domain to the account owner Send a test message FROM the verified domain (`noreply@`) TO the account owner's email, to @@ -92,7 +98,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SendTestEmailResponse] + Response[HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +120,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SendTestEmailResponse | None: +) -> HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError | None: """Send a test email from a verified domain to the account owner Send a test message FROM the verified domain (`noreply@`) TO the account owner's email, to @@ -134,7 +140,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SendTestEmailResponse + HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError """ return sync_detailed( @@ -151,7 +157,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SendTestEmailResponse]: +) -> Response[HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError]: """Send a test email from a verified domain to the account owner Send a test message FROM the verified domain (`noreply@`) TO the account owner's email, to @@ -171,7 +177,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SendTestEmailResponse] + Response[HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -191,7 +197,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SendTestEmailResponse | None: +) -> HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError | None: """Send a test email from a verified domain to the account owner Send a test message FROM the verified domain (`noreply@`) TO the account owner's email, to @@ -211,7 +217,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SendTestEmailResponse + HTTPValidationError | SendTestEmailResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/email_domains/set_primary_email_domain_api_api_email_domains_domain_id_primary_post.py b/seclai/_generated/api/email_domains/set_primary_email_domain_api_api_email_domains_domain_id_primary_post.py index 46b83f8..51deb6e 100644 --- a/seclai/_generated/api/email_domains/set_primary_email_domain_api_api_email_domains_domain_id_primary_post.py +++ b/seclai/_generated/api/email_domains/set_primary_email_domain_api_api_email_domains_domain_id_primary_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.email_domain_response import EmailDomainResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EmailDomainResponse | HTTPValidationError | None: +) -> EmailDomainResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = EmailDomainResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EmailDomainResponse | HTTPValidationError]: +) -> Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,12 +78,13 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailDomainResponse | HTTPValidationError]: - """Make a verified domain the account's primary sending/inbound domain +) -> Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError]: + """Make a verified domain the account's primary sending domain - Promote a verified domain to the account's primary domain — agent email then sends FROM and receives - ON this domain (`@`, `@`) instead of the shared `agent.seclai.com`. - The domain must be verified. Owner/admin only. + Promote a verified domain to the account's primary domain — agent email then sends FROM this domain + and shows its addresses on it (`@`, `@`) instead of the shared + `agent.seclai.com`; addresses keep resolving on the account's other verified domains and the shared + form. The domain must be verified. Owner/admin only. Auth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account. @@ -92,7 +99,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailDomainResponse | HTTPValidationError] + Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,12 +121,13 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailDomainResponse | HTTPValidationError | None: - """Make a verified domain the account's primary sending/inbound domain +) -> EmailDomainResponse | HTTPValidationError | ServiceUnavailableError | None: + """Make a verified domain the account's primary sending domain - Promote a verified domain to the account's primary domain — agent email then sends FROM and receives - ON this domain (`@`, `@`) instead of the shared `agent.seclai.com`. - The domain must be verified. Owner/admin only. + Promote a verified domain to the account's primary domain — agent email then sends FROM this domain + and shows its addresses on it (`@`, `@`) instead of the shared + `agent.seclai.com`; addresses keep resolving on the account's other verified domains and the shared + form. The domain must be verified. Owner/admin only. Auth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account. @@ -134,7 +142,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailDomainResponse | HTTPValidationError + EmailDomainResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -151,12 +159,13 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailDomainResponse | HTTPValidationError]: - """Make a verified domain the account's primary sending/inbound domain +) -> Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError]: + """Make a verified domain the account's primary sending domain - Promote a verified domain to the account's primary domain — agent email then sends FROM and receives - ON this domain (`@`, `@`) instead of the shared `agent.seclai.com`. - The domain must be verified. Owner/admin only. + Promote a verified domain to the account's primary domain — agent email then sends FROM this domain + and shows its addresses on it (`@`, `@`) instead of the shared + `agent.seclai.com`; addresses keep resolving on the account's other verified domains and the shared + form. The domain must be verified. Owner/admin only. Auth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account. @@ -171,7 +180,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailDomainResponse | HTTPValidationError] + Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -191,12 +200,13 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailDomainResponse | HTTPValidationError | None: - """Make a verified domain the account's primary sending/inbound domain +) -> EmailDomainResponse | HTTPValidationError | ServiceUnavailableError | None: + """Make a verified domain the account's primary sending domain - Promote a verified domain to the account's primary domain — agent email then sends FROM and receives - ON this domain (`@`, `@`) instead of the shared `agent.seclai.com`. - The domain must be verified. Owner/admin only. + Promote a verified domain to the account's primary domain — agent email then sends FROM this domain + and shows its addresses on it (`@`, `@`) instead of the shared + `agent.seclai.com`; addresses keep resolving on the account's other verified domains and the shared + form. The domain must be verified. Owner/admin only. Auth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account. @@ -211,7 +221,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailDomainResponse | HTTPValidationError + EmailDomainResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/email_domains/use_shared_domain_api_api_email_domains_use_shared_domain_post.py b/seclai/_generated/api/email_domains/use_shared_domain_api_api_email_domains_use_shared_domain_post.py index 8de81c5..9a64d80 100644 --- a/seclai/_generated/api/email_domains/use_shared_domain_api_api_email_domains_use_shared_domain_post.py +++ b/seclai/_generated/api/email_domains/use_shared_domain_api_api_email_domains_use_shared_domain_post.py @@ -1,11 +1,12 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from uuid import UUID import httpx from ... import errors from ...client import AuthenticatedClient, Client +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -32,9 +33,15 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | None: +) -> Any | ServiceUnavailableError | None: if response.status_code == 204: - return None + response_204 = cast(Any, None) + return response_204 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) @@ -44,7 +51,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any]: +) -> Response[Any | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -58,12 +65,12 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any]: +) -> Response[Any | ServiceUnavailableError]: """Revert to the shared agent.seclai.com sending domain - Clear the account's primary domain so agent email reverts to the shared `agent.seclai.com` - sending/inbound scheme, WITHOUT removing the configured domain(s) — they stay verified and can be - promoted again later. Owner/admin only. + Clear the account's primary domain so agent email reverts to the shared `agent.seclai.com` sending + domain, WITHOUT removing the configured domain(s) — they stay verified and can be promoted again + later. Owner/admin only. Auth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account. @@ -77,7 +84,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[Any | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -92,17 +99,51 @@ def sync_detailed( return _build_response(client=client, response=response) +def sync( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Any | ServiceUnavailableError | None: + """Revert to the shared agent.seclai.com sending domain + + Clear the account's primary domain so agent email reverts to the shared `agent.seclai.com` sending + domain, WITHOUT removing the configured domain(s) — they stay verified and can be promoted again + later. Owner/admin only. + + Auth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an + account-only key is refused with 403); the domain is scoped to the key's account. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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 | ServiceUnavailableError + """ + + return sync_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + async def asyncio_detailed( *, client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any]: +) -> Response[Any | ServiceUnavailableError]: """Revert to the shared agent.seclai.com sending domain - Clear the account's primary domain so agent email reverts to the shared `agent.seclai.com` - sending/inbound scheme, WITHOUT removing the configured domain(s) — they stay verified and can be - promoted again later. Owner/admin only. + Clear the account's primary domain so agent email reverts to the shared `agent.seclai.com` sending + domain, WITHOUT removing the configured domain(s) — they stay verified and can be promoted again + later. Owner/admin only. Auth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an account-only key is refused with 403); the domain is scoped to the key's account. @@ -116,7 +157,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[Any | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -127,3 +168,39 @@ async def asyncio_detailed( response = await client.get_async_httpx_client().request(**kwargs) return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Any | ServiceUnavailableError | None: + """Revert to the shared agent.seclai.com sending domain + + Clear the account's primary domain so agent email reverts to the shared `agent.seclai.com` sending + domain, WITHOUT removing the configured domain(s) — they stay verified and can be promoted again + later. Owner/admin only. + + Auth & scoping: requires an `X-API-Key` header or OAuth Bearer token bound to a **user** (an + account-only key is refused with 403); the domain is scoped to the key's account. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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 | ServiceUnavailableError + """ + + return ( + await asyncio_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/email_domains/verify_email_domain_api_api_email_domains_domain_id_verify_post.py b/seclai/_generated/api/email_domains/verify_email_domain_api_api_email_domains_domain_id_verify_post.py index 64d112c..642e897 100644 --- a/seclai/_generated/api/email_domains/verify_email_domain_api_api_email_domains_domain_id_verify_post.py +++ b/seclai/_generated/api/email_domains/verify_email_domain_api_api_email_domains_domain_id_verify_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.email_domain_response import EmailDomainResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EmailDomainResponse | HTTPValidationError | None: +) -> EmailDomainResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = EmailDomainResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EmailDomainResponse | HTTPValidationError]: +) -> Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailDomainResponse | HTTPValidationError]: +) -> Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError]: """Run a verification check immediately ('Check now') Re-poll SES + DNS for this domain right now instead of waiting for the background verification @@ -92,7 +98,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailDomainResponse | HTTPValidationError] + Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +120,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailDomainResponse | HTTPValidationError | None: +) -> EmailDomainResponse | HTTPValidationError | ServiceUnavailableError | None: """Run a verification check immediately ('Check now') Re-poll SES + DNS for this domain right now instead of waiting for the background verification @@ -134,7 +140,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailDomainResponse | HTTPValidationError + EmailDomainResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -151,7 +157,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EmailDomainResponse | HTTPValidationError]: +) -> Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError]: """Run a verification check immediately ('Check now') Re-poll SES + DNS for this domain right now instead of waiting for the background verification @@ -171,7 +177,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EmailDomainResponse | HTTPValidationError] + Response[EmailDomainResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -191,7 +197,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EmailDomainResponse | HTTPValidationError | None: +) -> EmailDomainResponse | HTTPValidationError | ServiceUnavailableError | None: """Run a verification check immediately ('Check now') Re-poll SES + DNS for this domain right now instead of waiting for the background verification @@ -211,7 +217,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EmailDomainResponse | HTTPValidationError + EmailDomainResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/governance/governance_ai_accept_api_governance_ai_assistant_conversation_id_accept_post.py b/seclai/_generated/api/governance/governance_ai_accept_api_governance_ai_assistant_conversation_id_accept_post.py index ea9ef49..3ad3028 100644 --- a/seclai/_generated/api/governance/governance_ai_accept_api_governance_ai_assistant_conversation_id_accept_post.py +++ b/seclai/_generated/api/governance/governance_ai_accept_api_governance_ai_assistant_conversation_id_accept_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.governance_ai_accept_response import GovernanceAiAcceptResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,13 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | GovernanceAiAcceptResponse | HTTPValidationError | None: +) -> ( + Any + | GovernanceAiAcceptResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = GovernanceAiAcceptResponse.from_dict(response.json()) @@ -57,6 +64,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +77,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | GovernanceAiAcceptResponse | HTTPValidationError]: +) -> Response[ + Any | GovernanceAiAcceptResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -80,7 +94,9 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | GovernanceAiAcceptResponse | HTTPValidationError]: +) -> Response[ + Any | GovernanceAiAcceptResponse | HTTPValidationError | ServiceUnavailableError +]: """Accept a governance plan Execute the proposed policy changes from a governance AI assistant conversation. Each action is @@ -98,7 +114,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | GovernanceAiAcceptResponse | HTTPValidationError] + Response[Any | GovernanceAiAcceptResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -120,7 +136,13 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | GovernanceAiAcceptResponse | HTTPValidationError | None: +) -> ( + Any + | GovernanceAiAcceptResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Accept a governance plan Execute the proposed policy changes from a governance AI assistant conversation. Each action is @@ -138,7 +160,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | GovernanceAiAcceptResponse | HTTPValidationError + Any | GovernanceAiAcceptResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -155,7 +177,9 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | GovernanceAiAcceptResponse | HTTPValidationError]: +) -> Response[ + Any | GovernanceAiAcceptResponse | HTTPValidationError | ServiceUnavailableError +]: """Accept a governance plan Execute the proposed policy changes from a governance AI assistant conversation. Each action is @@ -173,7 +197,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | GovernanceAiAcceptResponse | HTTPValidationError] + Response[Any | GovernanceAiAcceptResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -193,7 +217,13 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | GovernanceAiAcceptResponse | HTTPValidationError | None: +) -> ( + Any + | GovernanceAiAcceptResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Accept a governance plan Execute the proposed policy changes from a governance AI assistant conversation. Each action is @@ -211,7 +241,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | GovernanceAiAcceptResponse | HTTPValidationError + Any | GovernanceAiAcceptResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/governance/governance_ai_decline_api_governance_ai_assistant_conversation_id_decline_post.py b/seclai/_generated/api/governance/governance_ai_decline_api_governance_ai_assistant_conversation_id_decline_post.py index 9252846..46b8cea 100644 --- a/seclai/_generated/api/governance/governance_ai_decline_api_governance_ai_assistant_conversation_id_decline_post.py +++ b/seclai/_generated/api/governance/governance_ai_decline_api_governance_ai_assistant_conversation_id_decline_post.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -78,7 +84,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Decline a governance plan Reject a previously proposed governance AI assistant plan without applying any changes. The @@ -96,7 +102,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -118,7 +124,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Decline a governance plan Reject a previously proposed governance AI assistant plan without applying any changes. The @@ -136,7 +142,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -153,7 +159,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Decline a governance plan Reject a previously proposed governance AI assistant plan without applying any changes. The @@ -171,7 +177,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -191,7 +197,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Decline a governance plan Reject a previously proposed governance AI assistant plan without applying any changes. The @@ -209,7 +215,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/governance/governance_ai_generate_api_governance_ai_assistant_post.py b/seclai/_generated/api/governance/governance_ai_generate_api_governance_ai_assistant_post.py index f13cda2..7c7c0e4 100644 --- a/seclai/_generated/api/governance/governance_ai_generate_api_governance_ai_assistant_post.py +++ b/seclai/_generated/api/governance/governance_ai_generate_api_governance_ai_assistant_post.py @@ -9,6 +9,7 @@ from ...models.governance_ai_assistant_request import GovernanceAiAssistantRequest from ...models.governance_ai_assistant_response import GovernanceAiAssistantResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,13 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | GovernanceAiAssistantResponse | HTTPValidationError | None: +) -> ( + Any + | GovernanceAiAssistantResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = GovernanceAiAssistantResponse.from_dict(response.json()) @@ -59,6 +66,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -67,7 +79,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | GovernanceAiAssistantResponse | HTTPValidationError]: +) -> Response[ + Any | GovernanceAiAssistantResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -82,7 +96,9 @@ def sync_detailed( body: GovernanceAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | GovernanceAiAssistantResponse | HTTPValidationError]: +) -> Response[ + Any | GovernanceAiAssistantResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate a governance plan Send a natural-language request to the governance AI assistant to generate a plan of policy changes. @@ -100,7 +116,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | GovernanceAiAssistantResponse | HTTPValidationError] + Response[Any | GovernanceAiAssistantResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -122,7 +138,13 @@ def sync( body: GovernanceAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | GovernanceAiAssistantResponse | HTTPValidationError | None: +) -> ( + Any + | GovernanceAiAssistantResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Generate a governance plan Send a natural-language request to the governance AI assistant to generate a plan of policy changes. @@ -140,7 +162,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | GovernanceAiAssistantResponse | HTTPValidationError + Any | GovernanceAiAssistantResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -157,7 +179,9 @@ async def asyncio_detailed( body: GovernanceAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | GovernanceAiAssistantResponse | HTTPValidationError]: +) -> Response[ + Any | GovernanceAiAssistantResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate a governance plan Send a natural-language request to the governance AI assistant to generate a plan of policy changes. @@ -175,7 +199,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | GovernanceAiAssistantResponse | HTTPValidationError] + Response[Any | GovernanceAiAssistantResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -195,7 +219,13 @@ async def asyncio( body: GovernanceAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | GovernanceAiAssistantResponse | HTTPValidationError | None: +) -> ( + Any + | GovernanceAiAssistantResponse + | HTTPValidationError + | ServiceUnavailableError + | None +): """Generate a governance plan Send a natural-language request to the governance AI assistant to generate a plan of policy changes. @@ -213,7 +243,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | GovernanceAiAssistantResponse | HTTPValidationError + Any | GovernanceAiAssistantResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/governance/list_governance_ai_conversations_api_governance_ai_assistant_conversations_get.py b/seclai/_generated/api/governance/list_governance_ai_conversations_api_governance_ai_assistant_conversations_get.py index d6cc9f0..9a715b8 100644 --- a/seclai/_generated/api/governance/list_governance_ai_conversations_api_governance_ai_assistant_conversations_get.py +++ b/seclai/_generated/api/governance/list_governance_ai_conversations_api_governance_ai_assistant_conversations_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.governance_conversation_response import GovernanceConversationResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -42,7 +43,13 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | list[GovernanceConversationResponse] | None: +) -> ( + Any + | HTTPValidationError + | ServiceUnavailableError + | list[GovernanceConversationResponse] + | None +): if response.status_code == 200: response_200 = [] _response_200 = response.json() @@ -64,6 +71,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -72,7 +84,12 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError | list[GovernanceConversationResponse]]: +) -> Response[ + Any + | HTTPValidationError + | ServiceUnavailableError + | list[GovernanceConversationResponse] +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -87,7 +104,12 @@ def sync_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | list[GovernanceConversationResponse]]: +) -> Response[ + Any + | HTTPValidationError + | ServiceUnavailableError + | list[GovernanceConversationResponse] +]: """List AI assistant conversations Return recent governance AI assistant conversations for the account, ordered by most recent first. @@ -104,7 +126,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | list[GovernanceConversationResponse]] + Response[Any | HTTPValidationError | ServiceUnavailableError | list[GovernanceConversationResponse]] """ kwargs = _get_kwargs( @@ -126,7 +148,13 @@ def sync( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | list[GovernanceConversationResponse] | None: +) -> ( + Any + | HTTPValidationError + | ServiceUnavailableError + | list[GovernanceConversationResponse] + | None +): """List AI assistant conversations Return recent governance AI assistant conversations for the account, ordered by most recent first. @@ -143,7 +171,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | list[GovernanceConversationResponse] + Any | HTTPValidationError | ServiceUnavailableError | list[GovernanceConversationResponse] """ return sync_detailed( @@ -160,7 +188,12 @@ async def asyncio_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | list[GovernanceConversationResponse]]: +) -> Response[ + Any + | HTTPValidationError + | ServiceUnavailableError + | list[GovernanceConversationResponse] +]: """List AI assistant conversations Return recent governance AI assistant conversations for the account, ordered by most recent first. @@ -177,7 +210,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | list[GovernanceConversationResponse]] + Response[Any | HTTPValidationError | ServiceUnavailableError | list[GovernanceConversationResponse]] """ kwargs = _get_kwargs( @@ -197,7 +230,13 @@ async def asyncio( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | list[GovernanceConversationResponse] | None: +) -> ( + Any + | HTTPValidationError + | ServiceUnavailableError + | list[GovernanceConversationResponse] + | None +): """List AI assistant conversations Return recent governance AI assistant conversations for the account, ordered by most recent first. @@ -214,7 +253,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | list[GovernanceConversationResponse] + Any | HTTPValidationError | ServiceUnavailableError | list[GovernanceConversationResponse] """ return ( diff --git a/seclai/_generated/api/identity/get_me_api_me_get.py b/seclai/_generated/api/identity/get_me_api_me_get.py index 89f9a28..059de06 100644 --- a/seclai/_generated/api/identity/get_me_api_me_get.py +++ b/seclai/_generated/api/identity/get_me_api_me_get.py @@ -7,6 +7,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.me_response import MeResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -33,12 +34,17 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> MeResponse | None: +) -> MeResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = MeResponse.from_dict(response.json()) return response_200 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -47,7 +53,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[MeResponse]: +) -> Response[MeResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -61,7 +67,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[MeResponse]: +) -> Response[MeResponse | ServiceUnavailableError]: """Get current user identity Returns the authenticated user's personal account ID and a list of organisations they belong to. @@ -77,7 +83,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[MeResponse] + Response[MeResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -97,7 +103,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> MeResponse | None: +) -> MeResponse | ServiceUnavailableError | None: """Get current user identity Returns the authenticated user's personal account ID and a list of organisations they belong to. @@ -113,7 +119,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - MeResponse + MeResponse | ServiceUnavailableError """ return sync_detailed( @@ -128,7 +134,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[MeResponse]: +) -> Response[MeResponse | ServiceUnavailableError]: """Get current user identity Returns the authenticated user's personal account ID and a list of organisations they belong to. @@ -144,7 +150,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[MeResponse] + Response[MeResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -162,7 +168,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> MeResponse | None: +) -> MeResponse | ServiceUnavailableError | None: """Get current user identity Returns the authenticated user's personal account ID and a list of organisations they belong to. @@ -178,7 +184,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - MeResponse + MeResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/knowledge_bases/create_knowledge_base_api_knowledge_bases_post.py b/seclai/_generated/api/knowledge_bases/create_knowledge_base_api_knowledge_bases_post.py index 0550f97..75fdb05 100644 --- a/seclai/_generated/api/knowledge_bases/create_knowledge_base_api_knowledge_bases_post.py +++ b/seclai/_generated/api/knowledge_bases/create_knowledge_base_api_knowledge_bases_post.py @@ -9,6 +9,7 @@ from ...models.create_knowledge_base_body import CreateKnowledgeBaseBody from ...models.http_validation_error import HTTPValidationError from ...models.knowledge_base import KnowledgeBase +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | KnowledgeBase | None: +) -> Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError | None: if response.status_code == 201: response_201 = KnowledgeBase.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError | KnowledgeBase]: +) -> Response[Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -78,7 +84,7 @@ def sync_detailed( body: CreateKnowledgeBaseBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | KnowledgeBase]: +) -> Response[Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError]: """Create Knowledge Base Create a new knowledge base. @@ -95,7 +101,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | KnowledgeBase] + Response[Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -117,7 +123,7 @@ def sync( body: CreateKnowledgeBaseBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | KnowledgeBase | None: +) -> Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError | None: """Create Knowledge Base Create a new knowledge base. @@ -134,7 +140,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | KnowledgeBase + Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError """ return sync_detailed( @@ -151,7 +157,7 @@ async def asyncio_detailed( body: CreateKnowledgeBaseBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | KnowledgeBase]: +) -> Response[Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError]: """Create Knowledge Base Create a new knowledge base. @@ -168,7 +174,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | KnowledgeBase] + Response[Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -188,7 +194,7 @@ async def asyncio( body: CreateKnowledgeBaseBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | KnowledgeBase | None: +) -> Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError | None: """Create Knowledge Base Create a new knowledge base. @@ -205,7 +211,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | KnowledgeBase + Any | HTTPValidationError | KnowledgeBase | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/knowledge_bases/delete_knowledge_base_api_knowledge_bases_knowledge_base_id_delete.py b/seclai/_generated/api/knowledge_bases/delete_knowledge_base_api_knowledge_bases_knowledge_base_id_delete.py index 911e5e4..cad6484 100644 --- a/seclai/_generated/api/knowledge_bases/delete_knowledge_base_api_knowledge_bases_knowledge_base_id_delete.py +++ b/seclai/_generated/api/knowledge_bases/delete_knowledge_base_api_knowledge_bases_knowledge_base_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Knowledge Base Soft-delete a knowledge base. This action cannot be undone. @@ -88,7 +94,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -110,7 +116,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Knowledge Base Soft-delete a knowledge base. This action cannot be undone. @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Knowledge Base Soft-delete a knowledge base. This action cannot be undone. @@ -163,7 +169,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Knowledge Base Soft-delete a knowledge base. This action cannot be undone. @@ -201,7 +207,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/knowledge_bases/get_knowledge_base_api_knowledge_bases_knowledge_base_id_get.py b/seclai/_generated/api/knowledge_bases/get_knowledge_base_api_knowledge_bases_knowledge_base_id_get.py index eb5c7c6..6b89248 100644 --- a/seclai/_generated/api/knowledge_bases/get_knowledge_base_api_knowledge_bases_knowledge_base_id_get.py +++ b/seclai/_generated/api/knowledge_bases/get_knowledge_base_api_knowledge_bases_knowledge_base_id_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.knowledge_base import KnowledgeBase +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | KnowledgeBase | None: +) -> HTTPValidationError | KnowledgeBase | ServiceUnavailableError | None: if response.status_code == 200: response_200 = KnowledgeBase.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | KnowledgeBase]: +) -> Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | KnowledgeBase]: +) -> Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError]: """Get Knowledge Base Fetch a knowledge base by ID. @@ -91,7 +97,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | KnowledgeBase] + Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -113,7 +119,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | KnowledgeBase | None: +) -> HTTPValidationError | KnowledgeBase | ServiceUnavailableError | None: """Get Knowledge Base Fetch a knowledge base by ID. @@ -132,7 +138,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | KnowledgeBase + HTTPValidationError | KnowledgeBase | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +155,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | KnowledgeBase]: +) -> Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError]: """Get Knowledge Base Fetch a knowledge base by ID. @@ -168,7 +174,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | KnowledgeBase] + Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -188,7 +194,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | KnowledgeBase | None: +) -> HTTPValidationError | KnowledgeBase | ServiceUnavailableError | None: """Get Knowledge Base Fetch a knowledge base by ID. @@ -207,7 +213,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | KnowledgeBase + HTTPValidationError | KnowledgeBase | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/knowledge_bases/list_knowledge_bases_api_knowledge_bases_get.py b/seclai/_generated/api/knowledge_bases/list_knowledge_bases_api_knowledge_bases_get.py index b7abd30..d4ff44c 100644 --- a/seclai/_generated/api/knowledge_bases/list_knowledge_bases_api_knowledge_bases_get.py +++ b/seclai/_generated/api/knowledge_bases/list_knowledge_bases_api_knowledge_bases_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.knowledge_base_list_response_model import KnowledgeBaseListResponseModel +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -51,7 +52,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | KnowledgeBaseListResponseModel | None: +) -> ( + HTTPValidationError + | KnowledgeBaseListResponseModel + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = KnowledgeBaseListResponseModel.from_dict(response.json()) @@ -62,6 +68,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -70,7 +81,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | KnowledgeBaseListResponseModel]: +) -> Response[ + HTTPValidationError | KnowledgeBaseListResponseModel | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -88,7 +101,9 @@ def sync_detailed( order: str | Unset = "desc", x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | KnowledgeBaseListResponseModel]: +) -> Response[ + HTTPValidationError | KnowledgeBaseListResponseModel | ServiceUnavailableError +]: """List Knowledge Bases List knowledge bases for the account. @@ -111,7 +126,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | KnowledgeBaseListResponseModel] + Response[HTTPValidationError | KnowledgeBaseListResponseModel | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -139,7 +154,12 @@ def sync( order: str | Unset = "desc", x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | KnowledgeBaseListResponseModel | None: +) -> ( + HTTPValidationError + | KnowledgeBaseListResponseModel + | ServiceUnavailableError + | None +): """List Knowledge Bases List knowledge bases for the account. @@ -162,7 +182,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | KnowledgeBaseListResponseModel + HTTPValidationError | KnowledgeBaseListResponseModel | ServiceUnavailableError """ return sync_detailed( @@ -185,7 +205,9 @@ async def asyncio_detailed( order: str | Unset = "desc", x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | KnowledgeBaseListResponseModel]: +) -> Response[ + HTTPValidationError | KnowledgeBaseListResponseModel | ServiceUnavailableError +]: """List Knowledge Bases List knowledge bases for the account. @@ -208,7 +230,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | KnowledgeBaseListResponseModel] + Response[HTTPValidationError | KnowledgeBaseListResponseModel | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -234,7 +256,12 @@ async def asyncio( order: str | Unset = "desc", x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | KnowledgeBaseListResponseModel | None: +) -> ( + HTTPValidationError + | KnowledgeBaseListResponseModel + | ServiceUnavailableError + | None +): """List Knowledge Bases List knowledge bases for the account. @@ -257,7 +284,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | KnowledgeBaseListResponseModel + HTTPValidationError | KnowledgeBaseListResponseModel | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/knowledge_bases/update_knowledge_base_api_knowledge_bases_knowledge_base_id_put.py b/seclai/_generated/api/knowledge_bases/update_knowledge_base_api_knowledge_bases_knowledge_base_id_put.py index e6b8395..d634338 100644 --- a/seclai/_generated/api/knowledge_bases/update_knowledge_base_api_knowledge_bases_knowledge_base_id_put.py +++ b/seclai/_generated/api/knowledge_bases/update_knowledge_base_api_knowledge_bases_knowledge_base_id_put.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.knowledge_base import KnowledgeBase +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.update_knowledge_base_body import UpdateKnowledgeBaseBody from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | KnowledgeBase | None: +) -> HTTPValidationError | KnowledgeBase | ServiceUnavailableError | None: if response.status_code == 200: response_200 = KnowledgeBase.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | KnowledgeBase]: +) -> Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: UpdateKnowledgeBaseBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | KnowledgeBase]: +) -> Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError]: """Update Knowledge Base Update a knowledge base's configuration. Only provided fields are changed; omitted fields are left @@ -100,7 +106,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | KnowledgeBase] + Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -124,7 +130,7 @@ def sync( body: UpdateKnowledgeBaseBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | KnowledgeBase | None: +) -> HTTPValidationError | KnowledgeBase | ServiceUnavailableError | None: """Update Knowledge Base Update a knowledge base's configuration. Only provided fields are changed; omitted fields are left @@ -145,7 +151,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | KnowledgeBase + HTTPValidationError | KnowledgeBase | ServiceUnavailableError """ return sync_detailed( @@ -164,7 +170,7 @@ async def asyncio_detailed( body: UpdateKnowledgeBaseBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | KnowledgeBase]: +) -> Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError]: """Update Knowledge Base Update a knowledge base's configuration. Only provided fields are changed; omitted fields are left @@ -185,7 +191,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | KnowledgeBase] + Response[HTTPValidationError | KnowledgeBase | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -207,7 +213,7 @@ async def asyncio( body: UpdateKnowledgeBaseBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | KnowledgeBase | None: +) -> HTTPValidationError | KnowledgeBase | ServiceUnavailableError | None: """Update Knowledge Base Update a knowledge base's configuration. Only provided fields are changed; omitted fields are left @@ -228,7 +234,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | KnowledgeBase + HTTPValidationError | KnowledgeBase | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/compact_memory_bank_api_memory_banks_memory_bank_id_compact_post.py b/seclai/_generated/api/memory_banks/compact_memory_bank_api_memory_banks_memory_bank_id_compact_post.py index c78a7f0..0b2f2bf 100644 --- a/seclai/_generated/api/memory_banks/compact_memory_bank_api_memory_banks_memory_bank_id_compact_post.py +++ b/seclai/_generated/api/memory_banks/compact_memory_bank_api_memory_banks_memory_bank_id_compact_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.compaction_scheduled_response import CompactionScheduledResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> CompactionScheduledResponse | HTTPValidationError | None: +) -> CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 202: response_202 = CompactionScheduledResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[CompactionScheduledResponse | HTTPValidationError]: +) -> Response[ + CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,13 +80,16 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CompactionScheduledResponse | HTTPValidationError]: +) -> Response[ + CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError +]: """Compact Memory Bank Trigger an on-demand compaction run for a memory bank. - The bank must have at least one compaction threshold configured (max_age_days, max_turns, or - max_size_tokens). Compaction runs asynchronously — the response confirms scheduling, not completion. + The bank must have at least one compaction threshold configured (max_turns or max_size_tokens). Age + no longer triggers compaction — use retention_days to remove entries by age. Compaction runs + asynchronously — the response confirms scheduling, not completion. Args: memory_bank_id (str): @@ -90,7 +101,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CompactionScheduledResponse | HTTPValidationError] + Response[CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -112,13 +123,14 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CompactionScheduledResponse | HTTPValidationError | None: +) -> CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError | None: """Compact Memory Bank Trigger an on-demand compaction run for a memory bank. - The bank must have at least one compaction threshold configured (max_age_days, max_turns, or - max_size_tokens). Compaction runs asynchronously — the response confirms scheduling, not completion. + The bank must have at least one compaction threshold configured (max_turns or max_size_tokens). Age + no longer triggers compaction — use retention_days to remove entries by age. Compaction runs + asynchronously — the response confirms scheduling, not completion. Args: memory_bank_id (str): @@ -130,7 +142,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CompactionScheduledResponse | HTTPValidationError + CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -147,13 +159,16 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CompactionScheduledResponse | HTTPValidationError]: +) -> Response[ + CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError +]: """Compact Memory Bank Trigger an on-demand compaction run for a memory bank. - The bank must have at least one compaction threshold configured (max_age_days, max_turns, or - max_size_tokens). Compaction runs asynchronously — the response confirms scheduling, not completion. + The bank must have at least one compaction threshold configured (max_turns or max_size_tokens). Age + no longer triggers compaction — use retention_days to remove entries by age. Compaction runs + asynchronously — the response confirms scheduling, not completion. Args: memory_bank_id (str): @@ -165,7 +180,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CompactionScheduledResponse | HTTPValidationError] + Response[CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -185,13 +200,14 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CompactionScheduledResponse | HTTPValidationError | None: +) -> CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError | None: """Compact Memory Bank Trigger an on-demand compaction run for a memory bank. - The bank must have at least one compaction threshold configured (max_age_days, max_turns, or - max_size_tokens). Compaction runs asynchronously — the response confirms scheduling, not completion. + The bank must have at least one compaction threshold configured (max_turns or max_size_tokens). Age + no longer triggers compaction — use retention_days to remove entries by age. Compaction runs + asynchronously — the response confirms scheduling, not completion. Args: memory_bank_id (str): @@ -203,7 +219,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CompactionScheduledResponse | HTTPValidationError + CompactionScheduledResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/create_memory_bank_api_memory_banks_post.py b/seclai/_generated/api/memory_banks/create_memory_bank_api_memory_banks_post.py index 9953a07..9712004 100644 --- a/seclai/_generated/api/memory_banks/create_memory_bank_api_memory_banks_post.py +++ b/seclai/_generated/api/memory_banks/create_memory_bank_api_memory_banks_post.py @@ -9,6 +9,7 @@ from ...models.create_memory_bank_body import CreateMemoryBankBody from ...models.http_validation_error import HTTPValidationError from ...models.memory_bank import MemoryBank +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | MemoryBank | None: +) -> HTTPValidationError | MemoryBank | ServiceUnavailableError | None: if response.status_code == 201: response_201 = MemoryBank.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | MemoryBank]: +) -> Response[HTTPValidationError | MemoryBank | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +80,7 @@ def sync_detailed( body: CreateMemoryBankBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBank]: +) -> Response[HTTPValidationError | MemoryBank | ServiceUnavailableError]: """Create Memory Bank Create a new memory bank. @@ -92,7 +98,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBank] + Response[HTTPValidationError | MemoryBank | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +120,7 @@ def sync( body: CreateMemoryBankBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBank | None: +) -> HTTPValidationError | MemoryBank | ServiceUnavailableError | None: """Create Memory Bank Create a new memory bank. @@ -132,7 +138,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBank + HTTPValidationError | MemoryBank | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +155,7 @@ async def asyncio_detailed( body: CreateMemoryBankBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBank]: +) -> Response[HTTPValidationError | MemoryBank | ServiceUnavailableError]: """Create Memory Bank Create a new memory bank. @@ -167,7 +173,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBank] + Response[HTTPValidationError | MemoryBank | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -187,7 +193,7 @@ async def asyncio( body: CreateMemoryBankBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBank | None: +) -> HTTPValidationError | MemoryBank | ServiceUnavailableError | None: """Create Memory Bank Create a new memory bank. @@ -205,7 +211,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBank + HTTPValidationError | MemoryBank | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/delete_memory_bank_api_memory_banks_memory_bank_id_delete.py b/seclai/_generated/api/memory_banks/delete_memory_bank_api_memory_banks_memory_bank_id_delete.py index 4ad3519..4e2bc7b 100644 --- a/seclai/_generated/api/memory_banks/delete_memory_bank_api_memory_banks_memory_bank_id_delete.py +++ b/seclai/_generated/api/memory_banks/delete_memory_bank_api_memory_banks_memory_bank_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Memory Bank Soft-delete a memory bank. This action is permanent and cannot be undone. @@ -87,7 +93,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -109,7 +115,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Memory Bank Soft-delete a memory bank. This action is permanent and cannot be undone. @@ -126,7 +132,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -143,7 +149,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Memory Bank Soft-delete a memory bank. This action is permanent and cannot be undone. @@ -160,7 +166,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -180,7 +186,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Memory Bank Soft-delete a memory bank. This action is permanent and cannot be undone. @@ -197,7 +203,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/delete_memory_bank_source_api_memory_banks_memory_bank_id_source_delete.py b/seclai/_generated/api/memory_banks/delete_memory_bank_source_api_memory_banks_memory_bank_id_source_delete.py index 9227dcd..3bf9a56 100644 --- a/seclai/_generated/api/memory_banks/delete_memory_bank_source_api_memory_banks_memory_bank_id_source_delete.py +++ b/seclai/_generated/api/memory_banks/delete_memory_bank_source_api_memory_banks_memory_bank_id_source_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Memory Bank Source Delete the content source linked to a memory bank, removing all stored memory entries. @@ -88,7 +94,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -110,7 +116,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Memory Bank Source Delete the content source linked to a memory bank, removing all stored memory entries. @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Memory Bank Source Delete the content source linked to a memory bank, removing all stored memory entries. @@ -163,7 +169,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Memory Bank Source Delete the content source linked to a memory bank, removing all stored memory entries. @@ -201,7 +207,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/get_agents_using_bank_api_memory_banks_memory_bank_id_agents_get.py b/seclai/_generated/api/memory_banks/get_agents_using_bank_api_memory_banks_memory_bank_id_agents_get.py index 5598220..b9f667d 100644 --- a/seclai/_generated/api/memory_banks/get_agents_using_bank_api_memory_banks_memory_bank_id_agents_get.py +++ b/seclai/_generated/api/memory_banks/get_agents_using_bank_api_memory_banks_memory_bank_id_agents_get.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = response.json() return response_200 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Get Agents Using Bank List agents whose current definition references this memory bank. @@ -87,7 +93,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -109,7 +115,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Get Agents Using Bank List agents whose current definition references this memory bank. @@ -126,7 +132,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -143,7 +149,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Get Agents Using Bank List agents whose current definition references this memory bank. @@ -160,7 +166,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -180,7 +186,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Get Agents Using Bank List agents whose current definition references this memory bank. @@ -197,7 +203,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/get_memory_bank_api_memory_banks_memory_bank_id_get.py b/seclai/_generated/api/memory_banks/get_memory_bank_api_memory_banks_memory_bank_id_get.py index 9597be3..4e66ec8 100644 --- a/seclai/_generated/api/memory_banks/get_memory_bank_api_memory_banks_memory_bank_id_get.py +++ b/seclai/_generated/api/memory_banks/get_memory_bank_api_memory_banks_memory_bank_id_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.memory_bank import MemoryBank +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | MemoryBank | None: +) -> HTTPValidationError | MemoryBank | ServiceUnavailableError | None: if response.status_code == 200: response_200 = MemoryBank.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | MemoryBank]: +) -> Response[HTTPValidationError | MemoryBank | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBank]: +) -> Response[HTTPValidationError | MemoryBank | ServiceUnavailableError]: """Get Memory Bank Fetch a memory bank by ID. @@ -91,7 +97,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBank] + Response[HTTPValidationError | MemoryBank | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -113,7 +119,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBank | None: +) -> HTTPValidationError | MemoryBank | ServiceUnavailableError | None: """Get Memory Bank Fetch a memory bank by ID. @@ -132,7 +138,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBank + HTTPValidationError | MemoryBank | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +155,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBank]: +) -> Response[HTTPValidationError | MemoryBank | ServiceUnavailableError]: """Get Memory Bank Fetch a memory bank by ID. @@ -168,7 +174,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBank] + Response[HTTPValidationError | MemoryBank | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -188,7 +194,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBank | None: +) -> HTTPValidationError | MemoryBank | ServiceUnavailableError | None: """Get Memory Bank Fetch a memory bank by ID. @@ -207,7 +213,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBank + HTTPValidationError | MemoryBank | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/get_memory_bank_entry_stats_api_memory_banks_memory_bank_id_stats_get.py b/seclai/_generated/api/memory_banks/get_memory_bank_entry_stats_api_memory_banks_memory_bank_id_stats_get.py index 0f47ac0..34db2f5 100644 --- a/seclai/_generated/api/memory_banks/get_memory_bank_entry_stats_api_memory_banks_memory_bank_id_stats_get.py +++ b/seclai/_generated/api/memory_banks/get_memory_bank_entry_stats_api_memory_banks_memory_bank_id_stats_get.py @@ -12,6 +12,7 @@ GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet, ) from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -72,6 +73,7 @@ def _parse_response( ) -> ( GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError + | ServiceUnavailableError | None ): if response.status_code == 200: @@ -86,6 +88,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -97,6 +104,7 @@ def _build_response( ) -> Response[ GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError + | ServiceUnavailableError ]: return Response( status_code=HTTPStatus(response.status_code), @@ -118,6 +126,7 @@ def sync_detailed( ) -> Response[ GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError + | ServiceUnavailableError ]: """Get Memory Bank Entry Stats @@ -138,7 +147,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError] + Response[GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -169,6 +178,7 @@ def sync( ) -> ( GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError + | ServiceUnavailableError | None ): """Get Memory Bank Entry Stats @@ -190,7 +200,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError + GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -216,6 +226,7 @@ async def asyncio_detailed( ) -> Response[ GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError + | ServiceUnavailableError ]: """Get Memory Bank Entry Stats @@ -236,7 +247,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError] + Response[GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -265,6 +276,7 @@ async def asyncio( ) -> ( GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError + | ServiceUnavailableError | None ): """Get Memory Bank Entry Stats @@ -286,7 +298,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError + GetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGetResponseGetMemoryBankEntryStatsApiMemoryBanksMemoryBankIdStatsGet | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/list_memory_banks_api_memory_banks_get.py b/seclai/_generated/api/memory_banks/list_memory_banks_api_memory_banks_get.py index 3c2e752..a2ace43 100644 --- a/seclai/_generated/api/memory_banks/list_memory_banks_api_memory_banks_get.py +++ b/seclai/_generated/api/memory_banks/list_memory_banks_api_memory_banks_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.memory_bank_list_response_model import MemoryBankListResponseModel +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -59,7 +60,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | MemoryBankListResponseModel | None: +) -> HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError | None: if response.status_code == 200: response_200 = MemoryBankListResponseModel.from_dict(response.json()) @@ -70,6 +71,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -78,7 +84,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | MemoryBankListResponseModel]: +) -> Response[ + HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -97,7 +105,9 @@ def sync_detailed( type_: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBankListResponseModel]: +) -> Response[ + HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError +]: """List Memory Banks List memory banks for the account. @@ -121,7 +131,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBankListResponseModel] + Response[HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -151,7 +161,7 @@ def sync( type_: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBankListResponseModel | None: +) -> HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError | None: """List Memory Banks List memory banks for the account. @@ -175,7 +185,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBankListResponseModel + HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError """ return sync_detailed( @@ -200,7 +210,9 @@ async def asyncio_detailed( type_: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBankListResponseModel]: +) -> Response[ + HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError +]: """List Memory Banks List memory banks for the account. @@ -224,7 +236,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBankListResponseModel] + Response[HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -252,7 +264,7 @@ async def asyncio( type_: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBankListResponseModel | None: +) -> HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError | None: """List Memory Banks List memory banks for the account. @@ -276,7 +288,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBankListResponseModel + HTTPValidationError | MemoryBankListResponseModel | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/list_templates_api_memory_banks_templates_get.py b/seclai/_generated/api/memory_banks/list_templates_api_memory_banks_templates_get.py index 2f13e03..1a1adfa 100644 --- a/seclai/_generated/api/memory_banks/list_templates_api_memory_banks_templates_get.py +++ b/seclai/_generated/api/memory_banks/list_templates_api_memory_banks_templates_get.py @@ -6,6 +6,7 @@ from ... import errors from ...client import AuthenticatedClient, Client +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -32,9 +33,15 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | None: +) -> Any | ServiceUnavailableError | None: if response.status_code == 200: - return None + response_200 = response.json() + return response_200 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) @@ -44,7 +51,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any]: +) -> Response[Any | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -58,7 +65,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any]: +) -> Response[Any | ServiceUnavailableError]: """List Templates Return pre-built template configurations for common memory bank use cases. @@ -75,7 +82,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[Any | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -90,12 +97,44 @@ def sync_detailed( return _build_response(client=client, response=response) +def sync( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Any | ServiceUnavailableError | None: + """List Templates + + Return pre-built template configurations for common memory bank use cases. + + Each template includes a name, description, suggested use case, and full default settings that can + be used directly with the create endpoint. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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 | ServiceUnavailableError + """ + + return sync_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + async def asyncio_detailed( *, client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any]: +) -> Response[Any | ServiceUnavailableError]: """List Templates Return pre-built template configurations for common memory bank use cases. @@ -112,7 +151,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[Any | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -123,3 +162,37 @@ async def asyncio_detailed( response = await client.get_async_httpx_client().request(**kwargs) return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Any | ServiceUnavailableError | None: + """List Templates + + Return pre-built template configurations for common memory bank use cases. + + Each template includes a name, description, suggested use case, and full default settings that can + be used directly with the create endpoint. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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 | ServiceUnavailableError + """ + + return ( + await asyncio_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/memory_banks/memory_bank_ai_accept_api_memory_banks_ai_assistant_conversation_id_patch.py b/seclai/_generated/api/memory_banks/memory_bank_ai_accept_api_memory_banks_ai_assistant_conversation_id_patch.py index 342ebbc..de61022 100644 --- a/seclai/_generated/api/memory_banks/memory_bank_ai_accept_api_memory_banks_ai_assistant_conversation_id_patch.py +++ b/seclai/_generated/api/memory_banks/memory_bank_ai_accept_api_memory_banks_ai_assistant_conversation_id_patch.py @@ -10,6 +10,7 @@ from ...models.http_validation_error import HTTPValidationError from ...models.memory_bank_accept_request import MemoryBankAcceptRequest from ...models.ok_response import OkResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | OkResponse | None: +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = OkResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | OkResponse]: +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: MemoryBankAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OkResponse]: +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: """Accept or decline a memory bank AI suggestion Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to @@ -99,7 +105,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OkResponse] + Response[HTTPValidationError | OkResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -123,7 +129,7 @@ def sync( body: MemoryBankAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OkResponse | None: +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: """Accept or decline a memory bank AI suggestion Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to @@ -143,7 +149,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OkResponse + HTTPValidationError | OkResponse | ServiceUnavailableError """ return sync_detailed( @@ -162,7 +168,7 @@ async def asyncio_detailed( body: MemoryBankAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | OkResponse]: +) -> Response[HTTPValidationError | OkResponse | ServiceUnavailableError]: """Accept or decline a memory bank AI suggestion Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to @@ -182,7 +188,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | OkResponse] + Response[HTTPValidationError | OkResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -204,7 +210,7 @@ async def asyncio( body: MemoryBankAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | OkResponse | None: +) -> HTTPValidationError | OkResponse | ServiceUnavailableError | None: """Accept or decline a memory bank AI suggestion Update the acceptance status of a memory bank AI assistant conversation turn. Set ``accepted`` to @@ -224,7 +230,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | OkResponse + HTTPValidationError | OkResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/memory_bank_ai_generate_api_memory_banks_ai_assistant_post.py b/seclai/_generated/api/memory_banks/memory_bank_ai_generate_api_memory_banks_ai_assistant_post.py index 5701975..ec64985 100644 --- a/seclai/_generated/api/memory_banks/memory_bank_ai_generate_api_memory_banks_ai_assistant_post.py +++ b/seclai/_generated/api/memory_banks/memory_bank_ai_generate_api_memory_banks_ai_assistant_post.py @@ -9,6 +9,7 @@ from ...models.http_validation_error import HTTPValidationError from ...models.memory_bank_ai_assistant_request import MemoryBankAiAssistantRequest from ...models.memory_bank_ai_assistant_response import MemoryBankAiAssistantResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,13 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | MemoryBankAiAssistantResponse | None: +) -> ( + Any + | HTTPValidationError + | MemoryBankAiAssistantResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = MemoryBankAiAssistantResponse.from_dict(response.json()) @@ -55,6 +62,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +75,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError | MemoryBankAiAssistantResponse]: +) -> Response[ + Any | HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -78,7 +92,9 @@ def sync_detailed( body: MemoryBankAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | MemoryBankAiAssistantResponse]: +) -> Response[ + Any | HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError +]: """Generate a memory bank configuration Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, @@ -96,7 +112,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | MemoryBankAiAssistantResponse] + Response[Any | HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -118,7 +134,13 @@ def sync( body: MemoryBankAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | MemoryBankAiAssistantResponse | None: +) -> ( + Any + | HTTPValidationError + | MemoryBankAiAssistantResponse + | ServiceUnavailableError + | None +): """Generate a memory bank configuration Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, @@ -136,7 +158,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | MemoryBankAiAssistantResponse + Any | HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError """ return sync_detailed( @@ -153,7 +175,9 @@ async def asyncio_detailed( body: MemoryBankAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | MemoryBankAiAssistantResponse]: +) -> Response[ + Any | HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError +]: """Generate a memory bank configuration Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, @@ -171,7 +195,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | MemoryBankAiAssistantResponse] + Response[Any | HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -191,7 +215,13 @@ async def asyncio( body: MemoryBankAiAssistantRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | MemoryBankAiAssistantResponse | None: +) -> ( + Any + | HTTPValidationError + | MemoryBankAiAssistantResponse + | ServiceUnavailableError + | None +): """Generate a memory bank configuration Generate a memory bank configuration suggestion via the AI assistant. The AI proposes name, type, @@ -209,7 +239,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | MemoryBankAiAssistantResponse + Any | HTTPValidationError | MemoryBankAiAssistantResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/memory_bank_ai_last_conversation_api_memory_banks_ai_assistant_last_conversation_get.py b/seclai/_generated/api/memory_banks/memory_bank_ai_last_conversation_api_memory_banks_ai_assistant_last_conversation_get.py index 591ba3f..df8209d 100644 --- a/seclai/_generated/api/memory_banks/memory_bank_ai_last_conversation_api_memory_banks_ai_assistant_last_conversation_get.py +++ b/seclai/_generated/api/memory_banks/memory_bank_ai_last_conversation_api_memory_banks_ai_assistant_last_conversation_get.py @@ -10,6 +10,7 @@ from ...models.memory_bank_last_conversation_response import ( MemoryBankLastConversationResponse, ) +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -47,7 +48,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | MemoryBankLastConversationResponse | None: +) -> ( + HTTPValidationError + | MemoryBankLastConversationResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: response_200 = MemoryBankLastConversationResponse.from_dict(response.json()) @@ -58,6 +64,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -66,7 +77,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | MemoryBankLastConversationResponse]: +) -> Response[ + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -82,7 +95,9 @@ def sync_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBankLastConversationResponse]: +) -> Response[ + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError +]: """Fetch memory bank AI conversation history Fetch the most recent memory bank AI assistant conversation turns for the current user. Supports @@ -101,7 +116,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBankLastConversationResponse] + Response[HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -125,7 +140,12 @@ def sync( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBankLastConversationResponse | None: +) -> ( + HTTPValidationError + | MemoryBankLastConversationResponse + | ServiceUnavailableError + | None +): """Fetch memory bank AI conversation history Fetch the most recent memory bank AI assistant conversation turns for the current user. Supports @@ -144,7 +164,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBankLastConversationResponse + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError """ return sync_detailed( @@ -163,7 +183,9 @@ async def asyncio_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBankLastConversationResponse]: +) -> Response[ + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError +]: """Fetch memory bank AI conversation history Fetch the most recent memory bank AI assistant conversation turns for the current user. Supports @@ -182,7 +204,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBankLastConversationResponse] + Response[HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -204,7 +226,12 @@ async def asyncio( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBankLastConversationResponse | None: +) -> ( + HTTPValidationError + | MemoryBankLastConversationResponse + | ServiceUnavailableError + | None +): """Fetch memory bank AI conversation history Fetch the most recent memory bank AI assistant conversation turns for the current user. Supports @@ -223,7 +250,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBankLastConversationResponse + HTTPValidationError | MemoryBankLastConversationResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/test_compaction_prompt_api_memory_banks_memory_bank_id_test_compaction_post.py b/seclai/_generated/api/memory_banks/test_compaction_prompt_api_memory_banks_memory_bank_id_test_compaction_post.py index 68ce20b..c6df978 100644 --- a/seclai/_generated/api/memory_banks/test_compaction_prompt_api_memory_banks_memory_bank_id_test_compaction_post.py +++ b/seclai/_generated/api/memory_banks/test_compaction_prompt_api_memory_banks_memory_bank_id_test_compaction_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.compaction_test_response_model import CompactionTestResponseModel from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.test_compaction_request import TestCompactionRequest from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> CompactionTestResponseModel | HTTPValidationError | None: +) -> CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = CompactionTestResponseModel.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[CompactionTestResponseModel | HTTPValidationError]: +) -> Response[ + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +87,9 @@ def sync_detailed( body: TestCompactionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CompactionTestResponseModel | HTTPValidationError]: +) -> Response[ + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError +]: """Test Compaction Prompt Test a compaction prompt by running the summarizer and evaluating the result with an LLM-as-judge. @@ -109,7 +119,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CompactionTestResponseModel | HTTPValidationError] + Response[CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -133,7 +143,7 @@ def sync( body: TestCompactionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CompactionTestResponseModel | HTTPValidationError | None: +) -> CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError | None: """Test Compaction Prompt Test a compaction prompt by running the summarizer and evaluating the result with an LLM-as-judge. @@ -163,7 +173,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CompactionTestResponseModel | HTTPValidationError + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -182,7 +192,9 @@ async def asyncio_detailed( body: TestCompactionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CompactionTestResponseModel | HTTPValidationError]: +) -> Response[ + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError +]: """Test Compaction Prompt Test a compaction prompt by running the summarizer and evaluating the result with an LLM-as-judge. @@ -212,7 +224,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CompactionTestResponseModel | HTTPValidationError] + Response[CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -234,7 +246,7 @@ async def asyncio( body: TestCompactionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CompactionTestResponseModel | HTTPValidationError | None: +) -> CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError | None: """Test Compaction Prompt Test a compaction prompt by running the summarizer and evaluating the result with an LLM-as-judge. @@ -264,7 +276,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CompactionTestResponseModel | HTTPValidationError + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/test_compaction_prompt_standalone_api_memory_banks_test_compaction_post.py b/seclai/_generated/api/memory_banks/test_compaction_prompt_standalone_api_memory_banks_test_compaction_post.py index d4096b4..ebf28bb 100644 --- a/seclai/_generated/api/memory_banks/test_compaction_prompt_standalone_api_memory_banks_test_compaction_post.py +++ b/seclai/_generated/api/memory_banks/test_compaction_prompt_standalone_api_memory_banks_test_compaction_post.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.compaction_test_response_model import CompactionTestResponseModel from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.standalone_test_compaction_request import StandaloneTestCompactionRequest from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> CompactionTestResponseModel | HTTPValidationError | None: +) -> CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = CompactionTestResponseModel.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[CompactionTestResponseModel | HTTPValidationError]: +) -> Response[ + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +82,9 @@ def sync_detailed( body: StandaloneTestCompactionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CompactionTestResponseModel | HTTPValidationError]: +) -> Response[ + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError +]: """Test Compaction Prompt Standalone Test a compaction prompt by running the summarizer and evaluating the result with an LLM-as-judge. @@ -97,7 +107,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CompactionTestResponseModel | HTTPValidationError] + Response[CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -119,7 +129,7 @@ def sync( body: StandaloneTestCompactionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CompactionTestResponseModel | HTTPValidationError | None: +) -> CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError | None: """Test Compaction Prompt Standalone Test a compaction prompt by running the summarizer and evaluating the result with an LLM-as-judge. @@ -142,7 +152,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CompactionTestResponseModel | HTTPValidationError + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -159,7 +169,9 @@ async def asyncio_detailed( body: StandaloneTestCompactionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CompactionTestResponseModel | HTTPValidationError]: +) -> Response[ + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError +]: """Test Compaction Prompt Standalone Test a compaction prompt by running the summarizer and evaluating the result with an LLM-as-judge. @@ -182,7 +194,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CompactionTestResponseModel | HTTPValidationError] + Response[CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -202,7 +214,7 @@ async def asyncio( body: StandaloneTestCompactionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CompactionTestResponseModel | HTTPValidationError | None: +) -> CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError | None: """Test Compaction Prompt Standalone Test a compaction prompt by running the summarizer and evaluating the result with an LLM-as-judge. @@ -225,7 +237,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CompactionTestResponseModel | HTTPValidationError + CompactionTestResponseModel | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/memory_banks/update_memory_bank_api_memory_banks_memory_bank_id_put.py b/seclai/_generated/api/memory_banks/update_memory_bank_api_memory_banks_memory_bank_id_put.py index ea1c237..18cd4eb 100644 --- a/seclai/_generated/api/memory_banks/update_memory_bank_api_memory_banks_memory_bank_id_put.py +++ b/seclai/_generated/api/memory_banks/update_memory_bank_api_memory_banks_memory_bank_id_put.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.memory_bank import MemoryBank +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.update_memory_bank_body import UpdateMemoryBankBody from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | MemoryBank | None: +) -> HTTPValidationError | MemoryBank | ServiceUnavailableError | None: if response.status_code == 200: response_200 = MemoryBank.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | MemoryBank]: +) -> Response[HTTPValidationError | MemoryBank | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: UpdateMemoryBankBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBank]: +) -> Response[HTTPValidationError | MemoryBank | ServiceUnavailableError]: """Update Memory Bank Update a memory bank's configuration. Only provided fields are changed; omitted fields are left @@ -102,7 +108,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBank] + Response[HTTPValidationError | MemoryBank | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -126,7 +132,7 @@ def sync( body: UpdateMemoryBankBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBank | None: +) -> HTTPValidationError | MemoryBank | ServiceUnavailableError | None: """Update Memory Bank Update a memory bank's configuration. Only provided fields are changed; omitted fields are left @@ -149,7 +155,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBank + HTTPValidationError | MemoryBank | ServiceUnavailableError """ return sync_detailed( @@ -168,7 +174,7 @@ async def asyncio_detailed( body: UpdateMemoryBankBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | MemoryBank]: +) -> Response[HTTPValidationError | MemoryBank | ServiceUnavailableError]: """Update Memory Bank Update a memory bank's configuration. Only provided fields are changed; omitted fields are left @@ -191,7 +197,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | MemoryBank] + Response[HTTPValidationError | MemoryBank | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -213,7 +219,7 @@ async def asyncio( body: UpdateMemoryBankBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | MemoryBank | None: +) -> HTTPValidationError | MemoryBank | ServiceUnavailableError | None: """Update Memory Bank Update a memory bank's configuration. Only provided fields are changed; omitted fields are left @@ -236,7 +242,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | MemoryBank + HTTPValidationError | MemoryBank | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/cancel_experiment_endpoint_api_models_playground_experiments_experiment_id_cancel_post.py b/seclai/_generated/api/models/cancel_experiment_endpoint_api_models_playground_experiments_experiment_id_cancel_post.py index 89bc106..fc7efb5 100644 --- a/seclai/_generated/api/models/cancel_experiment_endpoint_api_models_playground_experiments_experiment_id_cancel_post.py +++ b/seclai/_generated/api/models/cancel_experiment_endpoint_api_models_playground_experiments_experiment_id_cancel_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.cancel_experiment_response import CancelExperimentResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> CancelExperimentResponse | HTTPValidationError | None: +) -> CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = CancelExperimentResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[CancelExperimentResponse | HTTPValidationError]: +) -> Response[CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CancelExperimentResponse | HTTPValidationError]: +) -> Response[CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError]: """Cancel Experiment Endpoint Cancel a running or pending model playground experiment. @@ -81,7 +87,7 @@ def sync_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -93,7 +99,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CancelExperimentResponse | HTTPValidationError] + Response[CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -115,7 +121,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CancelExperimentResponse | HTTPValidationError | None: +) -> CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError | None: """Cancel Experiment Endpoint Cancel a running or pending model playground experiment. @@ -124,7 +130,7 @@ def sync( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -136,7 +142,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CancelExperimentResponse | HTTPValidationError + CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -153,7 +159,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CancelExperimentResponse | HTTPValidationError]: +) -> Response[CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError]: """Cancel Experiment Endpoint Cancel a running or pending model playground experiment. @@ -162,7 +168,7 @@ async def asyncio_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -174,7 +180,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CancelExperimentResponse | HTTPValidationError] + Response[CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -194,7 +200,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CancelExperimentResponse | HTTPValidationError | None: +) -> CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError | None: """Cancel Experiment Endpoint Cancel a running or pending model playground experiment. @@ -203,7 +209,7 @@ async def asyncio( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -215,7 +221,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CancelExperimentResponse | HTTPValidationError + CancelExperimentResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/create_experiment_api_models_playground_experiments_post.py b/seclai/_generated/api/models/create_experiment_api_models_playground_experiments_post.py index cf6e09c..d9ebf94 100644 --- a/seclai/_generated/api/models/create_experiment_api_models_playground_experiments_post.py +++ b/seclai/_generated/api/models/create_experiment_api_models_playground_experiments_post.py @@ -9,6 +9,7 @@ from ...models.create_experiment_response import CreateExperimentResponse from ...models.http_validation_error import HTTPValidationError from ...models.playground_create_request import PlaygroundCreateRequest +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> CreateExperimentResponse | HTTPValidationError | None: +) -> CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = CreateExperimentResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[CreateExperimentResponse | HTTPValidationError]: +) -> Response[CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +80,7 @@ def sync_detailed( body: PlaygroundCreateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CreateExperimentResponse | HTTPValidationError]: +) -> Response[CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError]: """Create Experiment Create and schedule a model playground experiment. @@ -84,6 +90,8 @@ def sync_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. + - When the credential is bound to a user, the experiment belongs to that user; only that user or an + account-scoped key can cancel or delete it. Args: x_account_id (UUID | Unset): @@ -95,7 +103,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CreateExperimentResponse | HTTPValidationError] + Response[CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -117,7 +125,7 @@ def sync( body: PlaygroundCreateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CreateExperimentResponse | HTTPValidationError | None: +) -> CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError | None: """Create Experiment Create and schedule a model playground experiment. @@ -127,6 +135,8 @@ def sync( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. + - When the credential is bound to a user, the experiment belongs to that user; only that user or an + account-scoped key can cancel or delete it. Args: x_account_id (UUID | Unset): @@ -138,7 +148,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CreateExperimentResponse | HTTPValidationError + CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -155,7 +165,7 @@ async def asyncio_detailed( body: PlaygroundCreateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[CreateExperimentResponse | HTTPValidationError]: +) -> Response[CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError]: """Create Experiment Create and schedule a model playground experiment. @@ -165,6 +175,8 @@ async def asyncio_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. + - When the credential is bound to a user, the experiment belongs to that user; only that user or an + account-scoped key can cancel or delete it. Args: x_account_id (UUID | Unset): @@ -176,7 +188,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CreateExperimentResponse | HTTPValidationError] + Response[CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -196,7 +208,7 @@ async def asyncio( body: PlaygroundCreateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> CreateExperimentResponse | HTTPValidationError | None: +) -> CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError | None: """Create Experiment Create and schedule a model playground experiment. @@ -206,6 +218,8 @@ async def asyncio( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. + - When the credential is bound to a user, the experiment belongs to that user; only that user or an + account-scoped key can cancel or delete it. Args: x_account_id (UUID | Unset): @@ -217,7 +231,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - CreateExperimentResponse | HTTPValidationError + CreateExperimentResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/delete_experiment_endpoint_api_models_playground_experiments_experiment_id_delete.py b/seclai/_generated/api/models/delete_experiment_endpoint_api_models_playground_experiments_experiment_id_delete.py index 0e6b53f..d79cd9d 100644 --- a/seclai/_generated/api/models/delete_experiment_endpoint_api_models_playground_experiments_experiment_id_delete.py +++ b/seclai/_generated/api/models/delete_experiment_endpoint_api_models_playground_experiments_experiment_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Experiment Endpoint Soft-delete a model playground experiment. @@ -79,7 +85,7 @@ def sync_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth access token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -91,7 +97,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -113,7 +119,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Experiment Endpoint Soft-delete a model playground experiment. @@ -122,7 +128,7 @@ def sync( Auth & scoping: - Requires `X-API-Key` header or OAuth access token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -134,7 +140,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -151,7 +157,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Experiment Endpoint Soft-delete a model playground experiment. @@ -160,7 +166,7 @@ async def asyncio_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth access token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -172,7 +178,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -192,7 +198,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Experiment Endpoint Soft-delete a model playground experiment. @@ -201,7 +207,7 @@ async def asyncio( Auth & scoping: - Requires `X-API-Key` header or OAuth access token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -213,7 +219,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/get_alert_unread_count_api_models_alerts_unread_count_get.py b/seclai/_generated/api/models/get_alert_unread_count_api_models_alerts_unread_count_get.py index 25a65f1..75bf483 100644 --- a/seclai/_generated/api/models/get_alert_unread_count_api_models_alerts_unread_count_get.py +++ b/seclai/_generated/api/models/get_alert_unread_count_api_models_alerts_unread_count_get.py @@ -6,6 +6,7 @@ from ... import errors from ...client import AuthenticatedClient, Client +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.unread_count_response import UnreadCountResponse from ...types import UNSET, Response, Unset @@ -33,12 +34,17 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> UnreadCountResponse | None: +) -> ServiceUnavailableError | UnreadCountResponse | None: if response.status_code == 200: response_200 = UnreadCountResponse.from_dict(response.json()) return response_200 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -47,7 +53,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[UnreadCountResponse]: +) -> Response[ServiceUnavailableError | UnreadCountResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -61,7 +67,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[UnreadCountResponse]: +) -> Response[ServiceUnavailableError | UnreadCountResponse]: """Get Alert Unread Count Get the count of unread model lifecycle alerts. @@ -80,7 +86,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[UnreadCountResponse] + Response[ServiceUnavailableError | UnreadCountResponse] """ kwargs = _get_kwargs( @@ -100,7 +106,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> UnreadCountResponse | None: +) -> ServiceUnavailableError | UnreadCountResponse | None: """Get Alert Unread Count Get the count of unread model lifecycle alerts. @@ -119,7 +125,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - UnreadCountResponse + ServiceUnavailableError | UnreadCountResponse """ return sync_detailed( @@ -134,7 +140,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[UnreadCountResponse]: +) -> Response[ServiceUnavailableError | UnreadCountResponse]: """Get Alert Unread Count Get the count of unread model lifecycle alerts. @@ -153,7 +159,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[UnreadCountResponse] + Response[ServiceUnavailableError | UnreadCountResponse] """ kwargs = _get_kwargs( @@ -171,7 +177,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> UnreadCountResponse | None: +) -> ServiceUnavailableError | UnreadCountResponse | None: """Get Alert Unread Count Get the count of unread model lifecycle alerts. @@ -190,7 +196,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - UnreadCountResponse + ServiceUnavailableError | UnreadCountResponse """ return ( diff --git a/seclai/_generated/api/models/get_experiment_api_models_playground_experiments_experiment_id_get.py b/seclai/_generated/api/models/get_experiment_api_models_playground_experiments_experiment_id_get.py index 4c59601..46cac40 100644 --- a/seclai/_generated/api/models/get_experiment_api_models_playground_experiments_experiment_id_get.py +++ b/seclai/_generated/api/models/get_experiment_api_models_playground_experiments_experiment_id_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.experiment_detail_response import ExperimentDetailResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ExperimentDetailResponse | HTTPValidationError | None: +) -> ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ExperimentDetailResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ExperimentDetailResponse | HTTPValidationError]: +) -> Response[ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExperimentDetailResponse | HTTPValidationError]: +) -> Response[ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Get Experiment Get details and results for a specific model playground experiment. @@ -82,7 +88,7 @@ def sync_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -94,7 +100,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExperimentDetailResponse | HTTPValidationError] + Response[ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -116,7 +122,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExperimentDetailResponse | HTTPValidationError | None: +) -> ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Get Experiment Get details and results for a specific model playground experiment. @@ -126,7 +132,7 @@ def sync( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -138,7 +144,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExperimentDetailResponse | HTTPValidationError + ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -155,7 +161,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExperimentDetailResponse | HTTPValidationError]: +) -> Response[ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError]: """Get Experiment Get details and results for a specific model playground experiment. @@ -165,7 +171,7 @@ async def asyncio_detailed( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -177,7 +183,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExperimentDetailResponse | HTTPValidationError] + Response[ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -197,7 +203,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExperimentDetailResponse | HTTPValidationError | None: +) -> ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError | None: """Get Experiment Get details and results for a specific model playground experiment. @@ -207,7 +213,7 @@ async def asyncio( Auth & scoping: - Requires `X-API-Key` header or OAuth Bearer token. The experiment must belong to the caller's - account. + account and, when the credential is bound to a user, to that user; otherwise 404. Args: experiment_id (UUID): @@ -219,7 +225,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExperimentDetailResponse | HTTPValidationError + ExperimentDetailResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/get_generation_tiers_api_models_generation_tiers_get.py b/seclai/_generated/api/models/get_generation_tiers_api_models_generation_tiers_get.py index 1fda8e9..48846d3 100644 --- a/seclai/_generated/api/models/get_generation_tiers_api_models_generation_tiers_get.py +++ b/seclai/_generated/api/models/get_generation_tiers_api_models_generation_tiers_get.py @@ -7,6 +7,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.generation_tier_list_response import GenerationTierListResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -33,12 +34,17 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> GenerationTierListResponse | None: +) -> GenerationTierListResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = GenerationTierListResponse.from_dict(response.json()) return response_200 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -47,7 +53,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[GenerationTierListResponse]: +) -> Response[GenerationTierListResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -61,7 +67,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[GenerationTierListResponse]: +) -> Response[GenerationTierListResponse | ServiceUnavailableError]: """Get Generation Tiers List the media-generation quality tiers and the model + cost each resolves to. @@ -84,7 +90,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[GenerationTierListResponse] + Response[GenerationTierListResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -104,7 +110,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> GenerationTierListResponse | None: +) -> GenerationTierListResponse | ServiceUnavailableError | None: """Get Generation Tiers List the media-generation quality tiers and the model + cost each resolves to. @@ -127,7 +133,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - GenerationTierListResponse + GenerationTierListResponse | ServiceUnavailableError """ return sync_detailed( @@ -142,7 +148,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[GenerationTierListResponse]: +) -> Response[GenerationTierListResponse | ServiceUnavailableError]: """Get Generation Tiers List the media-generation quality tiers and the model + cost each resolves to. @@ -165,7 +171,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[GenerationTierListResponse] + Response[GenerationTierListResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> GenerationTierListResponse | None: +) -> GenerationTierListResponse | ServiceUnavailableError | None: """Get Generation Tiers List the media-generation quality tiers and the model + cost each resolves to. @@ -206,7 +212,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - GenerationTierListResponse + GenerationTierListResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/get_model_api_models_model_id_details_get.py b/seclai/_generated/api/models/get_model_api_models_model_id_details_get.py index 45bf1fb..b190317 100644 --- a/seclai/_generated/api/models/get_model_api_models_model_id_details_get.py +++ b/seclai/_generated/api/models/get_model_api_models_model_id_details_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.prompt_model_response import PromptModelResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | PromptModelResponse | None: +) -> HTTPValidationError | PromptModelResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = PromptModelResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | PromptModelResponse]: +) -> Response[HTTPValidationError | PromptModelResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | PromptModelResponse]: +) -> Response[HTTPValidationError | PromptModelResponse | ServiceUnavailableError]: """Get Model Get detailed information about a specific model. @@ -95,7 +101,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | PromptModelResponse] + Response[HTTPValidationError | PromptModelResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -117,7 +123,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | PromptModelResponse | None: +) -> HTTPValidationError | PromptModelResponse | ServiceUnavailableError | None: """Get Model Get detailed information about a specific model. @@ -140,7 +146,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | PromptModelResponse + HTTPValidationError | PromptModelResponse | ServiceUnavailableError """ return sync_detailed( @@ -157,7 +163,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | PromptModelResponse]: +) -> Response[HTTPValidationError | PromptModelResponse | ServiceUnavailableError]: """Get Model Get detailed information about a specific model. @@ -180,7 +186,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | PromptModelResponse] + Response[HTTPValidationError | PromptModelResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -200,7 +206,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | PromptModelResponse | None: +) -> HTTPValidationError | PromptModelResponse | ServiceUnavailableError | None: """Get Model Get detailed information about a specific model. @@ -223,7 +229,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | PromptModelResponse + HTTPValidationError | PromptModelResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/get_recommendations_api_models_model_id_recommendations_get.py b/seclai/_generated/api/models/get_recommendations_api_models_model_id_recommendations_get.py index e58a035..f45e9e1 100644 --- a/seclai/_generated/api/models/get_recommendations_api_models_model_id_recommendations_get.py +++ b/seclai/_generated/api/models/get_recommendations_api_models_model_id_recommendations_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.model_recommendations_response import ModelRecommendationsResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -83,7 +84,9 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | ModelRecommendationsResponse | None: +) -> ( + HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError | None +): if response.status_code == 200: response_200 = ModelRecommendationsResponse.from_dict(response.json()) @@ -94,6 +97,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -102,7 +110,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | ModelRecommendationsResponse]: +) -> Response[ + HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -122,7 +132,9 @@ def sync_detailed( min_output_tokens: int | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | ModelRecommendationsResponse]: +) -> Response[ + HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError +]: """Get Recommendations Get replacement/upgrade recommendations for a model. @@ -150,7 +162,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | ModelRecommendationsResponse] + Response[HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -182,7 +194,9 @@ def sync( min_output_tokens: int | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | ModelRecommendationsResponse | None: +) -> ( + HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError | None +): """Get Recommendations Get replacement/upgrade recommendations for a model. @@ -210,7 +224,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | ModelRecommendationsResponse + HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError """ return sync_detailed( @@ -237,7 +251,9 @@ async def asyncio_detailed( min_output_tokens: int | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | ModelRecommendationsResponse]: +) -> Response[ + HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError +]: """Get Recommendations Get replacement/upgrade recommendations for a model. @@ -265,7 +281,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | ModelRecommendationsResponse] + Response[HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -295,7 +311,9 @@ async def asyncio( min_output_tokens: int | None | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | ModelRecommendationsResponse | None: +) -> ( + HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError | None +): """Get Recommendations Get replacement/upgrade recommendations for a model. @@ -323,7 +341,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | ModelRecommendationsResponse + HTTPValidationError | ModelRecommendationsResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/list_alerts_api_models_alerts_get.py b/seclai/_generated/api/models/list_alerts_api_models_alerts_get.py index 64735a7..59a766c 100644 --- a/seclai/_generated/api/models/list_alerts_api_models_alerts_get.py +++ b/seclai/_generated/api/models/list_alerts_api_models_alerts_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.model_alert_list_response import ModelAlertListResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -56,7 +57,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | ModelAlertListResponse | None: +) -> HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ModelAlertListResponse.from_dict(response.json()) @@ -67,6 +68,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -75,7 +81,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | ModelAlertListResponse]: +) -> Response[HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -93,7 +99,7 @@ def sync_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | ModelAlertListResponse]: +) -> Response[HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError]: """List Alerts List model lifecycle alerts for the account. @@ -117,7 +123,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | ModelAlertListResponse] + Response[HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -145,7 +151,7 @@ def sync( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | ModelAlertListResponse | None: +) -> HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError | None: """List Alerts List model lifecycle alerts for the account. @@ -169,7 +175,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | ModelAlertListResponse + HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError """ return sync_detailed( @@ -192,7 +198,7 @@ async def asyncio_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | ModelAlertListResponse]: +) -> Response[HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError]: """List Alerts List model lifecycle alerts for the account. @@ -216,7 +222,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | ModelAlertListResponse] + Response[HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -242,7 +248,7 @@ async def asyncio( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | ModelAlertListResponse | None: +) -> HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError | None: """List Alerts List model lifecycle alerts for the account. @@ -266,7 +272,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | ModelAlertListResponse + HTTPValidationError | ModelAlertListResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/list_embedding_models_api_models_embedders_get.py b/seclai/_generated/api/models/list_embedding_models_api_models_embedders_get.py new file mode 100644 index 0000000..11694f3 --- /dev/null +++ b/seclai/_generated/api/models/list_embedding_models_api_models_embedders_get.py @@ -0,0 +1,313 @@ +from http import HTTPStatus +from typing import Any +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.embedding_model_list_response import EmbeddingModelListResponse +from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + supports_input_media: None | str | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + params: dict[str, Any] = {} + + json_supports_input_media: None | str | Unset + if isinstance(supports_input_media, Unset): + json_supports_input_media = UNSET + else: + json_supports_input_media = supports_input_media + params["supports_input_media"] = json_supports_input_media + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/models/embedders", + "params": params, + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError | None: + if response.status_code == 200: + response_200 = EmbeddingModelListResponse.from_dict(response.json()) + + return response_200 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[ + EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError +]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: AuthenticatedClient | Client, + supports_input_media: None | str | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError +]: + """List Embedding Models + + List the embedding models a source can be created with. + + Each entry carries the `model_type` to pass as `embedding_model` when creating a source, the + `dimensions` it supports, and — most importantly for multi-modal indexing — `supported_input_media`: + the modalities that embedder can actually index. A source only honours a `media_types` entry its + embedder lists here; unsupported kinds are dropped at save time with an `embedder_warning`, so check + this before choosing an embedder for a knowledge base of images or video. + + Text-only embedders report `supported_input_media` as null. Pricing is reported as `credits` (per + ~1,000 English words of text) plus `per_modality_rates` for the non-text modalities a multi-modal + embedder bills differently. + + An embedder whose credit rate has not been published yet is omitted, so you are never offered one + that cannot be billed. + + Optional query parameters: + - `supports_input_media`: keep only embedders that can index this modality + (`text`/`image`/`video`/`audio` or a full MIME) + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical + for every account. + + Args: + supports_input_media (None | str | Unset): Filter to embedders that can index this input + modality — a coarse kind (text, image, video, audio) or a full MIME. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + supports_input_media=supports_input_media, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: AuthenticatedClient | Client, + supports_input_media: None | str | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError | None: + """List Embedding Models + + List the embedding models a source can be created with. + + Each entry carries the `model_type` to pass as `embedding_model` when creating a source, the + `dimensions` it supports, and — most importantly for multi-modal indexing — `supported_input_media`: + the modalities that embedder can actually index. A source only honours a `media_types` entry its + embedder lists here; unsupported kinds are dropped at save time with an `embedder_warning`, so check + this before choosing an embedder for a knowledge base of images or video. + + Text-only embedders report `supported_input_media` as null. Pricing is reported as `credits` (per + ~1,000 English words of text) plus `per_modality_rates` for the non-text modalities a multi-modal + embedder bills differently. + + An embedder whose credit rate has not been published yet is omitted, so you are never offered one + that cannot be billed. + + Optional query parameters: + - `supports_input_media`: keep only embedders that can index this modality + (`text`/`image`/`video`/`audio` or a full MIME) + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical + for every account. + + Args: + supports_input_media (None | str | Unset): Filter to embedders that can index this input + modality — a coarse kind (text, image, video, audio) or a full MIME. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError + """ + + return sync_detailed( + client=client, + supports_input_media=supports_input_media, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + *, + client: AuthenticatedClient | Client, + supports_input_media: None | str | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError +]: + """List Embedding Models + + List the embedding models a source can be created with. + + Each entry carries the `model_type` to pass as `embedding_model` when creating a source, the + `dimensions` it supports, and — most importantly for multi-modal indexing — `supported_input_media`: + the modalities that embedder can actually index. A source only honours a `media_types` entry its + embedder lists here; unsupported kinds are dropped at save time with an `embedder_warning`, so check + this before choosing an embedder for a knowledge base of images or video. + + Text-only embedders report `supported_input_media` as null. Pricing is reported as `credits` (per + ~1,000 English words of text) plus `per_modality_rates` for the non-text modalities a multi-modal + embedder bills differently. + + An embedder whose credit rate has not been published yet is omitted, so you are never offered one + that cannot be billed. + + Optional query parameters: + - `supports_input_media`: keep only embedders that can index this modality + (`text`/`image`/`video`/`audio` or a full MIME) + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical + for every account. + + Args: + supports_input_media (None | str | Unset): Filter to embedders that can index this input + modality — a coarse kind (text, image, video, audio) or a full MIME. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + supports_input_media=supports_input_media, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient | Client, + supports_input_media: None | str | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError | None: + """List Embedding Models + + List the embedding models a source can be created with. + + Each entry carries the `model_type` to pass as `embedding_model` when creating a source, the + `dimensions` it supports, and — most importantly for multi-modal indexing — `supported_input_media`: + the modalities that embedder can actually index. A source only honours a `media_types` entry its + embedder lists here; unsupported kinds are dropped at save time with an `embedder_warning`, so check + this before choosing an embedder for a knowledge base of images or video. + + Text-only embedders report `supported_input_media` as null. Pricing is reported as `credits` (per + ~1,000 English words of text) plus `per_modality_rates` for the non-text modalities a multi-modal + embedder bills differently. + + An embedder whose credit rate has not been published yet is omitted, so you are never offered one + that cannot be billed. + + Optional query parameters: + - `supports_input_media`: keep only embedders that can index this modality + (`text`/`image`/`video`/`audio` or a full MIME) + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical + for every account. + + Args: + supports_input_media (None | str | Unset): Filter to embedders that can index this input + modality — a coarse kind (text, image, video, audio) or a full MIME. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + EmbeddingModelListResponse | HTTPValidationError | ServiceUnavailableError + """ + + return ( + await asyncio_detailed( + client=client, + supports_input_media=supports_input_media, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/models/list_experiments_api_models_playground_experiments_get.py b/seclai/_generated/api/models/list_experiments_api_models_playground_experiments_get.py index 3c94f7d..60005a3 100644 --- a/seclai/_generated/api/models/list_experiments_api_models_playground_experiments_get.py +++ b/seclai/_generated/api/models/list_experiments_api_models_playground_experiments_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.experiment_list_response import ExperimentListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -69,7 +70,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ExperimentListResponse | HTTPValidationError | None: +) -> ExperimentListResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ExperimentListResponse.from_dict(response.json()) @@ -80,6 +81,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -88,7 +94,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ExperimentListResponse | HTTPValidationError]: +) -> Response[ExperimentListResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -107,7 +113,7 @@ def sync_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExperimentListResponse | HTTPValidationError]: +) -> Response[ExperimentListResponse | HTTPValidationError | ServiceUnavailableError]: """List Experiments List model playground experiments for the account. @@ -115,7 +121,8 @@ def sync_detailed( Returns a paginated, time-filtered list of experiments ordered by creation date descending. Auth & scoping: - - Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account. + - Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account + and, when the credential is bound to a user, to that user. Args: days (int | Unset): Look-back window in days. Default: 30. @@ -131,7 +138,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExperimentListResponse | HTTPValidationError] + Response[ExperimentListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -161,7 +168,7 @@ def sync( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExperimentListResponse | HTTPValidationError | None: +) -> ExperimentListResponse | HTTPValidationError | ServiceUnavailableError | None: """List Experiments List model playground experiments for the account. @@ -169,7 +176,8 @@ def sync( Returns a paginated, time-filtered list of experiments ordered by creation date descending. Auth & scoping: - - Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account. + - Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account + and, when the credential is bound to a user, to that user. Args: days (int | Unset): Look-back window in days. Default: 30. @@ -185,7 +193,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExperimentListResponse | HTTPValidationError + ExperimentListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -210,7 +218,7 @@ async def asyncio_detailed( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExperimentListResponse | HTTPValidationError]: +) -> Response[ExperimentListResponse | HTTPValidationError | ServiceUnavailableError]: """List Experiments List model playground experiments for the account. @@ -218,7 +226,8 @@ async def asyncio_detailed( Returns a paginated, time-filtered list of experiments ordered by creation date descending. Auth & scoping: - - Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account. + - Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account + and, when the credential is bound to a user, to that user. Args: days (int | Unset): Look-back window in days. Default: 30. @@ -234,7 +243,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExperimentListResponse | HTTPValidationError] + Response[ExperimentListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -262,7 +271,7 @@ async def asyncio( offset: int | Unset = 0, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExperimentListResponse | HTTPValidationError | None: +) -> ExperimentListResponse | HTTPValidationError | ServiceUnavailableError | None: """List Experiments List model playground experiments for the account. @@ -270,7 +279,8 @@ async def asyncio( Returns a paginated, time-filtered list of experiments ordered by creation date descending. Auth & scoping: - - Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account. + - Requires `X-API-Key` header or OAuth Bearer token. Experiments are scoped to the caller's account + and, when the credential is bound to a user, to that user. Args: days (int | Unset): Look-back window in days. Default: 30. @@ -286,7 +296,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExperimentListResponse | HTTPValidationError + ExperimentListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/models/list_models_api_models_get.py b/seclai/_generated/api/models/list_models_api_models_get.py index 89197e2..e2592be 100644 --- a/seclai/_generated/api/models/list_models_api_models_get.py +++ b/seclai/_generated/api/models/list_models_api_models_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.provider_group_response import ProviderGroupResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -79,7 +80,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | list[ProviderGroupResponse] | None: +) -> HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse] | None: if response.status_code == 200: response_200 = [] _response_200 = response.json() @@ -95,6 +96,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -103,7 +109,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | list[ProviderGroupResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse] +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -122,14 +130,20 @@ def sync_detailed( supports_output_media: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[ProviderGroupResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse] +]: """List Models - List all enabled LLM models with full details. + List the enabled LLM models with full details. Returns models grouped by provider, including capabilities, credit pricing, tool support, variant tiers, and lifecycle status. + A model whose credit rate has not been published yet is omitted, so you are never offered a model + that cannot be billed and therefore cannot be run. Such a model may appear later without any other + change. + Optional query parameters: - `provider`: filter by provider (e.g. 'anthropic', 'openai') - `supports_tool_use`: filter to models with tool calling support @@ -159,7 +173,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[ProviderGroupResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse]] """ kwargs = _get_kwargs( @@ -189,14 +203,18 @@ def sync( supports_output_media: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[ProviderGroupResponse] | None: +) -> HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse] | None: """List Models - List all enabled LLM models with full details. + List the enabled LLM models with full details. Returns models grouped by provider, including capabilities, credit pricing, tool support, variant tiers, and lifecycle status. + A model whose credit rate has not been published yet is omitted, so you are never offered a model + that cannot be billed and therefore cannot be run. Such a model may appear later without any other + change. + Optional query parameters: - `provider`: filter by provider (e.g. 'anthropic', 'openai') - `supports_tool_use`: filter to models with tool calling support @@ -226,7 +244,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[ProviderGroupResponse] + HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse] """ return sync_detailed( @@ -251,14 +269,20 @@ async def asyncio_detailed( supports_output_media: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[ProviderGroupResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse] +]: """List Models - List all enabled LLM models with full details. + List the enabled LLM models with full details. Returns models grouped by provider, including capabilities, credit pricing, tool support, variant tiers, and lifecycle status. + A model whose credit rate has not been published yet is omitted, so you are never offered a model + that cannot be billed and therefore cannot be run. Such a model may appear later without any other + change. + Optional query parameters: - `provider`: filter by provider (e.g. 'anthropic', 'openai') - `supports_tool_use`: filter to models with tool calling support @@ -288,7 +312,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[ProviderGroupResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse]] """ kwargs = _get_kwargs( @@ -316,14 +340,18 @@ async def asyncio( supports_output_media: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[ProviderGroupResponse] | None: +) -> HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse] | None: """List Models - List all enabled LLM models with full details. + List the enabled LLM models with full details. Returns models grouped by provider, including capabilities, credit pricing, tool support, variant tiers, and lifecycle status. + A model whose credit rate has not been published yet is omitted, so you are never offered a model + that cannot be billed and therefore cannot be run. Such a model may appear later without any other + change. + Optional query parameters: - `provider`: filter by provider (e.g. 'anthropic', 'openai') - `supports_tool_use`: filter to models with tool calling support @@ -353,7 +381,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[ProviderGroupResponse] + HTTPValidationError | ServiceUnavailableError | list[ProviderGroupResponse] """ return ( diff --git a/seclai/_generated/api/models/list_reranker_models_api_models_rerankers_get.py b/seclai/_generated/api/models/list_reranker_models_api_models_rerankers_get.py new file mode 100644 index 0000000..56bbe44 --- /dev/null +++ b/seclai/_generated/api/models/list_reranker_models_api_models_rerankers_get.py @@ -0,0 +1,236 @@ +from http import HTTPStatus +from typing import Any +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.reranker_model_list_response import RerankerModelListResponse +from ...models.service_unavailable_error import ServiceUnavailableError +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/models/rerankers", + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> RerankerModelListResponse | ServiceUnavailableError | None: + if response.status_code == 200: + response_200 = RerankerModelListResponse.from_dict(response.json()) + + return response_200 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[RerankerModelListResponse | ServiceUnavailableError]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[RerankerModelListResponse | ServiceUnavailableError]: + r"""List Reranker Models + + List the reranker models a knowledge base can be created with. + + A reranker re-scores the top results of a vector search for relevance. Each entry carries the + `model_type` to pass as `reranker_model` on a knowledge base, its `credits_per_action`, and whether + it is the platform default (`is_default`, used when you omit `reranker_model`). + + To disable reranking, send `\"none\"` or an empty string as `reranker_model` rather than a value + from this list. Reranking scores text, so a knowledge base whose sources all embed media natively — + whose chunks carry no text — defaults to no reranker. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical + for every account. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[RerankerModelListResponse | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> RerankerModelListResponse | ServiceUnavailableError | None: + r"""List Reranker Models + + List the reranker models a knowledge base can be created with. + + A reranker re-scores the top results of a vector search for relevance. Each entry carries the + `model_type` to pass as `reranker_model` on a knowledge base, its `credits_per_action`, and whether + it is the platform default (`is_default`, used when you omit `reranker_model`). + + To disable reranking, send `\"none\"` or an empty string as `reranker_model` rather than a value + from this list. Reranking scores text, so a knowledge base whose sources all embed media natively — + whose chunks carry no text — defaults to no reranker. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical + for every account. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + RerankerModelListResponse | ServiceUnavailableError + """ + + return sync_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[RerankerModelListResponse | ServiceUnavailableError]: + r"""List Reranker Models + + List the reranker models a knowledge base can be created with. + + A reranker re-scores the top results of a vector search for relevance. Each entry carries the + `model_type` to pass as `reranker_model` on a knowledge base, its `credits_per_action`, and whether + it is the platform default (`is_default`, used when you omit `reranker_model`). + + To disable reranking, send `\"none\"` or an empty string as `reranker_model` rather than a value + from this list. Reranking scores text, so a knowledge base whose sources all embed media natively — + whose chunks carry no text — defaults to no reranker. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical + for every account. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[RerankerModelListResponse | ServiceUnavailableError] + """ + + kwargs = _get_kwargs( + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> RerankerModelListResponse | ServiceUnavailableError | None: + r"""List Reranker Models + + List the reranker models a knowledge base can be created with. + + A reranker re-scores the top results of a vector search for relevance. Each entry carries the + `model_type` to pass as `reranker_model` on a knowledge base, its `credits_per_action`, and whether + it is the platform default (`is_default`, used when you omit `reranker_model`). + + To disable reranking, send `\"none\"` or an empty string as `reranker_model` rather than a value + from this list. Reranking scores text, so a knowledge base whose sources all embed media natively — + whose chunks carry no text — defaults to no reranker. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. The catalog is global reference data, identical + for every account. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + RerankerModelListResponse | ServiceUnavailableError + """ + + return ( + await asyncio_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/models/mark_all_read_api_models_alerts_mark_all_read_post.py b/seclai/_generated/api/models/mark_all_read_api_models_alerts_mark_all_read_post.py index 8abbbd9..1881067 100644 --- a/seclai/_generated/api/models/mark_all_read_api_models_alerts_mark_all_read_post.py +++ b/seclai/_generated/api/models/mark_all_read_api_models_alerts_mark_all_read_post.py @@ -1,11 +1,12 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from uuid import UUID import httpx from ... import errors from ...client import AuthenticatedClient, Client +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -32,9 +33,15 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | None: +) -> Any | ServiceUnavailableError | None: if response.status_code == 204: - return None + response_204 = cast(Any, None) + return response_204 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) @@ -44,7 +51,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any]: +) -> Response[Any | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -58,7 +65,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any]: +) -> Response[Any | ServiceUnavailableError]: """Mark All Read Mark all model lifecycle alerts as read for the account. @@ -75,7 +82,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[Any | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -90,12 +97,44 @@ def sync_detailed( return _build_response(client=client, response=response) +def sync( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Any | ServiceUnavailableError | None: + """Mark All Read + + Mark all model lifecycle alerts as read for the account. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. Scoped to the caller's account. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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 | ServiceUnavailableError + """ + + return sync_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + async def asyncio_detailed( *, client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any]: +) -> Response[Any | ServiceUnavailableError]: """Mark All Read Mark all model lifecycle alerts as read for the account. @@ -112,7 +151,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[Any | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -123,3 +162,37 @@ async def asyncio_detailed( response = await client.get_async_httpx_client().request(**kwargs) return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Any | ServiceUnavailableError | None: + """Mark All Read + + Mark all model lifecycle alerts as read for the account. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. Scoped to the caller's account. + + Args: + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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 | ServiceUnavailableError + """ + + return ( + await asyncio_detailed( + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/models/mark_read_api_models_alerts_alert_id_read_patch.py b/seclai/_generated/api/models/mark_read_api_models_alerts_alert_id_read_patch.py index 3682eeb..a53eb6b 100644 --- a/seclai/_generated/api/models/mark_read_api_models_alerts_alert_id_read_patch.py +++ b/seclai/_generated/api/models/mark_read_api_models_alerts_alert_id_read_patch.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Mark Read Mark a single model lifecycle alert as read (dismissed). @@ -88,7 +94,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -110,7 +116,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Mark Read Mark a single model lifecycle alert as read (dismissed). @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Mark Read Mark a single model lifecycle alert as read (dismissed). @@ -163,7 +169,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Mark Read Mark a single model lifecycle alert as read (dismissed). @@ -201,7 +207,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/search/docs_search_api_docs_search_get.py b/seclai/_generated/api/search/docs_search_api_docs_search_get.py index b2f6e77..f6a177a 100644 --- a/seclai/_generated/api/search/docs_search_api_docs_search_get.py +++ b/seclai/_generated/api/search/docs_search_api_docs_search_get.py @@ -11,6 +11,7 @@ ) from ...models.docs_search_response import DocsSearchResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -57,7 +58,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> DocsSearchResponse | HTTPValidationError | None: +) -> DocsSearchResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = DocsSearchResponse.from_dict(response.json()) @@ -68,6 +69,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -76,7 +82,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[DocsSearchResponse | HTTPValidationError]: +) -> Response[DocsSearchResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -95,7 +101,7 @@ def sync_detailed( limit: int | Unset = 8, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[DocsSearchResponse | HTTPValidationError]: +) -> Response[DocsSearchResponse | HTTPValidationError | ServiceUnavailableError]: """Search documentation Search the Seclai documentation by content and return matching pages. `mode=keyword` matches page @@ -118,7 +124,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[DocsSearchResponse | HTTPValidationError] + Response[DocsSearchResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -146,7 +152,7 @@ def sync( limit: int | Unset = 8, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> DocsSearchResponse | HTTPValidationError | None: +) -> DocsSearchResponse | HTTPValidationError | ServiceUnavailableError | None: """Search documentation Search the Seclai documentation by content and return matching pages. `mode=keyword` matches page @@ -169,7 +175,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - DocsSearchResponse | HTTPValidationError + DocsSearchResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -192,7 +198,7 @@ async def asyncio_detailed( limit: int | Unset = 8, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[DocsSearchResponse | HTTPValidationError]: +) -> Response[DocsSearchResponse | HTTPValidationError | ServiceUnavailableError]: """Search documentation Search the Seclai documentation by content and return matching pages. `mode=keyword` matches page @@ -215,7 +221,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[DocsSearchResponse | HTTPValidationError] + Response[DocsSearchResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -241,7 +247,7 @@ async def asyncio( limit: int | Unset = 8, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> DocsSearchResponse | HTTPValidationError | None: +) -> DocsSearchResponse | HTTPValidationError | ServiceUnavailableError | None: """Search documentation Search the Seclai documentation by content and return matching pages. `mode=keyword` matches page @@ -264,7 +270,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - DocsSearchResponse | HTTPValidationError + DocsSearchResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/search/search_api_search_get.py b/seclai/_generated/api/search/search_api_search_get.py index 751dd09..6a1443c 100644 --- a/seclai/_generated/api/search/search_api_search_get.py +++ b/seclai/_generated/api/search/search_api_search_get.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.search_response import SearchResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -53,7 +54,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SearchResponse | None: +) -> HTTPValidationError | SearchResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = SearchResponse.from_dict(response.json()) @@ -64,6 +65,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -72,7 +78,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SearchResponse]: +) -> Response[HTTPValidationError | SearchResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -89,7 +95,7 @@ def sync_detailed( entity_type: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SearchResponse]: +) -> Response[HTTPValidationError | SearchResponse | ServiceUnavailableError]: """Search resources Search across all resource types in your account. Accepts a free-text keyword query or a UUID. @@ -111,7 +117,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SearchResponse] + Response[HTTPValidationError | SearchResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -137,7 +143,7 @@ def sync( entity_type: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SearchResponse | None: +) -> HTTPValidationError | SearchResponse | ServiceUnavailableError | None: """Search resources Search across all resource types in your account. Accepts a free-text keyword query or a UUID. @@ -159,7 +165,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SearchResponse + HTTPValidationError | SearchResponse | ServiceUnavailableError """ return sync_detailed( @@ -180,7 +186,7 @@ async def asyncio_detailed( entity_type: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SearchResponse]: +) -> Response[HTTPValidationError | SearchResponse | ServiceUnavailableError]: """Search resources Search across all resource types in your account. Accepts a free-text keyword query or a UUID. @@ -202,7 +208,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SearchResponse] + Response[HTTPValidationError | SearchResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -226,7 +232,7 @@ async def asyncio( entity_type: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SearchResponse | None: +) -> HTTPValidationError | SearchResponse | ServiceUnavailableError | None: """Search resources Search across all resource types in your account. Accepts a free-text keyword query or a UUID. @@ -248,7 +254,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SearchResponse + HTTPValidationError | SearchResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/solutions/add_conversation_turn_api_solutions_solution_id_conversations_post.py b/seclai/_generated/api/solutions/add_conversation_turn_api_solutions_solution_id_conversations_post.py index cf9f4a0..6e46931 100644 --- a/seclai/_generated/api/solutions/add_conversation_turn_api_solutions_solution_id_conversations_post.py +++ b/seclai/_generated/api/solutions/add_conversation_turn_api_solutions_solution_id_conversations_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.add_conversation_turn_request import AddConversationTurnRequest from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_conversation_response import SolutionConversationResponse from ...types import UNSET, Response, Unset @@ -44,7 +45,9 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionConversationResponse | None: +) -> ( + HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse | None +): if response.status_code == 201: response_201 = SolutionConversationResponse.from_dict(response.json()) @@ -55,6 +58,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +71,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionConversationResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +89,9 @@ def sync_detailed( body: AddConversationTurnRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionConversationResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse +]: """Add conversation turn Add a conversation turn to a solution's AI assistant history. @@ -98,7 +110,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionConversationResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse] """ kwargs = _get_kwargs( @@ -122,7 +134,9 @@ def sync( body: AddConversationTurnRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionConversationResponse | None: +) -> ( + HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse | None +): """Add conversation turn Add a conversation turn to a solution's AI assistant history. @@ -141,7 +155,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionConversationResponse + HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse """ return sync_detailed( @@ -160,7 +174,9 @@ async def asyncio_detailed( body: AddConversationTurnRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionConversationResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse +]: """Add conversation turn Add a conversation turn to a solution's AI assistant history. @@ -179,7 +195,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionConversationResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse] """ kwargs = _get_kwargs( @@ -201,7 +217,9 @@ async def asyncio( body: AddConversationTurnRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionConversationResponse | None: +) -> ( + HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse | None +): """Add conversation turn Add a conversation turn to a solution's AI assistant history. @@ -220,7 +238,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionConversationResponse + HTTPValidationError | ServiceUnavailableError | SolutionConversationResponse """ return ( diff --git a/seclai/_generated/api/solutions/ai_assistant_accept_api_solutions_solution_id_ai_assistant_conversation_id_accept_post.py b/seclai/_generated/api/solutions/ai_assistant_accept_api_solutions_solution_id_ai_assistant_conversation_id_accept_post.py index ba50d36..e9f83c0 100644 --- a/seclai/_generated/api/solutions/ai_assistant_accept_api_solutions_solution_id_ai_assistant_conversation_id_accept_post.py +++ b/seclai/_generated/api/solutions/ai_assistant_accept_api_solutions_solution_id_ai_assistant_conversation_id_accept_post.py @@ -10,6 +10,7 @@ from ...models.ai_assistant_accept_request import AiAssistantAcceptRequest from ...models.ai_assistant_accept_response import AiAssistantAcceptResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -46,7 +47,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiAssistantAcceptResponse | HTTPValidationError | None: +) -> AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AiAssistantAcceptResponse.from_dict(response.json()) @@ -57,6 +58,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -65,7 +71,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiAssistantAcceptResponse | HTTPValidationError]: +) -> Response[ + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -82,7 +90,9 @@ def sync_detailed( body: AiAssistantAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantAcceptResponse | HTTPValidationError]: +) -> Response[ + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError +]: """Accept plan Accept and execute a proposed plan generated by one of the AI assistant endpoints. @@ -103,7 +113,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantAcceptResponse | HTTPValidationError] + Response[AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -129,7 +139,7 @@ def sync( body: AiAssistantAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantAcceptResponse | HTTPValidationError | None: +) -> AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError | None: """Accept plan Accept and execute a proposed plan generated by one of the AI assistant endpoints. @@ -150,7 +160,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantAcceptResponse | HTTPValidationError + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -171,7 +181,9 @@ async def asyncio_detailed( body: AiAssistantAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantAcceptResponse | HTTPValidationError]: +) -> Response[ + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError +]: """Accept plan Accept and execute a proposed plan generated by one of the AI assistant endpoints. @@ -192,7 +204,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantAcceptResponse | HTTPValidationError] + Response[AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -216,7 +228,7 @@ async def asyncio( body: AiAssistantAcceptRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantAcceptResponse | HTTPValidationError | None: +) -> AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError | None: """Accept plan Accept and execute a proposed plan generated by one of the AI assistant endpoints. @@ -237,7 +249,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantAcceptResponse | HTTPValidationError + AiAssistantAcceptResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/solutions/ai_assistant_decline_api_solutions_solution_id_ai_assistant_conversation_id_decline_post.py b/seclai/_generated/api/solutions/ai_assistant_decline_api_solutions_solution_id_ai_assistant_conversation_id_decline_post.py index b2ce507..64b7bd8 100644 --- a/seclai/_generated/api/solutions/ai_assistant_decline_api_solutions_solution_id_ai_assistant_conversation_id_decline_post.py +++ b/seclai/_generated/api/solutions/ai_assistant_decline_api_solutions_solution_id_ai_assistant_conversation_id_decline_post.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -39,7 +40,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -73,7 +79,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Decline plan Decline a proposed plan generated by one of the AI assistant endpoints. @@ -92,7 +98,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -116,7 +122,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Decline plan Decline a proposed plan generated by one of the AI assistant endpoints. @@ -135,7 +141,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -154,7 +160,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Decline plan Decline a proposed plan generated by one of the AI assistant endpoints. @@ -173,7 +179,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -195,7 +201,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Decline plan Decline a proposed plan generated by one of the AI assistant endpoints. @@ -214,7 +220,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/solutions/ai_assistant_generate_api_solutions_solution_id_ai_assistant_generate_post.py b/seclai/_generated/api/solutions/ai_assistant_generate_api_solutions_solution_id_ai_assistant_generate_post.py index 1e6b98a..cea88db 100644 --- a/seclai/_generated/api/solutions/ai_assistant_generate_api_solutions_solution_id_ai_assistant_generate_post.py +++ b/seclai/_generated/api/solutions/ai_assistant_generate_api_solutions_solution_id_ai_assistant_generate_post.py @@ -10,6 +10,7 @@ from ...models.ai_assistant_generate_request import AiAssistantGenerateRequest from ...models.ai_assistant_generate_response import AiAssistantGenerateResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AiAssistantGenerateResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +87,9 @@ def sync_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate solution plan Generate a comprehensive solution management plan via the solution AI assistant. @@ -101,7 +111,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -125,7 +135,7 @@ def sync( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate solution plan Generate a comprehensive solution management plan via the solution AI assistant. @@ -147,7 +157,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -166,7 +176,9 @@ async def asyncio_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate solution plan Generate a comprehensive solution management plan via the solution AI assistant. @@ -188,7 +200,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -210,7 +222,7 @@ async def asyncio( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate solution plan Generate a comprehensive solution management plan via the solution AI assistant. @@ -232,7 +244,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/solutions/ai_assistant_knowledge_base_api_solutions_solution_id_ai_assistant_knowledge_base_post.py b/seclai/_generated/api/solutions/ai_assistant_knowledge_base_api_solutions_solution_id_ai_assistant_knowledge_base_post.py index 4bea15f..26e86d9 100644 --- a/seclai/_generated/api/solutions/ai_assistant_knowledge_base_api_solutions_solution_id_ai_assistant_knowledge_base_post.py +++ b/seclai/_generated/api/solutions/ai_assistant_knowledge_base_api_solutions_solution_id_ai_assistant_knowledge_base_post.py @@ -10,6 +10,7 @@ from ...models.ai_assistant_generate_request import AiAssistantGenerateRequest from ...models.ai_assistant_generate_response import AiAssistantGenerateResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AiAssistantGenerateResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +87,9 @@ def sync_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate knowledge base plan Generate a knowledge base plan via the KB AI assistant. @@ -99,7 +109,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -123,7 +133,7 @@ def sync( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate knowledge base plan Generate a knowledge base plan via the KB AI assistant. @@ -143,7 +153,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -162,7 +172,9 @@ async def asyncio_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate knowledge base plan Generate a knowledge base plan via the KB AI assistant. @@ -182,7 +194,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -204,7 +216,7 @@ async def asyncio( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate knowledge base plan Generate a knowledge base plan via the KB AI assistant. @@ -224,7 +236,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/solutions/ai_assistant_source_api_solutions_solution_id_ai_assistant_source_post.py b/seclai/_generated/api/solutions/ai_assistant_source_api_solutions_solution_id_ai_assistant_source_post.py index ed6201d..84f6da6 100644 --- a/seclai/_generated/api/solutions/ai_assistant_source_api_solutions_solution_id_ai_assistant_source_post.py +++ b/seclai/_generated/api/solutions/ai_assistant_source_api_solutions_solution_id_ai_assistant_source_post.py @@ -10,6 +10,7 @@ from ...models.ai_assistant_generate_request import AiAssistantGenerateRequest from ...models.ai_assistant_generate_response import AiAssistantGenerateResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = AiAssistantGenerateResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +87,9 @@ def sync_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate source plan Generate a content source plan via the source AI assistant. @@ -99,7 +109,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -123,7 +133,7 @@ def sync( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate source plan Generate a content source plan via the source AI assistant. @@ -143,7 +153,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -162,7 +172,9 @@ async def asyncio_detailed( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[AiAssistantGenerateResponse | HTTPValidationError]: +) -> Response[ + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError +]: """Generate source plan Generate a content source plan via the source AI assistant. @@ -182,7 +194,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[AiAssistantGenerateResponse | HTTPValidationError] + Response[AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -204,7 +216,7 @@ async def asyncio( body: AiAssistantGenerateRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> AiAssistantGenerateResponse | HTTPValidationError | None: +) -> AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError | None: """Generate source plan Generate a content source plan via the source AI assistant. @@ -224,7 +236,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - AiAssistantGenerateResponse | HTTPValidationError + AiAssistantGenerateResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/solutions/create_solution_api_solutions_post.py b/seclai/_generated/api/solutions/create_solution_api_solutions_post.py index cd7a18d..fd0bf24 100644 --- a/seclai/_generated/api/solutions/create_solution_api_solutions_post.py +++ b/seclai/_generated/api/solutions/create_solution_api_solutions_post.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.create_solution_request import CreateSolutionRequest from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_response import SolutionResponse from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: if response.status_code == 201: response_201 = SolutionResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +80,7 @@ def sync_detailed( body: CreateSolutionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Create a solution Create a new solution for the caller's account. @@ -92,7 +98,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -114,7 +120,7 @@ def sync( body: CreateSolutionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Create a solution Create a new solution for the caller's account. @@ -132,7 +138,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return sync_detailed( @@ -149,7 +155,7 @@ async def asyncio_detailed( body: CreateSolutionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Create a solution Create a new solution for the caller's account. @@ -167,7 +173,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -187,7 +193,7 @@ async def asyncio( body: CreateSolutionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Create a solution Create a new solution for the caller's account. @@ -205,7 +211,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return ( diff --git a/seclai/_generated/api/solutions/delete_solution_api_solutions_solution_id_delete.py b/seclai/_generated/api/solutions/delete_solution_api_solutions_solution_id_delete.py index d5142a9..1c366af 100644 --- a/seclai/_generated/api/solutions/delete_solution_api_solutions_solution_id_delete.py +++ b/seclai/_generated/api/solutions/delete_solution_api_solutions_solution_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete a solution Delete a solution by its ID. @@ -88,7 +94,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -110,7 +116,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete a solution Delete a solution by its ID. @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete a solution Delete a solution by its ID. @@ -163,7 +169,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete a solution Delete a solution by its ID. @@ -201,7 +207,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/solutions/get_solution_api_solutions_solution_id_get.py b/seclai/_generated/api/solutions/get_solution_api_solutions_solution_id_get.py index ae5c7f1..c727545 100644 --- a/seclai/_generated/api/solutions/get_solution_api_solutions_solution_id_get.py +++ b/seclai/_generated/api/solutions/get_solution_api_solutions_solution_id_get.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_response import SolutionResponse from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: if response.status_code == 200: response_200 = SolutionResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Get a solution Retrieve a solution by its ID, including all linked agents, knowledge bases, and source connections. @@ -89,7 +95,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -111,7 +117,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Get a solution Retrieve a solution by its ID, including all linked agents, knowledge bases, and source connections. @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Get a solution Retrieve a solution by its ID, including all linked agents, knowledge bases, and source connections. @@ -162,7 +168,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -182,7 +188,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Get a solution Retrieve a solution by its ID, including all linked agents, knowledge bases, and source connections. @@ -199,7 +205,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return ( diff --git a/seclai/_generated/api/solutions/link_agents_api_solutions_solution_id_agents_post.py b/seclai/_generated/api/solutions/link_agents_api_solutions_solution_id_agents_post.py index 6bc5316..de0280d 100644 --- a/seclai/_generated/api/solutions/link_agents_api_solutions_solution_id_agents_post.py +++ b/seclai/_generated/api/solutions/link_agents_api_solutions_solution_id_agents_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.link_resources_request import LinkResourcesRequest +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_response import SolutionResponse from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: if response.status_code == 200: response_200 = SolutionResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Link agents Link one or more agents to a solution by their IDs. @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -122,7 +128,7 @@ def sync( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Link agents Link one or more agents to a solution by their IDs. @@ -141,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return sync_detailed( @@ -160,7 +166,7 @@ async def asyncio_detailed( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Link agents Link one or more agents to a solution by their IDs. @@ -179,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -201,7 +207,7 @@ async def asyncio( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Link agents Link one or more agents to a solution by their IDs. @@ -220,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return ( diff --git a/seclai/_generated/api/solutions/link_knowledge_bases_api_solutions_solution_id_knowledge_bases_post.py b/seclai/_generated/api/solutions/link_knowledge_bases_api_solutions_solution_id_knowledge_bases_post.py index 2a21e45..c308651 100644 --- a/seclai/_generated/api/solutions/link_knowledge_bases_api_solutions_solution_id_knowledge_bases_post.py +++ b/seclai/_generated/api/solutions/link_knowledge_bases_api_solutions_solution_id_knowledge_bases_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.link_resources_request import LinkResourcesRequest +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_response import SolutionResponse from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: if response.status_code == 200: response_200 = SolutionResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Link knowledge bases Link one or more knowledge bases to a solution by their IDs. @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -122,7 +128,7 @@ def sync( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Link knowledge bases Link one or more knowledge bases to a solution by their IDs. @@ -141,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return sync_detailed( @@ -160,7 +166,7 @@ async def asyncio_detailed( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Link knowledge bases Link one or more knowledge bases to a solution by their IDs. @@ -179,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -201,7 +207,7 @@ async def asyncio( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Link knowledge bases Link one or more knowledge bases to a solution by their IDs. @@ -220,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return ( diff --git a/seclai/_generated/api/solutions/link_source_connections_api_solutions_solution_id_source_connections_post.py b/seclai/_generated/api/solutions/link_source_connections_api_solutions_solution_id_source_connections_post.py index 469dc2c..9662ba3 100644 --- a/seclai/_generated/api/solutions/link_source_connections_api_solutions_solution_id_source_connections_post.py +++ b/seclai/_generated/api/solutions/link_source_connections_api_solutions_solution_id_source_connections_post.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.link_resources_request import LinkResourcesRequest +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_response import SolutionResponse from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: if response.status_code == 200: response_200 = SolutionResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Link source connections Link one or more source connections to a solution by their IDs. @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -122,7 +128,7 @@ def sync( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Link source connections Link one or more source connections to a solution by their IDs. @@ -141,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return sync_detailed( @@ -160,7 +166,7 @@ async def asyncio_detailed( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Link source connections Link one or more source connections to a solution by their IDs. @@ -179,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -201,7 +207,7 @@ async def asyncio( body: LinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Link source connections Link one or more source connections to a solution by their IDs. @@ -220,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return ( diff --git a/seclai/_generated/api/solutions/list_conversations_api_solutions_solution_id_conversations_get.py b/seclai/_generated/api/solutions/list_conversations_api_solutions_solution_id_conversations_get.py index 113c752..25e419f 100644 --- a/seclai/_generated/api/solutions/list_conversations_api_solutions_solution_id_conversations_get.py +++ b/seclai/_generated/api/solutions/list_conversations_api_solutions_solution_id_conversations_get.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_conversation_response import SolutionConversationResponse from ...types import UNSET, Response, Unset @@ -38,7 +39,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | list[SolutionConversationResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[SolutionConversationResponse] + | None +): if response.status_code == 200: response_200 = [] _response_200 = response.json() @@ -56,6 +62,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -64,7 +75,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | list[SolutionConversationResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[SolutionConversationResponse] +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +92,9 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[SolutionConversationResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[SolutionConversationResponse] +]: """List conversations List AI assistant conversation history for a solution. @@ -97,7 +112,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[SolutionConversationResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[SolutionConversationResponse]] """ kwargs = _get_kwargs( @@ -119,7 +134,12 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[SolutionConversationResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[SolutionConversationResponse] + | None +): """List conversations List AI assistant conversation history for a solution. @@ -137,7 +157,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[SolutionConversationResponse] + HTTPValidationError | ServiceUnavailableError | list[SolutionConversationResponse] """ return sync_detailed( @@ -154,7 +174,9 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | list[SolutionConversationResponse]]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | list[SolutionConversationResponse] +]: """List conversations List AI assistant conversation history for a solution. @@ -172,7 +194,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | list[SolutionConversationResponse]] + Response[HTTPValidationError | ServiceUnavailableError | list[SolutionConversationResponse]] """ kwargs = _get_kwargs( @@ -192,7 +214,12 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | list[SolutionConversationResponse] | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | list[SolutionConversationResponse] + | None +): """List conversations List AI assistant conversation history for a solution. @@ -210,7 +237,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | list[SolutionConversationResponse] + HTTPValidationError | ServiceUnavailableError | list[SolutionConversationResponse] """ return ( diff --git a/seclai/_generated/api/solutions/list_solutions_api_solutions_get.py b/seclai/_generated/api/solutions/list_solutions_api_solutions_get.py index da2730f..f392631 100644 --- a/seclai/_generated/api/solutions/list_solutions_api_solutions_get.py +++ b/seclai/_generated/api/solutions/list_solutions_api_solutions_get.py @@ -7,6 +7,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_list_response import SolutionListResponse from ...types import UNSET, Response, Unset @@ -59,7 +60,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionListResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionListResponse | None: if response.status_code == 200: response_200 = SolutionListResponse.from_dict(response.json()) @@ -70,6 +71,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -78,7 +84,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionListResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionListResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -97,7 +103,7 @@ def sync_detailed( search: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionListResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionListResponse]: """List solutions List solutions for your account. @@ -127,7 +133,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionListResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionListResponse] """ kwargs = _get_kwargs( @@ -157,7 +163,7 @@ def sync( search: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionListResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionListResponse | None: """List solutions List solutions for your account. @@ -187,7 +193,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionListResponse + HTTPValidationError | ServiceUnavailableError | SolutionListResponse """ return sync_detailed( @@ -212,7 +218,7 @@ async def asyncio_detailed( search: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionListResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionListResponse]: """List solutions List solutions for your account. @@ -242,7 +248,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionListResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionListResponse] """ kwargs = _get_kwargs( @@ -270,7 +276,7 @@ async def asyncio( search: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionListResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionListResponse | None: """List solutions List solutions for your account. @@ -300,7 +306,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionListResponse + HTTPValidationError | ServiceUnavailableError | SolutionListResponse """ return ( diff --git a/seclai/_generated/api/solutions/mark_conversation_turn_api_solutions_solution_id_conversations_conversation_id_patch.py b/seclai/_generated/api/solutions/mark_conversation_turn_api_solutions_solution_id_conversations_conversation_id_patch.py index 36c5d6c..bc66f53 100644 --- a/seclai/_generated/api/solutions/mark_conversation_turn_api_solutions_solution_id_conversations_conversation_id_patch.py +++ b/seclai/_generated/api/solutions/mark_conversation_turn_api_solutions_solution_id_conversations_conversation_id_patch.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.mark_conversation_turn_request import MarkConversationTurnRequest +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -45,7 +46,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -80,7 +86,7 @@ def sync_detailed( body: MarkConversationTurnRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Mark conversation turn Mark a conversation turn as accepted or declined. @@ -100,7 +106,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -126,7 +132,7 @@ def sync( body: MarkConversationTurnRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Mark conversation turn Mark a conversation turn as accepted or declined. @@ -146,7 +152,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -167,7 +173,7 @@ async def asyncio_detailed( body: MarkConversationTurnRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Mark conversation turn Mark a conversation turn as accepted or declined. @@ -187,7 +193,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -211,7 +217,7 @@ async def asyncio( body: MarkConversationTurnRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Mark conversation turn Mark a conversation turn as accepted or declined. @@ -231,7 +237,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/solutions/unlink_agents_api_solutions_solution_id_agents_delete.py b/seclai/_generated/api/solutions/unlink_agents_api_solutions_solution_id_agents_delete.py index 39c4757..a9095e3 100644 --- a/seclai/_generated/api/solutions/unlink_agents_api_solutions_solution_id_agents_delete.py +++ b/seclai/_generated/api/solutions/unlink_agents_api_solutions_solution_id_agents_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_response import SolutionResponse from ...models.unlink_resources_request import UnlinkResourcesRequest from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: if response.status_code == 200: response_200 = SolutionResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Unlink agents Unlink one or more agents from a solution by their IDs. @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -122,7 +128,7 @@ def sync( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Unlink agents Unlink one or more agents from a solution by their IDs. @@ -141,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return sync_detailed( @@ -160,7 +166,7 @@ async def asyncio_detailed( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Unlink agents Unlink one or more agents from a solution by their IDs. @@ -179,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -201,7 +207,7 @@ async def asyncio( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Unlink agents Unlink one or more agents from a solution by their IDs. @@ -220,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return ( diff --git a/seclai/_generated/api/solutions/unlink_knowledge_bases_api_solutions_solution_id_knowledge_bases_delete.py b/seclai/_generated/api/solutions/unlink_knowledge_bases_api_solutions_solution_id_knowledge_bases_delete.py index 00b5690..1f19ffc 100644 --- a/seclai/_generated/api/solutions/unlink_knowledge_bases_api_solutions_solution_id_knowledge_bases_delete.py +++ b/seclai/_generated/api/solutions/unlink_knowledge_bases_api_solutions_solution_id_knowledge_bases_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_response import SolutionResponse from ...models.unlink_resources_request import UnlinkResourcesRequest from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: if response.status_code == 200: response_200 = SolutionResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Unlink knowledge bases Unlink one or more knowledge bases from a solution by their IDs. @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -122,7 +128,7 @@ def sync( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Unlink knowledge bases Unlink one or more knowledge bases from a solution by their IDs. @@ -141,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return sync_detailed( @@ -160,7 +166,7 @@ async def asyncio_detailed( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Unlink knowledge bases Unlink one or more knowledge bases from a solution by their IDs. @@ -179,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -201,7 +207,7 @@ async def asyncio( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Unlink knowledge bases Unlink one or more knowledge bases from a solution by their IDs. @@ -220,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return ( diff --git a/seclai/_generated/api/solutions/unlink_source_connections_api_solutions_solution_id_source_connections_delete.py b/seclai/_generated/api/solutions/unlink_source_connections_api_solutions_solution_id_source_connections_delete.py index da920c1..4d5ac2e 100644 --- a/seclai/_generated/api/solutions/unlink_source_connections_api_solutions_solution_id_source_connections_delete.py +++ b/seclai/_generated/api/solutions/unlink_source_connections_api_solutions_solution_id_source_connections_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_response import SolutionResponse from ...models.unlink_resources_request import UnlinkResourcesRequest from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: if response.status_code == 200: response_200 = SolutionResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Unlink source connections Unlink one or more source connections from a solution by their IDs. @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -122,7 +128,7 @@ def sync( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Unlink source connections Unlink one or more source connections from a solution by their IDs. @@ -141,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return sync_detailed( @@ -160,7 +166,7 @@ async def asyncio_detailed( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Unlink source connections Unlink one or more source connections from a solution by their IDs. @@ -179,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -201,7 +207,7 @@ async def asyncio( body: UnlinkResourcesRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Unlink source connections Unlink one or more source connections from a solution by their IDs. @@ -220,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return ( diff --git a/seclai/_generated/api/solutions/update_solution_api_solutions_solution_id_patch.py b/seclai/_generated/api/solutions/update_solution_api_solutions_solution_id_patch.py index 3d7f917..4904212 100644 --- a/seclai/_generated/api/solutions/update_solution_api_solutions_solution_id_patch.py +++ b/seclai/_generated/api/solutions/update_solution_api_solutions_solution_id_patch.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.solution_response import SolutionResponse from ...models.update_solution_request import UpdateSolutionRequest from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: if response.status_code == 200: response_200 = SolutionResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: UpdateSolutionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Update a solution Update an existing solution's name or description. @@ -97,7 +103,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -121,7 +127,7 @@ def sync( body: UpdateSolutionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Update a solution Update an existing solution's name or description. @@ -139,7 +145,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return sync_detailed( @@ -158,7 +164,7 @@ async def asyncio_detailed( body: UpdateSolutionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SolutionResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse]: """Update a solution Update an existing solution's name or description. @@ -176,7 +182,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SolutionResponse] + Response[HTTPValidationError | ServiceUnavailableError | SolutionResponse] """ kwargs = _get_kwargs( @@ -198,7 +204,7 @@ async def asyncio( body: UpdateSolutionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SolutionResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SolutionResponse | None: """Update a solution Update an existing solution's name or description. @@ -216,7 +222,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SolutionResponse + HTTPValidationError | ServiceUnavailableError | SolutionResponse """ return ( diff --git a/seclai/_generated/api/source_exports/cancel_source_export_api_sources_source_connection_id_exports_export_id_cancel_post.py b/seclai/_generated/api/source_exports/cancel_source_export_api_sources_source_connection_id_exports_export_id_cancel_post.py index c5d82e7..35499d7 100644 --- a/seclai/_generated/api/source_exports/cancel_source_export_api_sources_source_connection_id_exports_export_id_cancel_post.py +++ b/seclai/_generated/api/source_exports/cancel_source_export_api_sources_source_connection_id_exports_export_id_cancel_post.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote from uuid import UUID @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.export_response import ExportResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,17 +41,26 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ExportResponse | HTTPValidationError | None: +) -> Any | ExportResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ExportResponse.from_dict(response.json()) return response_200 + if response.status_code == 403: + response_403 = cast(Any, None) + return response_403 + if response.status_code == 422: response_422 = HTTPValidationError.from_dict(response.json()) return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ExportResponse | HTTPValidationError]: +) -> Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -75,11 +85,13 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExportResponse | HTTPValidationError]: +) -> Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError]: """Cancel export Cancel a pending or running export. The background task will stop at the next chunk boundary. - Completed, failed, expired, or already-cancelled exports cannot be cancelled. + Completed, failed, expired, or already-cancelled exports cannot be cancelled. On an organization + account, a key bound to a user must belong to an owner or administrator; a viewer's key is refused + with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -92,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExportResponse | HTTPValidationError] + Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -116,11 +128,13 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExportResponse | HTTPValidationError | None: +) -> Any | ExportResponse | HTTPValidationError | ServiceUnavailableError | None: """Cancel export Cancel a pending or running export. The background task will stop at the next chunk boundary. - Completed, failed, expired, or already-cancelled exports cannot be cancelled. + Completed, failed, expired, or already-cancelled exports cannot be cancelled. On an organization + account, a key bound to a user must belong to an owner or administrator; a viewer's key is refused + with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -133,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExportResponse | HTTPValidationError + Any | ExportResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -152,11 +166,13 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExportResponse | HTTPValidationError]: +) -> Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError]: """Cancel export Cancel a pending or running export. The background task will stop at the next chunk boundary. - Completed, failed, expired, or already-cancelled exports cannot be cancelled. + Completed, failed, expired, or already-cancelled exports cannot be cancelled. On an organization + account, a key bound to a user must belong to an owner or administrator; a viewer's key is refused + with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -169,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExportResponse | HTTPValidationError] + Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -191,11 +207,13 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExportResponse | HTTPValidationError | None: +) -> Any | ExportResponse | HTTPValidationError | ServiceUnavailableError | None: """Cancel export Cancel a pending or running export. The background task will stop at the next chunk boundary. - Completed, failed, expired, or already-cancelled exports cannot be cancelled. + Completed, failed, expired, or already-cancelled exports cannot be cancelled. On an organization + account, a key bound to a user must belong to an owner or administrator; a viewer's key is refused + with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -208,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExportResponse | HTTPValidationError + Any | ExportResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/source_exports/create_source_export_api_sources_source_connection_id_exports_post.py b/seclai/_generated/api/source_exports/create_source_export_api_sources_source_connection_id_exports_post.py index 09899b1..45929f5 100644 --- a/seclai/_generated/api/source_exports/create_source_export_api_sources_source_connection_id_exports_post.py +++ b/seclai/_generated/api/source_exports/create_source_export_api_sources_source_connection_id_exports_post.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote from uuid import UUID @@ -10,6 +10,7 @@ from ...models.create_export_request import CreateExportRequest from ...models.export_response import ExportResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,17 +45,26 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ExportResponse | HTTPValidationError | None: +) -> Any | ExportResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 202: response_202 = ExportResponse.from_dict(response.json()) return response_202 + if response.status_code == 403: + response_403 = cast(Any, None) + return response_403 + if response.status_code == 422: response_422 = HTTPValidationError.from_dict(response.json()) return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +73,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ExportResponse | HTTPValidationError]: +) -> Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,11 +89,13 @@ def sync_detailed( body: CreateExportRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExportResponse | HTTPValidationError]: +) -> Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError]: """Create export Start an asynchronous export job. Poll GET .../exports/{export_id} until status becomes completed, - then use /download to retrieve the file. + then use /download to retrieve the file. On an organization account, a key bound to a user must + belong to an owner or administrator; a viewer's key is refused with 403 `permission_denied`. + Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -96,7 +108,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExportResponse | HTTPValidationError] + Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -120,11 +132,13 @@ def sync( body: CreateExportRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExportResponse | HTTPValidationError | None: +) -> Any | ExportResponse | HTTPValidationError | ServiceUnavailableError | None: """Create export Start an asynchronous export job. Poll GET .../exports/{export_id} until status becomes completed, - then use /download to retrieve the file. + then use /download to retrieve the file. On an organization account, a key bound to a user must + belong to an owner or administrator; a viewer's key is refused with 403 `permission_denied`. + Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -137,7 +151,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExportResponse | HTTPValidationError + Any | ExportResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -156,11 +170,13 @@ async def asyncio_detailed( body: CreateExportRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExportResponse | HTTPValidationError]: +) -> Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError]: """Create export Start an asynchronous export job. Poll GET .../exports/{export_id} until status becomes completed, - then use /download to retrieve the file. + then use /download to retrieve the file. On an organization account, a key bound to a user must + belong to an owner or administrator; a viewer's key is refused with 403 `permission_denied`. + Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -173,7 +189,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExportResponse | HTTPValidationError] + Response[Any | ExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -195,11 +211,13 @@ async def asyncio( body: CreateExportRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExportResponse | HTTPValidationError | None: +) -> Any | ExportResponse | HTTPValidationError | ServiceUnavailableError | None: """Create export Start an asynchronous export job. Poll GET .../exports/{export_id} until status becomes completed, - then use /download to retrieve the file. + then use /download to retrieve the file. On an organization account, a key bound to a user must + belong to an owner or administrator; a viewer's key is refused with 403 `permission_denied`. + Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -212,7 +230,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExportResponse | HTTPValidationError + Any | ExportResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/source_exports/delete_source_export_api_sources_source_connection_id_exports_export_id_delete.py b/seclai/_generated/api/source_exports/delete_source_export_api_sources_source_connection_id_exports_export_id_delete.py index 352099a..eb740de 100644 --- a/seclai/_generated/api/source_exports/delete_source_export_api_sources_source_connection_id_exports_export_id_delete.py +++ b/seclai/_generated/api/source_exports/delete_source_export_api_sources_source_connection_id_exports_export_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -39,16 +40,25 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 + if response.status_code == 403: + response_403 = cast(Any, None) + return response_403 + if response.status_code == 422: response_422 = HTTPValidationError.from_dict(response.json()) return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +67,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -73,11 +83,13 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete export Delete an export job and remove the associated file from S3. This is a soft-delete: the database - record is retained for audit purposes but the backing file is permanently removed. + record is retained for audit purposes but the backing file is permanently removed. On an + organization account, a key bound to a user must belong to an owner or administrator; a viewer's key + is refused with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -90,7 +102,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,11 +126,13 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete export Delete an export job and remove the associated file from S3. This is a soft-delete: the database - record is retained for audit purposes but the backing file is permanently removed. + record is retained for audit purposes but the backing file is permanently removed. On an + organization account, a key bound to a user must belong to an owner or administrator; a viewer's key + is refused with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -131,7 +145,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -150,11 +164,13 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete export Delete an export job and remove the associated file from S3. This is a soft-delete: the database - record is retained for audit purposes but the backing file is permanently removed. + record is retained for audit purposes but the backing file is permanently removed. On an + organization account, a key bound to a user must belong to an owner or administrator; a viewer's key + is refused with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -167,7 +183,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -189,11 +205,13 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete export Delete an export job and remove the associated file from S3. This is a soft-delete: the database - record is retained for audit purposes but the backing file is permanently removed. + record is retained for audit purposes but the backing file is permanently removed. On an + organization account, a key bound to a user must belong to an owner or administrator; a viewer's key + is refused with 403 `permission_denied`. Personal accounts and account-scoped keys are unaffected. Args: source_connection_id (UUID): @@ -206,7 +224,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/source_exports/download_source_export_api_sources_source_connection_id_exports_export_id_download_get.py b/seclai/_generated/api/source_exports/download_source_export_api_sources_source_connection_id_exports_export_id_download_get.py index 25b8df9..7891626 100644 --- a/seclai/_generated/api/source_exports/download_source_export_api_sources_source_connection_id_exports_export_id_download_get.py +++ b/seclai/_generated/api/source_exports/download_source_export_api_sources_source_connection_id_exports_export_id_download_get.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -39,7 +40,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = response.json() return response_200 @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -73,7 +79,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Download export Stream the completed export file. Returns the file content with appropriate Content-Type and @@ -91,7 +97,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -115,7 +121,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Download export Stream the completed export file. Returns the file content with appropriate Content-Type and @@ -133,7 +139,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -152,7 +158,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Download export Stream the completed export file. Returns the file content with appropriate Content-Type and @@ -170,7 +176,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -192,7 +198,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Download export Stream the completed export file. Returns the file content with appropriate Content-Type and @@ -210,7 +216,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/source_exports/estimate_source_export_api_sources_source_connection_id_exports_estimate_post.py b/seclai/_generated/api/source_exports/estimate_source_export_api_sources_source_connection_id_exports_estimate_post.py index 112d656..e118b30 100644 --- a/seclai/_generated/api/source_exports/estimate_source_export_api_sources_source_connection_id_exports_estimate_post.py +++ b/seclai/_generated/api/source_exports/estimate_source_export_api_sources_source_connection_id_exports_estimate_post.py @@ -10,6 +10,7 @@ from ...models.estimate_export_request import EstimateExportRequest from ...models.estimate_export_response import EstimateExportResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> EstimateExportResponse | HTTPValidationError | None: +) -> EstimateExportResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = EstimateExportResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[EstimateExportResponse | HTTPValidationError]: +) -> Response[EstimateExportResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: EstimateExportRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EstimateExportResponse | HTTPValidationError]: +) -> Response[EstimateExportResponse | HTTPValidationError | ServiceUnavailableError]: """Estimate export size Return an order-of-magnitude size estimate (in bytes) for an export without creating a job. Use @@ -96,7 +102,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EstimateExportResponse | HTTPValidationError] + Response[EstimateExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -120,7 +126,7 @@ def sync( body: EstimateExportRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EstimateExportResponse | HTTPValidationError | None: +) -> EstimateExportResponse | HTTPValidationError | ServiceUnavailableError | None: """Estimate export size Return an order-of-magnitude size estimate (in bytes) for an export without creating a job. Use @@ -137,7 +143,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EstimateExportResponse | HTTPValidationError + EstimateExportResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -156,7 +162,7 @@ async def asyncio_detailed( body: EstimateExportRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[EstimateExportResponse | HTTPValidationError]: +) -> Response[EstimateExportResponse | HTTPValidationError | ServiceUnavailableError]: """Estimate export size Return an order-of-magnitude size estimate (in bytes) for an export without creating a job. Use @@ -173,7 +179,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[EstimateExportResponse | HTTPValidationError] + Response[EstimateExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -195,7 +201,7 @@ async def asyncio( body: EstimateExportRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> EstimateExportResponse | HTTPValidationError | None: +) -> EstimateExportResponse | HTTPValidationError | ServiceUnavailableError | None: """Estimate export size Return an order-of-magnitude size estimate (in bytes) for an export without creating a job. Use @@ -212,7 +218,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - EstimateExportResponse | HTTPValidationError + EstimateExportResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/source_exports/get_source_export_api_sources_source_connection_id_exports_export_id_get.py b/seclai/_generated/api/source_exports/get_source_export_api_sources_source_connection_id_exports_export_id_get.py index d1f1b2f..6fe1c8d 100644 --- a/seclai/_generated/api/source_exports/get_source_export_api_sources_source_connection_id_exports_export_id_get.py +++ b/seclai/_generated/api/source_exports/get_source_export_api_sources_source_connection_id_exports_export_id_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.export_response import ExportResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ExportResponse | HTTPValidationError | None: +) -> ExportResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ExportResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ExportResponse | HTTPValidationError]: +) -> Response[ExportResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -75,7 +81,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExportResponse | HTTPValidationError]: +) -> Response[ExportResponse | HTTPValidationError | ServiceUnavailableError]: """Get export status Retrieve the current status and progress of an export job. Returns all metadata including progress @@ -92,7 +98,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExportResponse | HTTPValidationError] + Response[ExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -116,7 +122,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExportResponse | HTTPValidationError | None: +) -> ExportResponse | HTTPValidationError | ServiceUnavailableError | None: """Get export status Retrieve the current status and progress of an export job. Returns all metadata including progress @@ -133,7 +139,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExportResponse | HTTPValidationError + ExportResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -152,7 +158,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExportResponse | HTTPValidationError]: +) -> Response[ExportResponse | HTTPValidationError | ServiceUnavailableError]: """Get export status Retrieve the current status and progress of an export job. Returns all metadata including progress @@ -169,7 +175,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExportResponse | HTTPValidationError] + Response[ExportResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -191,7 +197,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExportResponse | HTTPValidationError | None: +) -> ExportResponse | HTTPValidationError | ServiceUnavailableError | None: """Get export status Retrieve the current status and progress of an export job. Returns all metadata including progress @@ -208,7 +214,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExportResponse | HTTPValidationError + ExportResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/source_exports/list_source_exports_api_sources_source_connection_id_exports_get.py b/seclai/_generated/api/source_exports/list_source_exports_api_sources_source_connection_id_exports_get.py index 76434e6..50a333e 100644 --- a/seclai/_generated/api/source_exports/list_source_exports_api_sources_source_connection_id_exports_get.py +++ b/seclai/_generated/api/source_exports/list_source_exports_api_sources_source_connection_id_exports_get.py @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.export_list_response import ExportListResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -49,7 +50,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ExportListResponse | HTTPValidationError | None: +) -> ExportListResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ExportListResponse.from_dict(response.json()) @@ -60,6 +61,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -68,7 +74,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ExportListResponse | HTTPValidationError]: +) -> Response[ExportListResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -85,7 +91,7 @@ def sync_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExportListResponse | HTTPValidationError]: +) -> Response[ExportListResponse | HTTPValidationError | ServiceUnavailableError]: """List exports List all export jobs for a source connection, ordered newest first. Supports pagination via @@ -104,7 +110,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExportListResponse | HTTPValidationError] + Response[ExportListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -130,7 +136,7 @@ def sync( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExportListResponse | HTTPValidationError | None: +) -> ExportListResponse | HTTPValidationError | ServiceUnavailableError | None: """List exports List all export jobs for a source connection, ordered newest first. Supports pagination via @@ -149,7 +155,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExportListResponse | HTTPValidationError + ExportListResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -170,7 +176,7 @@ async def asyncio_detailed( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ExportListResponse | HTTPValidationError]: +) -> Response[ExportListResponse | HTTPValidationError | ServiceUnavailableError]: """List exports List all export jobs for a source connection, ordered newest first. Supports pagination via @@ -189,7 +195,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ExportListResponse | HTTPValidationError] + Response[ExportListResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -213,7 +219,7 @@ async def asyncio( limit: int | Unset = 20, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ExportListResponse | HTTPValidationError | None: +) -> ExportListResponse | HTTPValidationError | ServiceUnavailableError | None: """List exports List all export jobs for a source connection, ordered newest first. Supports pagination via @@ -232,7 +238,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ExportListResponse | HTTPValidationError + ExportListResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/sources/cancel_source_embedding_migration_api_sources_source_connection_id_embedding_migration_cancel_post.py b/seclai/_generated/api/sources/cancel_source_embedding_migration_api_sources_source_connection_id_embedding_migration_cancel_post.py index 7610c7f..a80a0e8 100644 --- a/seclai/_generated/api/sources/cancel_source_embedding_migration_api_sources_source_connection_id_embedding_migration_cancel_post.py +++ b/seclai/_generated/api/sources/cancel_source_embedding_migration_api_sources_source_connection_id_embedding_migration_cancel_post.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.source_embedding_migration_response import ( SourceEmbeddingMigrationResponse, ) @@ -40,7 +41,12 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SourceEmbeddingMigrationResponse | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | SourceEmbeddingMigrationResponse + | None +): if response.status_code == 200: response_200 = SourceEmbeddingMigrationResponse.from_dict(response.json()) @@ -51,6 +57,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +70,9 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SourceEmbeddingMigrationResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,12 +87,16 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SourceEmbeddingMigrationResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse +]: """Cancel Source Embedding Migration Cancel an active embedding migration for a custom-index source. - Only pending, running, or switching migrations can be cancelled. + Only pending and running migrations can be cancelled. A migration that has reached the switching + phase is committing its switch-over in a single transaction, so there is no half-applied state to + back out of and cancel is refused. Args: source_connection_id (UUID): @@ -91,7 +108,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SourceEmbeddingMigrationResponse] + Response[HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse] """ kwargs = _get_kwargs( @@ -113,12 +130,19 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SourceEmbeddingMigrationResponse | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | SourceEmbeddingMigrationResponse + | None +): """Cancel Source Embedding Migration Cancel an active embedding migration for a custom-index source. - Only pending, running, or switching migrations can be cancelled. + Only pending and running migrations can be cancelled. A migration that has reached the switching + phase is committing its switch-over in a single transaction, so there is no half-applied state to + back out of and cancel is refused. Args: source_connection_id (UUID): @@ -130,7 +154,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SourceEmbeddingMigrationResponse + HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse """ return sync_detailed( @@ -147,12 +171,16 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SourceEmbeddingMigrationResponse]: +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse +]: """Cancel Source Embedding Migration Cancel an active embedding migration for a custom-index source. - Only pending, running, or switching migrations can be cancelled. + Only pending and running migrations can be cancelled. A migration that has reached the switching + phase is committing its switch-over in a single transaction, so there is no half-applied state to + back out of and cancel is refused. Args: source_connection_id (UUID): @@ -164,7 +192,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SourceEmbeddingMigrationResponse] + Response[HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse] """ kwargs = _get_kwargs( @@ -184,12 +212,19 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SourceEmbeddingMigrationResponse | None: +) -> ( + HTTPValidationError + | ServiceUnavailableError + | SourceEmbeddingMigrationResponse + | None +): """Cancel Source Embedding Migration Cancel an active embedding migration for a custom-index source. - Only pending, running, or switching migrations can be cancelled. + Only pending and running migrations can be cancelled. A migration that has reached the switching + phase is committing its switch-over in a single transaction, so there is no half-applied state to + back out of and cancel is refused. Args: source_connection_id (UUID): @@ -201,7 +236,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SourceEmbeddingMigrationResponse + HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse """ return ( diff --git a/seclai/_generated/api/sources/create_source_api_sources_post.py b/seclai/_generated/api/sources/create_source_api_sources_post.py index 0b6b70d..79a6cd6 100644 --- a/seclai/_generated/api/sources/create_source_api_sources_post.py +++ b/seclai/_generated/api/sources/create_source_api_sources_post.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.create_source_body import CreateSourceBody from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.source_response import SourceResponse from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | SourceResponse | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | SourceResponse | None: if response.status_code == 201: response_201 = SourceResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError | SourceResponse]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError | SourceResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -78,7 +84,7 @@ def sync_detailed( body: CreateSourceBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | SourceResponse]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError | SourceResponse]: """Create Source Create a new content source. @@ -102,7 +108,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | SourceResponse] + Response[Any | HTTPValidationError | ServiceUnavailableError | SourceResponse] """ kwargs = _get_kwargs( @@ -124,7 +130,7 @@ def sync( body: CreateSourceBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | SourceResponse | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | SourceResponse | None: """Create Source Create a new content source. @@ -148,7 +154,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | SourceResponse + Any | HTTPValidationError | ServiceUnavailableError | SourceResponse """ return sync_detailed( @@ -165,7 +171,7 @@ async def asyncio_detailed( body: CreateSourceBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | SourceResponse]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError | SourceResponse]: """Create Source Create a new content source. @@ -189,7 +195,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | SourceResponse] + Response[Any | HTTPValidationError | ServiceUnavailableError | SourceResponse] """ kwargs = _get_kwargs( @@ -209,7 +215,7 @@ async def asyncio( body: CreateSourceBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | SourceResponse | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | SourceResponse | None: """Create Source Create a new content source. @@ -233,7 +239,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | SourceResponse + Any | HTTPValidationError | ServiceUnavailableError | SourceResponse """ return ( diff --git a/seclai/_generated/api/sources/delete_source_api_sources_source_connection_id_delete.py b/seclai/_generated/api/sources/delete_source_api_sources_source_connection_id_delete.py index f75100e..dea7354 100644 --- a/seclai/_generated/api/sources/delete_source_api_sources_source_connection_id_delete.py +++ b/seclai/_generated/api/sources/delete_source_api_sources_source_connection_id_delete.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -37,7 +38,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 204: response_204 = cast(Any, None) return response_204 @@ -47,6 +48,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -55,7 +61,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -70,7 +76,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Source Soft-delete a content source. This action cannot be undone. @@ -88,7 +94,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -110,7 +116,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Source Soft-delete a content source. This action cannot be undone. @@ -128,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -145,7 +151,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Delete Source Soft-delete a content source. This action cannot be undone. @@ -163,7 +169,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -183,7 +189,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Delete Source Soft-delete a content source. This action cannot be undone. @@ -201,7 +207,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/sources/get_source_api_sources_source_connection_id_get.py b/seclai/_generated/api/sources/get_source_api_sources_source_connection_id_get.py index fd5ff4d..64af5c5 100644 --- a/seclai/_generated/api/sources/get_source_api_sources_source_connection_id_get.py +++ b/seclai/_generated/api/sources/get_source_api_sources_source_connection_id_get.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.source_response import SourceResponse from ...types import UNSET, Response, Unset @@ -38,7 +39,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SourceResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SourceResponse | None: if response.status_code == 200: response_200 = SourceResponse.from_dict(response.json()) @@ -49,6 +50,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +63,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SourceResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SourceResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -72,7 +78,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SourceResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SourceResponse]: """Get Source Fetch a content source by ID. @@ -91,7 +97,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SourceResponse] + Response[HTTPValidationError | ServiceUnavailableError | SourceResponse] """ kwargs = _get_kwargs( @@ -113,7 +119,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SourceResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SourceResponse | None: """Get Source Fetch a content source by ID. @@ -132,7 +138,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SourceResponse + HTTPValidationError | ServiceUnavailableError | SourceResponse """ return sync_detailed( @@ -149,7 +155,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SourceResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SourceResponse]: """Get Source Fetch a content source by ID. @@ -168,7 +174,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SourceResponse] + Response[HTTPValidationError | ServiceUnavailableError | SourceResponse] """ kwargs = _get_kwargs( @@ -188,7 +194,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SourceResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SourceResponse | None: """Get Source Fetch a content source by ID. @@ -207,7 +213,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SourceResponse + HTTPValidationError | ServiceUnavailableError | SourceResponse """ return ( diff --git a/seclai/_generated/api/sources/get_source_content_status_endpoint_api_sources_source_connection_id_contents_content_version_id_get.py b/seclai/_generated/api/sources/get_source_content_status_endpoint_api_sources_source_connection_id_contents_content_version_id_get.py new file mode 100644 index 0000000..6748cc4 --- /dev/null +++ b/seclai/_generated/api/sources/get_source_content_status_endpoint_api_sources_source_connection_id_contents_content_version_id_get.py @@ -0,0 +1,266 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError +from ...models.source_content_status_response import SourceContentStatusResponse +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + source_connection_id: UUID, + content_version_id: UUID, + *, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/sources/{source_connection_id}/contents/{content_version_id}".format( + source_connection_id=quote(str(source_connection_id), safe=""), + content_version_id=quote(str(content_version_id), safe=""), + ), + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse | None: + if response.status_code == 200: + response_200 = SourceContentStatusResponse.from_dict(response.json()) + + return response_200 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[ + HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse +]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + source_connection_id: UUID, + content_version_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse +]: + """Get one content item's indexing status + + Get the indexing status of a single content item, addressed by the `content_version_id` the upload + endpoints return. + + Use this to follow one uploaded file through indexing. To follow many at once, use `GET + /sources/{id}/contents` with repeated `content_version_id` parameters instead of polling this + endpoint per item. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. You can only access content belonging to your + account. + + Args: + source_connection_id (UUID): + content_version_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse] + """ + + kwargs = _get_kwargs( + source_connection_id=source_connection_id, + content_version_id=content_version_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + source_connection_id: UUID, + content_version_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse | None: + """Get one content item's indexing status + + Get the indexing status of a single content item, addressed by the `content_version_id` the upload + endpoints return. + + Use this to follow one uploaded file through indexing. To follow many at once, use `GET + /sources/{id}/contents` with repeated `content_version_id` parameters instead of polling this + endpoint per item. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. You can only access content belonging to your + account. + + Args: + source_connection_id (UUID): + content_version_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse + """ + + return sync_detailed( + source_connection_id=source_connection_id, + content_version_id=content_version_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + source_connection_id: UUID, + content_version_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse +]: + """Get one content item's indexing status + + Get the indexing status of a single content item, addressed by the `content_version_id` the upload + endpoints return. + + Use this to follow one uploaded file through indexing. To follow many at once, use `GET + /sources/{id}/contents` with repeated `content_version_id` parameters instead of polling this + endpoint per item. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. You can only access content belonging to your + account. + + Args: + source_connection_id (UUID): + content_version_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse] + """ + + kwargs = _get_kwargs( + source_connection_id=source_connection_id, + content_version_id=content_version_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + source_connection_id: UUID, + content_version_id: UUID, + *, + client: AuthenticatedClient | Client, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse | None: + """Get one content item's indexing status + + Get the indexing status of a single content item, addressed by the `content_version_id` the upload + endpoints return. + + Use this to follow one uploaded file through indexing. To follow many at once, use `GET + /sources/{id}/contents` with repeated `content_version_id` parameters instead of polling this + endpoint per item. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. You can only access content belonging to your + account. + + Args: + source_connection_id (UUID): + content_version_id (UUID): + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | ServiceUnavailableError | SourceContentStatusResponse + """ + + return ( + await asyncio_detailed( + source_connection_id=source_connection_id, + content_version_id=content_version_id, + client=client, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/sources/get_source_embedding_migration_api_sources_source_connection_id_embedding_migration_get.py b/seclai/_generated/api/sources/get_source_embedding_migration_api_sources_source_connection_id_embedding_migration_get.py index 49c14e7..7ef1d2a 100644 --- a/seclai/_generated/api/sources/get_source_embedding_migration_api_sources_source_connection_id_embedding_migration_get.py +++ b/seclai/_generated/api/sources/get_source_embedding_migration_api_sources_source_connection_id_embedding_migration_get.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.source_embedding_migration_response import ( SourceEmbeddingMigrationResponse, ) @@ -40,7 +41,13 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | None | SourceEmbeddingMigrationResponse | None: +) -> ( + HTTPValidationError + | None + | SourceEmbeddingMigrationResponse + | ServiceUnavailableError + | None +): if response.status_code == 200: def _parse_response_200( @@ -67,6 +74,11 @@ def _parse_response_200( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -75,7 +87,12 @@ def _parse_response_200( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | None | SourceEmbeddingMigrationResponse]: +) -> Response[ + HTTPValidationError + | None + | SourceEmbeddingMigrationResponse + | ServiceUnavailableError +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -90,7 +107,12 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | None | SourceEmbeddingMigrationResponse]: +) -> Response[ + HTTPValidationError + | None + | SourceEmbeddingMigrationResponse + | ServiceUnavailableError +]: """Get Source Embedding Migration Get the latest embedding migration status for a custom-index source. @@ -107,7 +129,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | None | SourceEmbeddingMigrationResponse] + Response[HTTPValidationError | None | SourceEmbeddingMigrationResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -129,7 +151,13 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | None | SourceEmbeddingMigrationResponse | None: +) -> ( + HTTPValidationError + | None + | SourceEmbeddingMigrationResponse + | ServiceUnavailableError + | None +): """Get Source Embedding Migration Get the latest embedding migration status for a custom-index source. @@ -146,7 +174,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | None | SourceEmbeddingMigrationResponse + HTTPValidationError | None | SourceEmbeddingMigrationResponse | ServiceUnavailableError """ return sync_detailed( @@ -163,7 +191,12 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | None | SourceEmbeddingMigrationResponse]: +) -> Response[ + HTTPValidationError + | None + | SourceEmbeddingMigrationResponse + | ServiceUnavailableError +]: """Get Source Embedding Migration Get the latest embedding migration status for a custom-index source. @@ -180,7 +213,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | None | SourceEmbeddingMigrationResponse] + Response[HTTPValidationError | None | SourceEmbeddingMigrationResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -200,7 +233,13 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | None | SourceEmbeddingMigrationResponse | None: +) -> ( + HTTPValidationError + | None + | SourceEmbeddingMigrationResponse + | ServiceUnavailableError + | None +): """Get Source Embedding Migration Get the latest embedding migration status for a custom-index source. @@ -217,7 +256,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | None | SourceEmbeddingMigrationResponse + HTTPValidationError | None | SourceEmbeddingMigrationResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/sources/list_source_contents_api_sources_source_connection_id_contents_get.py b/seclai/_generated/api/sources/list_source_contents_api_sources_source_connection_id_contents_get.py new file mode 100644 index 0000000..b2d41a4 --- /dev/null +++ b/seclai/_generated/api/sources/list_source_contents_api_sources_source_connection_id_contents_get.py @@ -0,0 +1,452 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError +from ...models.source_content_status_list_response import ( + SourceContentStatusListResponse, +) +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + source_connection_id: UUID, + *, + page: int | Unset = 1, + limit: int | Unset = 20, + sort: str | Unset = "created_at", + order: str | Unset = "desc", + status: None | str | Unset = UNSET, + content_version_id: list[UUID] | None | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(x_account_id, Unset): + headers["X-Account-Id"] = x_account_id + + if not isinstance(seclai_version, Unset): + headers["Seclai-Version"] = seclai_version + + params: dict[str, Any] = {} + + params["page"] = page + + params["limit"] = limit + + params["sort"] = sort + + params["order"] = order + + json_status: None | str | Unset + if isinstance(status, Unset): + json_status = UNSET + else: + json_status = status + params["status"] = json_status + + json_content_version_id: list[str] | None | Unset + if isinstance(content_version_id, Unset): + json_content_version_id = UNSET + elif isinstance(content_version_id, list): + json_content_version_id = [] + for content_version_id_type_0_item_data in content_version_id: + content_version_id_type_0_item = str(content_version_id_type_0_item_data) + json_content_version_id.append(content_version_id_type_0_item) + + else: + json_content_version_id = content_version_id + params["content_version_id"] = json_content_version_id + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/sources/{source_connection_id}/contents".format( + source_connection_id=quote(str(source_connection_id), safe=""), + ), + "params": params, + } + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> ( + HTTPValidationError + | ServiceUnavailableError + | SourceContentStatusListResponse + | None +): + if response.status_code == 200: + response_200 = SourceContentStatusListResponse.from_dict(response.json()) + + return response_200 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + + 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[ + HTTPValidationError | ServiceUnavailableError | SourceContentStatusListResponse +]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + source_connection_id: UUID, + *, + client: AuthenticatedClient | Client, + page: int | Unset = 1, + limit: int | Unset = 20, + sort: str | Unset = "created_at", + order: str | Unset = "desc", + status: None | str | Unset = UNSET, + content_version_id: list[UUID] | None | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SourceContentStatusListResponse +]: + """List content items and their indexing status + + List every content item this source has attempted to index, with the status of each. + + Unlike the source's `content_count`, which only counts finished items, this listing includes items + that are still processing and items that failed — so a bulk upload can report per-item progress and + point at the specific items that did not make it. + + Correlating with an upload: + - Each item is keyed by `content_version_id`, which is what the upload endpoints return. Pass those + ids as repeated `content_version_id` query parameters to poll exactly the items you uploaded. + - `source_connection_content_version_id` is `null` until an item finishes indexing; once set, it is + the id `GET /contents/{id}` takes. + - `content_status` reaches `completed` on success and `failed` on error, with the reason in `error`. + The intermediate values are `pending`, `fetching`, `transcribing`, `scanning`, and `indexing`. + + Parameters: + - Pagination: `page` and `limit`. + - Sorting: `sort` (created_at/title/status) and `order` (asc/desc). `created_at` sorts on when the + item was uploaded or pulled. + - Filtering: `status` and repeatable `content_version_id`. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. You can only list content for sources belonging + to your account. + + Args: + source_connection_id (UUID): + page (int | Unset): Page number Default: 1. + limit (int | Unset): Items per page Default: 20. + sort (str | Unset): Sort field (created_at/title/status) Default: 'created_at'. + order (str | Unset): Sort order Default: 'desc'. + status (None | str | Unset): Filter to one status: pending, fetching, transcribing, + scanning, indexing, completed, or failed. Use `failed` to list only the items that could + not be indexed. + content_version_id (list[UUID] | None | Unset): Filter to specific content versions, + repeatable. Pass the `content_version_id` values returned by the upload endpoints to poll + exactly the items you uploaded in a single request. At most 500 ids per request — beyond + that, page through the unfiltered listing or split the poll. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | ServiceUnavailableError | SourceContentStatusListResponse] + """ + + kwargs = _get_kwargs( + source_connection_id=source_connection_id, + page=page, + limit=limit, + sort=sort, + order=order, + status=status, + content_version_id=content_version_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + source_connection_id: UUID, + *, + client: AuthenticatedClient | Client, + page: int | Unset = 1, + limit: int | Unset = 20, + sort: str | Unset = "created_at", + order: str | Unset = "desc", + status: None | str | Unset = UNSET, + content_version_id: list[UUID] | None | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ( + HTTPValidationError + | ServiceUnavailableError + | SourceContentStatusListResponse + | None +): + """List content items and their indexing status + + List every content item this source has attempted to index, with the status of each. + + Unlike the source's `content_count`, which only counts finished items, this listing includes items + that are still processing and items that failed — so a bulk upload can report per-item progress and + point at the specific items that did not make it. + + Correlating with an upload: + - Each item is keyed by `content_version_id`, which is what the upload endpoints return. Pass those + ids as repeated `content_version_id` query parameters to poll exactly the items you uploaded. + - `source_connection_content_version_id` is `null` until an item finishes indexing; once set, it is + the id `GET /contents/{id}` takes. + - `content_status` reaches `completed` on success and `failed` on error, with the reason in `error`. + The intermediate values are `pending`, `fetching`, `transcribing`, `scanning`, and `indexing`. + + Parameters: + - Pagination: `page` and `limit`. + - Sorting: `sort` (created_at/title/status) and `order` (asc/desc). `created_at` sorts on when the + item was uploaded or pulled. + - Filtering: `status` and repeatable `content_version_id`. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. You can only list content for sources belonging + to your account. + + Args: + source_connection_id (UUID): + page (int | Unset): Page number Default: 1. + limit (int | Unset): Items per page Default: 20. + sort (str | Unset): Sort field (created_at/title/status) Default: 'created_at'. + order (str | Unset): Sort order Default: 'desc'. + status (None | str | Unset): Filter to one status: pending, fetching, transcribing, + scanning, indexing, completed, or failed. Use `failed` to list only the items that could + not be indexed. + content_version_id (list[UUID] | None | Unset): Filter to specific content versions, + repeatable. Pass the `content_version_id` values returned by the upload endpoints to poll + exactly the items you uploaded in a single request. At most 500 ids per request — beyond + that, page through the unfiltered listing or split the poll. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | ServiceUnavailableError | SourceContentStatusListResponse + """ + + return sync_detailed( + source_connection_id=source_connection_id, + client=client, + page=page, + limit=limit, + sort=sort, + order=order, + status=status, + content_version_id=content_version_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ).parsed + + +async def asyncio_detailed( + source_connection_id: UUID, + *, + client: AuthenticatedClient | Client, + page: int | Unset = 1, + limit: int | Unset = 20, + sort: str | Unset = "created_at", + order: str | Unset = "desc", + status: None | str | Unset = UNSET, + content_version_id: list[UUID] | None | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> Response[ + HTTPValidationError | ServiceUnavailableError | SourceContentStatusListResponse +]: + """List content items and their indexing status + + List every content item this source has attempted to index, with the status of each. + + Unlike the source's `content_count`, which only counts finished items, this listing includes items + that are still processing and items that failed — so a bulk upload can report per-item progress and + point at the specific items that did not make it. + + Correlating with an upload: + - Each item is keyed by `content_version_id`, which is what the upload endpoints return. Pass those + ids as repeated `content_version_id` query parameters to poll exactly the items you uploaded. + - `source_connection_content_version_id` is `null` until an item finishes indexing; once set, it is + the id `GET /contents/{id}` takes. + - `content_status` reaches `completed` on success and `failed` on error, with the reason in `error`. + The intermediate values are `pending`, `fetching`, `transcribing`, `scanning`, and `indexing`. + + Parameters: + - Pagination: `page` and `limit`. + - Sorting: `sort` (created_at/title/status) and `order` (asc/desc). `created_at` sorts on when the + item was uploaded or pulled. + - Filtering: `status` and repeatable `content_version_id`. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. You can only list content for sources belonging + to your account. + + Args: + source_connection_id (UUID): + page (int | Unset): Page number Default: 1. + limit (int | Unset): Items per page Default: 20. + sort (str | Unset): Sort field (created_at/title/status) Default: 'created_at'. + order (str | Unset): Sort order Default: 'desc'. + status (None | str | Unset): Filter to one status: pending, fetching, transcribing, + scanning, indexing, completed, or failed. Use `failed` to list only the items that could + not be indexed. + content_version_id (list[UUID] | None | Unset): Filter to specific content versions, + repeatable. Pass the `content_version_id` values returned by the upload endpoints to poll + exactly the items you uploaded in a single request. At most 500 ids per request — beyond + that, page through the unfiltered listing or split the poll. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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[HTTPValidationError | ServiceUnavailableError | SourceContentStatusListResponse] + """ + + kwargs = _get_kwargs( + source_connection_id=source_connection_id, + page=page, + limit=limit, + sort=sort, + order=order, + status=status, + content_version_id=content_version_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + source_connection_id: UUID, + *, + client: AuthenticatedClient | Client, + page: int | Unset = 1, + limit: int | Unset = 20, + sort: str | Unset = "created_at", + order: str | Unset = "desc", + status: None | str | Unset = UNSET, + content_version_id: list[UUID] | None | Unset = UNSET, + x_account_id: UUID | Unset = UNSET, + seclai_version: str | Unset = UNSET, +) -> ( + HTTPValidationError + | ServiceUnavailableError + | SourceContentStatusListResponse + | None +): + """List content items and their indexing status + + List every content item this source has attempted to index, with the status of each. + + Unlike the source's `content_count`, which only counts finished items, this listing includes items + that are still processing and items that failed — so a bulk upload can report per-item progress and + point at the specific items that did not make it. + + Correlating with an upload: + - Each item is keyed by `content_version_id`, which is what the upload endpoints return. Pass those + ids as repeated `content_version_id` query parameters to poll exactly the items you uploaded. + - `source_connection_content_version_id` is `null` until an item finishes indexing; once set, it is + the id `GET /contents/{id}` takes. + - `content_status` reaches `completed` on success and `failed` on error, with the reason in `error`. + The intermediate values are `pending`, `fetching`, `transcribing`, `scanning`, and `indexing`. + + Parameters: + - Pagination: `page` and `limit`. + - Sorting: `sort` (created_at/title/status) and `order` (asc/desc). `created_at` sorts on when the + item was uploaded or pulled. + - Filtering: `status` and repeatable `content_version_id`. + + Auth & scoping: + - Requires `X-API-Key` header or OAuth Bearer token. You can only list content for sources belonging + to your account. + + Args: + source_connection_id (UUID): + page (int | Unset): Page number Default: 1. + limit (int | Unset): Items per page Default: 20. + sort (str | Unset): Sort field (created_at/title/status) Default: 'created_at'. + order (str | Unset): Sort order Default: 'desc'. + status (None | str | Unset): Filter to one status: pending, fetching, transcribing, + scanning, indexing, completed, or failed. Use `failed` to list only the items that could + not be indexed. + content_version_id (list[UUID] | None | Unset): Filter to specific content versions, + repeatable. Pass the `content_version_id` values returned by the upload endpoints to poll + exactly the items you uploaded in a single request. At most 500 ids per request — beyond + that, page through the unfiltered listing or split the poll. + x_account_id (UUID | Unset): + seclai_version (str | Unset): + + 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: + HTTPValidationError | ServiceUnavailableError | SourceContentStatusListResponse + """ + + return ( + await asyncio_detailed( + source_connection_id=source_connection_id, + client=client, + page=page, + limit=limit, + sort=sort, + order=order, + status=status, + content_version_id=content_version_id, + x_account_id=x_account_id, + seclai_version=seclai_version, + ) + ).parsed diff --git a/seclai/_generated/api/sources/list_sources_api_sources_get.py b/seclai/_generated/api/sources/list_sources_api_sources_get.py index 1da1e43..efb72ee 100644 --- a/seclai/_generated/api/sources/list_sources_api_sources_get.py +++ b/seclai/_generated/api/sources/list_sources_api_sources_get.py @@ -7,6 +7,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.source_list_response import SourceListResponse from ...types import UNSET, Response, Unset @@ -59,7 +60,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SourceListResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SourceListResponse | None: if response.status_code == 200: response_200 = SourceListResponse.from_dict(response.json()) @@ -70,6 +71,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -78,7 +84,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SourceListResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SourceListResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -97,7 +103,7 @@ def sync_detailed( account_id: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SourceListResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SourceListResponse]: """List sources List content sources for your account. @@ -129,7 +135,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SourceListResponse] + Response[HTTPValidationError | ServiceUnavailableError | SourceListResponse] """ kwargs = _get_kwargs( @@ -159,7 +165,7 @@ def sync( account_id: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SourceListResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SourceListResponse | None: """List sources List content sources for your account. @@ -191,7 +197,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SourceListResponse + HTTPValidationError | ServiceUnavailableError | SourceListResponse """ return sync_detailed( @@ -216,7 +222,7 @@ async def asyncio_detailed( account_id: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SourceListResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SourceListResponse]: """List sources List content sources for your account. @@ -248,7 +254,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SourceListResponse] + Response[HTTPValidationError | ServiceUnavailableError | SourceListResponse] """ kwargs = _get_kwargs( @@ -276,7 +282,7 @@ async def asyncio( account_id: None | str | Unset = UNSET, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SourceListResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SourceListResponse | None: """List sources List content sources for your account. @@ -308,7 +314,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SourceListResponse + HTTPValidationError | ServiceUnavailableError | SourceListResponse """ return ( diff --git a/seclai/_generated/api/sources/start_source_embedding_migration_api_sources_source_connection_id_embedding_migration_post.py b/seclai/_generated/api/sources/start_source_embedding_migration_api_sources_source_connection_id_embedding_migration_post.py index 8db7841..2ca4794 100644 --- a/seclai/_generated/api/sources/start_source_embedding_migration_api_sources_source_connection_id_embedding_migration_post.py +++ b/seclai/_generated/api/sources/start_source_embedding_migration_api_sources_source_connection_id_embedding_migration_post.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.source_embedding_migration_response import ( SourceEmbeddingMigrationResponse, ) @@ -48,7 +49,13 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | SourceEmbeddingMigrationResponse | None: +) -> ( + Any + | HTTPValidationError + | ServiceUnavailableError + | SourceEmbeddingMigrationResponse + | None +): if response.status_code == 200: response_200 = SourceEmbeddingMigrationResponse.from_dict(response.json()) @@ -63,6 +70,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -71,7 +83,12 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError | SourceEmbeddingMigrationResponse]: +) -> Response[ + Any + | HTTPValidationError + | ServiceUnavailableError + | SourceEmbeddingMigrationResponse +]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -87,7 +104,12 @@ def sync_detailed( body: StartSourceEmbeddingMigrationRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | SourceEmbeddingMigrationResponse]: +) -> Response[ + Any + | HTTPValidationError + | ServiceUnavailableError + | SourceEmbeddingMigrationResponse +]: """Start Source Embedding Migration Start an embedding model migration for a custom-index source. @@ -116,7 +138,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | SourceEmbeddingMigrationResponse] + Response[Any | HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse] """ kwargs = _get_kwargs( @@ -140,7 +162,13 @@ def sync( body: StartSourceEmbeddingMigrationRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | SourceEmbeddingMigrationResponse | None: +) -> ( + Any + | HTTPValidationError + | ServiceUnavailableError + | SourceEmbeddingMigrationResponse + | None +): """Start Source Embedding Migration Start an embedding model migration for a custom-index source. @@ -169,7 +197,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | SourceEmbeddingMigrationResponse + Any | HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse """ return sync_detailed( @@ -188,7 +216,12 @@ async def asyncio_detailed( body: StartSourceEmbeddingMigrationRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[Any | HTTPValidationError | SourceEmbeddingMigrationResponse]: +) -> Response[ + Any + | HTTPValidationError + | ServiceUnavailableError + | SourceEmbeddingMigrationResponse +]: """Start Source Embedding Migration Start an embedding model migration for a custom-index source. @@ -217,7 +250,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | HTTPValidationError | SourceEmbeddingMigrationResponse] + Response[Any | HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse] """ kwargs = _get_kwargs( @@ -239,7 +272,13 @@ async def asyncio( body: StartSourceEmbeddingMigrationRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Any | HTTPValidationError | SourceEmbeddingMigrationResponse | None: +) -> ( + Any + | HTTPValidationError + | ServiceUnavailableError + | SourceEmbeddingMigrationResponse + | None +): """Start Source Embedding Migration Start an embedding model migration for a custom-index source. @@ -268,7 +307,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | HTTPValidationError | SourceEmbeddingMigrationResponse + Any | HTTPValidationError | ServiceUnavailableError | SourceEmbeddingMigrationResponse """ return ( diff --git a/seclai/_generated/api/sources/update_source_api_sources_source_connection_id_put.py b/seclai/_generated/api/sources/update_source_api_sources_source_connection_id_put.py index ea81c87..24d00ab 100644 --- a/seclai/_generated/api/sources/update_source_api_sources_source_connection_id_put.py +++ b/seclai/_generated/api/sources/update_source_api_sources_source_connection_id_put.py @@ -8,6 +8,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.source_response import SourceResponse from ...models.update_source_body import UpdateSourceBody from ...types import UNSET, Response, Unset @@ -44,7 +45,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SourceResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SourceResponse | None: if response.status_code == 200: response_200 = SourceResponse.from_dict(response.json()) @@ -55,6 +56,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -63,7 +69,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SourceResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SourceResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -79,7 +85,7 @@ def sync_detailed( body: UpdateSourceBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SourceResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SourceResponse]: """Update Source Update a content source's configuration. Only provided fields are changed; omitted fields are left @@ -98,7 +104,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SourceResponse] + Response[HTTPValidationError | ServiceUnavailableError | SourceResponse] """ kwargs = _get_kwargs( @@ -122,7 +128,7 @@ def sync( body: UpdateSourceBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SourceResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SourceResponse | None: """Update Source Update a content source's configuration. Only provided fields are changed; omitted fields are left @@ -141,7 +147,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SourceResponse + HTTPValidationError | ServiceUnavailableError | SourceResponse """ return sync_detailed( @@ -160,7 +166,7 @@ async def asyncio_detailed( body: UpdateSourceBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError | SourceResponse]: +) -> Response[HTTPValidationError | ServiceUnavailableError | SourceResponse]: """Update Source Update a content source's configuration. Only provided fields are changed; omitted fields are left @@ -179,7 +185,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError | SourceResponse] + Response[HTTPValidationError | ServiceUnavailableError | SourceResponse] """ kwargs = _get_kwargs( @@ -201,7 +207,7 @@ async def asyncio( body: UpdateSourceBody, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | SourceResponse | None: +) -> HTTPValidationError | ServiceUnavailableError | SourceResponse | None: """Update Source Update a content source's configuration. Only provided fields are changed; omitted fields are left @@ -220,7 +226,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError | SourceResponse + HTTPValidationError | ServiceUnavailableError | SourceResponse """ return ( diff --git a/seclai/_generated/api/sources/upload_file_to_source_api_sources_source_connection_id_upload_post.py b/seclai/_generated/api/sources/upload_file_to_source_api_sources_source_connection_id_upload_post.py index 4c46455..e818d9b 100644 --- a/seclai/_generated/api/sources/upload_file_to_source_api_sources_source_connection_id_upload_post.py +++ b/seclai/_generated/api/sources/upload_file_to_source_api_sources_source_connection_id_upload_post.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote from uuid import UUID @@ -11,6 +11,7 @@ BodyUploadFileToSourceApiSourcesSourceConnectionIdUploadPost, ) from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -43,12 +44,21 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: + if response.status_code == 403: + response_403 = cast(Any, None) + return response_403 + if response.status_code == 422: response_422 = HTTPValidationError.from_dict(response.json()) return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +67,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -73,12 +83,13 @@ def sync_detailed( body: BodyUploadFileToSourceApiSourcesSourceConnectionIdUploadPost, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: r"""Upload a file to a content source Upload a file to a content source. - **Maximum file size:** 209715200 bytes. + **Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized + before it is stored). **Supported MIME types:** - `application/epub+zip` @@ -115,6 +126,8 @@ def sync_detailed( - `video/x-msvideo` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension. - Use `metadata` to attach an arbitrary JSON object of metadata (for example @@ -128,6 +141,19 @@ def sync_detailed( - `status` is `uploaded` for a new upload, or `duplicate` when the same file already exists for this source. + Tracking indexing progress: + - **Which id you get back depends on `status`, and they are not interchangeable:** + - `uploaded` — a new item. `content_version_id` is set and `source_connection_content_version_id` + is `null`. Indexing continues in the background after this call returns. + - `duplicate` — this exact file is already on the source, so nothing was created and nothing is + being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the + existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll. + - For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned + `content_version_id`, or `GET /sources/{id}/contents?content_version_id=…&content_version_id=…` for + a whole batch, to follow each item through to `completed` or `failed`. + - On those status endpoints `source_connection_content_version_id` stays `null` until the item + finishes indexing; that is the id `GET /contents/{id}` takes. + Args: source_connection_id (str): x_account_id (UUID | Unset): @@ -139,7 +165,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -163,12 +189,13 @@ def sync( body: BodyUploadFileToSourceApiSourcesSourceConnectionIdUploadPost, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: r"""Upload a file to a content source Upload a file to a content source. - **Maximum file size:** 209715200 bytes. + **Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized + before it is stored). **Supported MIME types:** - `application/epub+zip` @@ -205,6 +232,8 @@ def sync( - `video/x-msvideo` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension. - Use `metadata` to attach an arbitrary JSON object of metadata (for example @@ -218,6 +247,19 @@ def sync( - `status` is `uploaded` for a new upload, or `duplicate` when the same file already exists for this source. + Tracking indexing progress: + - **Which id you get back depends on `status`, and they are not interchangeable:** + - `uploaded` — a new item. `content_version_id` is set and `source_connection_content_version_id` + is `null`. Indexing continues in the background after this call returns. + - `duplicate` — this exact file is already on the source, so nothing was created and nothing is + being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the + existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll. + - For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned + `content_version_id`, or `GET /sources/{id}/contents?content_version_id=…&content_version_id=…` for + a whole batch, to follow each item through to `completed` or `failed`. + - On those status endpoints `source_connection_content_version_id` stays `null` until the item + finishes indexing; that is the id `GET /contents/{id}` takes. + Args: source_connection_id (str): x_account_id (UUID | Unset): @@ -229,7 +271,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -248,12 +290,13 @@ async def asyncio_detailed( body: BodyUploadFileToSourceApiSourcesSourceConnectionIdUploadPost, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: r"""Upload a file to a content source Upload a file to a content source. - **Maximum file size:** 209715200 bytes. + **Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized + before it is stored). **Supported MIME types:** - `application/epub+zip` @@ -290,6 +333,8 @@ async def asyncio_detailed( - `video/x-msvideo` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension. - Use `metadata` to attach an arbitrary JSON object of metadata (for example @@ -303,6 +348,19 @@ async def asyncio_detailed( - `status` is `uploaded` for a new upload, or `duplicate` when the same file already exists for this source. + Tracking indexing progress: + - **Which id you get back depends on `status`, and they are not interchangeable:** + - `uploaded` — a new item. `content_version_id` is set and `source_connection_content_version_id` + is `null`. Indexing continues in the background after this call returns. + - `duplicate` — this exact file is already on the source, so nothing was created and nothing is + being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the + existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll. + - For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned + `content_version_id`, or `GET /sources/{id}/contents?content_version_id=…&content_version_id=…` for + a whole batch, to follow each item through to `completed` or `failed`. + - On those status endpoints `source_connection_content_version_id` stays `null` until the item + finishes indexing; that is the id `GET /contents/{id}` takes. + Args: source_connection_id (str): x_account_id (UUID | Unset): @@ -314,7 +372,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -336,12 +394,13 @@ async def asyncio( body: BodyUploadFileToSourceApiSourcesSourceConnectionIdUploadPost, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: r"""Upload a file to a content source Upload a file to a content source. - **Maximum file size:** 209715200 bytes. + **Maximum file size:** 209715200 bytes, except `image/svg+xml` at 5242880 bytes (SVG is sanitized + before it is stored). **Supported MIME types:** - `application/epub+zip` @@ -378,6 +437,8 @@ async def asyncio( - `video/x-msvideo` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - If the uploaded file's content type is `application/octet-stream`, the server attempts to infer the type from the file extension. - Use `metadata` to attach an arbitrary JSON object of metadata (for example @@ -391,6 +452,19 @@ async def asyncio( - `status` is `uploaded` for a new upload, or `duplicate` when the same file already exists for this source. + Tracking indexing progress: + - **Which id you get back depends on `status`, and they are not interchangeable:** + - `uploaded` — a new item. `content_version_id` is set and `source_connection_content_version_id` + is `null`. Indexing continues in the background after this call returns. + - `duplicate` — this exact file is already on the source, so nothing was created and nothing is + being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the + existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll. + - For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned + `content_version_id`, or `GET /sources/{id}/contents?content_version_id=…&content_version_id=…` for + a whole batch, to follow each item through to `completed` or `failed`. + - On those status endpoints `source_connection_content_version_id` stays `null` until the item + finishes indexing; that is the id `GET /contents/{id}` takes. + Args: source_connection_id (str): x_account_id (UUID | Unset): @@ -402,7 +476,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/sources/upload_inline_text_to_source_api_sources_source_connection_id_post.py b/seclai/_generated/api/sources/upload_inline_text_to_source_api_sources_source_connection_id_post.py index ec91232..67220e5 100644 --- a/seclai/_generated/api/sources/upload_inline_text_to_source_api_sources_source_connection_id_post.py +++ b/seclai/_generated/api/sources/upload_inline_text_to_source_api_sources_source_connection_id_post.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote from uuid import UUID @@ -9,6 +9,7 @@ from ...client import AuthenticatedClient, Client from ...models.http_validation_error import HTTPValidationError from ...models.inline_text_upload_request import InlineTextUploadRequest +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -43,12 +44,21 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: + if response.status_code == 403: + response_403 = cast(Any, None) + return response_403 + if response.status_code == 422: response_422 = HTTPValidationError.from_dict(response.json()) return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -57,7 +67,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -73,7 +83,7 @@ def sync_detailed( body: InlineTextUploadRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Upload inline text to a content source Upload a small text payload to a content source (no multipart/form-data required). @@ -91,9 +101,24 @@ def sync_detailed( - `text/xml` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - Use this endpoint for small text payloads; larger files should use `/upload`. - `title` is merged into `metadata.title` when not already present. + Tracking indexing progress: + - **Which id you get back depends on `status`, and they are not interchangeable:** + - `uploaded` — a new item. `content_version_id` is set and `source_connection_content_version_id` + is `null`. Indexing continues in the background after this call returns. + - `duplicate` — this exact file is already on the source, so nothing was created and nothing is + being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the + existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll. + - For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned + `content_version_id`, or `GET /sources/{id}/contents?content_version_id=…&content_version_id=…` for + a whole batch, to follow each item through to `completed` or `failed`. + - On those status endpoints `source_connection_content_version_id` stays `null` until the item + finishes indexing; that is the id `GET /contents/{id}` takes. + Args: source_connection_id (UUID): x_account_id (UUID | Unset): @@ -105,7 +130,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -129,7 +154,7 @@ def sync( body: InlineTextUploadRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Upload inline text to a content source Upload a small text payload to a content source (no multipart/form-data required). @@ -147,9 +172,24 @@ def sync( - `text/xml` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - Use this endpoint for small text payloads; larger files should use `/upload`. - `title` is merged into `metadata.title` when not already present. + Tracking indexing progress: + - **Which id you get back depends on `status`, and they are not interchangeable:** + - `uploaded` — a new item. `content_version_id` is set and `source_connection_content_version_id` + is `null`. Indexing continues in the background after this call returns. + - `duplicate` — this exact file is already on the source, so nothing was created and nothing is + being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the + existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll. + - For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned + `content_version_id`, or `GET /sources/{id}/contents?content_version_id=…&content_version_id=…` for + a whole batch, to follow each item through to `completed` or `failed`. + - On those status endpoints `source_connection_content_version_id` stays `null` until the item + finishes indexing; that is the id `GET /contents/{id}` takes. + Args: source_connection_id (UUID): x_account_id (UUID | Unset): @@ -161,7 +201,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -180,7 +220,7 @@ async def asyncio_detailed( body: InlineTextUploadRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[HTTPValidationError]: +) -> Response[Any | HTTPValidationError | ServiceUnavailableError]: """Upload inline text to a content source Upload a small text payload to a content source (no multipart/form-data required). @@ -198,9 +238,24 @@ async def asyncio_detailed( - `text/xml` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - Use this endpoint for small text payloads; larger files should use `/upload`. - `title` is merged into `metadata.title` when not already present. + Tracking indexing progress: + - **Which id you get back depends on `status`, and they are not interchangeable:** + - `uploaded` — a new item. `content_version_id` is set and `source_connection_content_version_id` + is `null`. Indexing continues in the background after this call returns. + - `duplicate` — this exact file is already on the source, so nothing was created and nothing is + being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the + existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll. + - For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned + `content_version_id`, or `GET /sources/{id}/contents?content_version_id=…&content_version_id=…` for + a whole batch, to follow each item through to `completed` or `failed`. + - On those status endpoints `source_connection_content_version_id` stays `null` until the item + finishes indexing; that is the id `GET /contents/{id}` takes. + Args: source_connection_id (UUID): x_account_id (UUID | Unset): @@ -212,7 +267,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[HTTPValidationError] + Response[Any | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -234,7 +289,7 @@ async def asyncio( body: InlineTextUploadRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> HTTPValidationError | None: +) -> Any | HTTPValidationError | ServiceUnavailableError | None: """Upload inline text to a content source Upload a small text payload to a content source (no multipart/form-data required). @@ -252,9 +307,24 @@ async def asyncio( - `text/xml` Notes: + - A key bound to a user must belong to an owner or administrator of the account; a viewer's key is + refused with 403 `permission_denied`. Account-scoped keys carry no user and are unaffected. - Use this endpoint for small text payloads; larger files should use `/upload`. - `title` is merged into `metadata.title` when not already present. + Tracking indexing progress: + - **Which id you get back depends on `status`, and they are not interchangeable:** + - `uploaded` — a new item. `content_version_id` is set and `source_connection_content_version_id` + is `null`. Indexing continues in the background after this call returns. + - `duplicate` — this exact file is already on the source, so nothing was created and nothing is + being indexed. `content_version_id` is `null` and `source_connection_content_version_id` is the + existing, already-indexed item: pass it straight to `GET /contents/{id}`. There is nothing to poll. + - For an `uploaded` item, poll `GET /sources/{id}/contents/{content_version_id}` with the returned + `content_version_id`, or `GET /sources/{id}/contents?content_version_id=…&content_version_id=…` for + a whole batch, to follow each item through to `completed` or `failed`. + - On those status endpoints `source_connection_content_version_id` stays `null` until the item + finishes indexing; that is the id `GET /contents/{id}` takes. + Args: source_connection_id (UUID): x_account_id (UUID | Unset): @@ -266,7 +336,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - HTTPValidationError + Any | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/version/get_api_version_api_version_get.py b/seclai/_generated/api/version/get_api_version_api_version_get.py index 787051f..b6bc282 100644 --- a/seclai/_generated/api/version/get_api_version_api_version_get.py +++ b/seclai/_generated/api/version/get_api_version_api_version_get.py @@ -7,6 +7,7 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.api_version_response import ApiVersionResponse +from ...models.service_unavailable_error import ServiceUnavailableError from ...types import UNSET, Response, Unset @@ -33,12 +34,17 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ApiVersionResponse | None: +) -> ApiVersionResponse | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ApiVersionResponse.from_dict(response.json()) return response_200 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -47,7 +53,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ApiVersionResponse]: +) -> Response[ApiVersionResponse | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -61,7 +67,7 @@ def sync_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ApiVersionResponse]: +) -> Response[ApiVersionResponse | ServiceUnavailableError]: """Get the account's API version Returns the account's pinned `Seclai-Version` (null when unpinned), the version this request @@ -77,7 +83,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ApiVersionResponse] + Response[ApiVersionResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -97,7 +103,7 @@ def sync( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ApiVersionResponse | None: +) -> ApiVersionResponse | ServiceUnavailableError | None: """Get the account's API version Returns the account's pinned `Seclai-Version` (null when unpinned), the version this request @@ -113,7 +119,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ApiVersionResponse + ApiVersionResponse | ServiceUnavailableError """ return sync_detailed( @@ -128,7 +134,7 @@ async def asyncio_detailed( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ApiVersionResponse]: +) -> Response[ApiVersionResponse | ServiceUnavailableError]: """Get the account's API version Returns the account's pinned `Seclai-Version` (null when unpinned), the version this request @@ -144,7 +150,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ApiVersionResponse] + Response[ApiVersionResponse | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -162,7 +168,7 @@ async def asyncio( client: AuthenticatedClient | Client, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ApiVersionResponse | None: +) -> ApiVersionResponse | ServiceUnavailableError | None: """Get the account's API version Returns the account's pinned `Seclai-Version` (null when unpinned), the version this request @@ -178,7 +184,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ApiVersionResponse + ApiVersionResponse | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/api/version/update_api_version_api_version_put.py b/seclai/_generated/api/version/update_api_version_api_version_put.py index a98e697..3936b5b 100644 --- a/seclai/_generated/api/version/update_api_version_api_version_put.py +++ b/seclai/_generated/api/version/update_api_version_api_version_put.py @@ -8,6 +8,7 @@ from ...client import AuthenticatedClient, Client from ...models.api_version_response import ApiVersionResponse from ...models.http_validation_error import HTTPValidationError +from ...models.service_unavailable_error import ServiceUnavailableError from ...models.update_api_version_request import UpdateApiVersionRequest from ...types import UNSET, Response, Unset @@ -40,7 +41,7 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ApiVersionResponse | HTTPValidationError | None: +) -> ApiVersionResponse | HTTPValidationError | ServiceUnavailableError | None: if response.status_code == 200: response_200 = ApiVersionResponse.from_dict(response.json()) @@ -51,6 +52,11 @@ def _parse_response( return response_422 + if response.status_code == 503: + response_503 = ServiceUnavailableError.from_dict(response.json()) + + return response_503 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -59,7 +65,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ApiVersionResponse | HTTPValidationError]: +) -> Response[ApiVersionResponse | HTTPValidationError | ServiceUnavailableError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -74,7 +80,7 @@ def sync_detailed( body: UpdateApiVersionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ApiVersionResponse | HTTPValidationError]: +) -> Response[ApiVersionResponse | HTTPValidationError | ServiceUnavailableError]: """Pin (or clear) the account's API version Sets the account's sticky `Seclai-Version` to the given `YYYY-MM-DD` date, or clears it with `null`. @@ -92,7 +98,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ApiVersionResponse | HTTPValidationError] + Response[ApiVersionResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -114,7 +120,7 @@ def sync( body: UpdateApiVersionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ApiVersionResponse | HTTPValidationError | None: +) -> ApiVersionResponse | HTTPValidationError | ServiceUnavailableError | None: """Pin (or clear) the account's API version Sets the account's sticky `Seclai-Version` to the given `YYYY-MM-DD` date, or clears it with `null`. @@ -132,7 +138,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ApiVersionResponse | HTTPValidationError + ApiVersionResponse | HTTPValidationError | ServiceUnavailableError """ return sync_detailed( @@ -149,7 +155,7 @@ async def asyncio_detailed( body: UpdateApiVersionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> Response[ApiVersionResponse | HTTPValidationError]: +) -> Response[ApiVersionResponse | HTTPValidationError | ServiceUnavailableError]: """Pin (or clear) the account's API version Sets the account's sticky `Seclai-Version` to the given `YYYY-MM-DD` date, or clears it with `null`. @@ -167,7 +173,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ApiVersionResponse | HTTPValidationError] + Response[ApiVersionResponse | HTTPValidationError | ServiceUnavailableError] """ kwargs = _get_kwargs( @@ -187,7 +193,7 @@ async def asyncio( body: UpdateApiVersionRequest, x_account_id: UUID | Unset = UNSET, seclai_version: str | Unset = UNSET, -) -> ApiVersionResponse | HTTPValidationError | None: +) -> ApiVersionResponse | HTTPValidationError | ServiceUnavailableError | None: """Pin (or clear) the account's API version Sets the account's sticky `Seclai-Version` to the given `YYYY-MM-DD` date, or clears it with `null`. @@ -205,7 +211,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ApiVersionResponse | HTTPValidationError + ApiVersionResponse | HTTPValidationError | ServiceUnavailableError """ return ( diff --git a/seclai/_generated/models/__init__.py b/seclai/_generated/models/__init__.py index 74d1c28..055d8a9 100644 --- a/seclai/_generated/models/__init__.py +++ b/seclai/_generated/models/__init__.py @@ -42,6 +42,7 @@ ) from .agent_list_response import AgentListResponse from .agent_run_attempt_response import AgentRunAttemptResponse +from .agent_run_file_response import AgentRunFileResponse from .agent_run_list_response import AgentRunListResponse from .agent_run_request import AgentRunRequest from .agent_run_request_metadata_type_0 import AgentRunRequestMetadataType0 @@ -57,6 +58,7 @@ from .agent_trace_match_response import AgentTraceMatchResponse from .agent_trace_search_request import AgentTraceSearchRequest from .agent_trace_search_response import AgentTraceSearchResponse +from .agent_using_cloud_drive_response_model import AgentUsingCloudDriveResponseModel from .ai_assistant_accept_request import AiAssistantAcceptRequest from .ai_assistant_accept_response import AiAssistantAcceptResponse from .ai_assistant_feedback_request import AiAssistantFeedbackRequest @@ -95,6 +97,12 @@ from .cancel_experiment_response import CancelExperimentResponse from .cancel_queued_runs_response import CancelQueuedRunsResponse from .change_status_request import ChangeStatusRequest +from .cloud_drive_access_level_response_model import CloudDriveAccessLevelResponseModel +from .cloud_drive_provider_response_model import CloudDriveProviderResponseModel +from .cloud_drive_rejection_response_model import CloudDriveRejectionResponseModel +from .cloud_drive_response_model import CloudDriveResponseModel +from .cloud_drive_scope_response_model import CloudDriveScopeResponseModel +from .cloud_drive_update_request import CloudDriveUpdateRequest from .compaction_evaluation_model import CompactionEvaluationModel from .compaction_scheduled_response import CompactionScheduledResponse from .compaction_test_response_model import CompactionTestResponseModel @@ -140,9 +148,14 @@ from .docs_search_api_docs_search_get_mode import DocsSearchApiDocsSearchGetMode from .docs_search_response import DocsSearchResponse from .docs_search_result_response import DocsSearchResultResponse +from .effort_options_response import EffortOptionsResponse from .email_domain_response import EmailDomainResponse from .email_domains_list_response import EmailDomainsListResponse from .email_trigger_config_response import EmailTriggerConfigResponse +from .embedding_modality_rate_response import EmbeddingModalityRateResponse +from .embedding_model_list_response import EmbeddingModelListResponse +from .embedding_model_response import EmbeddingModelResponse +from .embedding_storage_credits_response import EmbeddingStorageCreditsResponse from .estimate_export_request import EstimateExportRequest from .estimate_export_request_metadata_filter_type_0 import ( EstimateExportRequestMetadataFilterType0, @@ -176,6 +189,7 @@ from .example_prompt import ExamplePrompt from .executed_action_response import ExecutedActionResponse from .experiment_detail_response import ExperimentDetailResponse +from .experiment_detail_response_effort import ExperimentDetailResponseEffort from .experiment_detail_response_result_data_type_0 import ( ExperimentDetailResponseResultDataType0, ) @@ -277,6 +291,7 @@ PendingProcessingCompletedFailedStatus, ) from .playground_create_request import PlaygroundCreateRequest +from .playground_create_request_effort_type_0 import PlaygroundCreateRequestEffortType0 from .playground_create_request_evaluation_complexity import ( PlaygroundCreateRequestEvaluationComplexity, ) @@ -285,6 +300,9 @@ ) from .prompt_model_auto_upgrade_strategy import PromptModelAutoUpgradeStrategy from .prompt_model_response import PromptModelResponse +from .prompt_model_response_generation_credits_per_variant_type_0 import ( + PromptModelResponseGenerationCreditsPerVariantType0, +) from .prompt_model_response_generation_params_type_0 import ( PromptModelResponseGenerationParamsType0, ) @@ -300,10 +318,15 @@ from .proposed_policy_action_response_params import ProposedPolicyActionResponseParams from .provider_group_response import ProviderGroupResponse from .remove_email_domain_response import RemoveEmailDomainResponse +from .reranker_model_list_response import RerankerModelListResponse +from .reranker_model_response import RerankerModelResponse from .resume_inbound_response import ResumeInboundResponse from .search_response import SearchResponse from .search_result_response import SearchResultResponse from .send_test_email_response import SendTestEmailResponse +from .service_unavailable_error import ServiceUnavailableError +from .service_unavailable_error_error import ServiceUnavailableErrorError +from .service_unavailable_error_error_code import ServiceUnavailableErrorErrorCode from .set_auto_block_mode_request import SetAutoBlockModeRequest from .set_email_trigger_config_request import SetEmailTriggerConfigRequest from .solution_agent_response import SolutionAgentResponse @@ -317,6 +340,8 @@ from .solution_source_connection_response import SolutionSourceConnectionResponse from .solution_summary_response import SolutionSummaryResponse from .source_connection_response_model import SourceConnectionResponseModel +from .source_content_status_list_response import SourceContentStatusListResponse +from .source_content_status_response import SourceContentStatusResponse from .source_embedding_migration_response import SourceEmbeddingMigrationResponse from .source_index_mode import SourceIndexMode from .source_list_response import SourceListResponse @@ -393,6 +418,7 @@ "AgentImportPreviewResponseUnresolvedRefsItem", "AgentListResponse", "AgentRunAttemptResponse", + "AgentRunFileResponse", "AgentRunListResponse", "AgentRunRequest", "AgentRunRequestMetadataType0", @@ -406,6 +432,7 @@ "AgentTraceMatchResponse", "AgentTraceSearchRequest", "AgentTraceSearchResponse", + "AgentUsingCloudDriveResponseModel", "AiAssistantAcceptRequest", "AiAssistantAcceptResponse", "AiAssistantFeedbackRequest", @@ -436,6 +463,12 @@ "CancelExperimentResponse", "CancelQueuedRunsResponse", "ChangeStatusRequest", + "CloudDriveAccessLevelResponseModel", + "CloudDriveProviderResponseModel", + "CloudDriveRejectionResponseModel", + "CloudDriveResponseModel", + "CloudDriveScopeResponseModel", + "CloudDriveUpdateRequest", "CompactionEvaluationModel", "CompactionScheduledResponse", "CompactionTestResponseModel", @@ -469,9 +502,14 @@ "DocsSearchApiDocsSearchGetMode", "DocsSearchResponse", "DocsSearchResultResponse", + "EffortOptionsResponse", "EmailDomainResponse", "EmailDomainsListResponse", "EmailTriggerConfigResponse", + "EmbeddingModalityRateResponse", + "EmbeddingModelListResponse", + "EmbeddingModelResponse", + "EmbeddingStorageCreditsResponse", "EstimateExportRequest", "EstimateExportRequestMetadataFilterType0", "EstimateExportResponse", @@ -491,6 +529,7 @@ "ExamplePrompt", "ExecutedActionResponse", "ExperimentDetailResponse", + "ExperimentDetailResponseEffort", "ExperimentDetailResponseResultDataType0", "ExperimentListResponse", "ExperimentSummaryResponse", @@ -560,10 +599,12 @@ "PaginationResponse", "PendingProcessingCompletedFailedStatus", "PlaygroundCreateRequest", + "PlaygroundCreateRequestEffortType0", "PlaygroundCreateRequestEvaluationComplexity", "PlaygroundCreateRequestEvaluationMode", "PromptModelAutoUpgradeStrategy", "PromptModelResponse", + "PromptModelResponseGenerationCreditsPerVariantType0", "PromptModelResponseGenerationParamsType0", "PromptModelResponsePayloadSchemaType0", "PromptToolResponse", @@ -575,10 +616,15 @@ "ProposedPolicyActionResponseParams", "ProviderGroupResponse", "RemoveEmailDomainResponse", + "RerankerModelListResponse", + "RerankerModelResponse", "ResumeInboundResponse", "SearchResponse", "SearchResultResponse", "SendTestEmailResponse", + "ServiceUnavailableError", + "ServiceUnavailableErrorError", + "ServiceUnavailableErrorErrorCode", "SetAutoBlockModeRequest", "SetEmailTriggerConfigRequest", "SolutionAgentResponse", @@ -590,6 +636,8 @@ "SolutionSourceConnectionResponse", "SolutionSummaryResponse", "SourceConnectionResponseModel", + "SourceContentStatusListResponse", + "SourceContentStatusResponse", "SourceEmbeddingMigrationResponse", "SourceIndexMode", "SourceListResponse", diff --git a/seclai/_generated/models/agent_export_response.py b/seclai/_generated/models/agent_export_response.py index f51281a..1390350 100644 --- a/seclai/_generated/models/agent_export_response.py +++ b/seclai/_generated/models/agent_export_response.py @@ -39,7 +39,7 @@ class AgentExportResponse: definition, default_evaluation_tier, evaluation_mode, sampling_config, max_retries, retry_on_failure, prompt_model_auto_upgrade_strategy, prompt_model_auto_rollback_enabled, prompt_model_auto_rollback_triggers, created_at, updated_at. - export_version (str): Schema version of the export format (currently "2"). + export_version (str): Schema version of the export format (currently "5"). exported_at (str): ISO-8601 timestamp of when the export was generated. software_version (str): Application version that produced this export. alert_configs (list[AgentExportResponseAlertConfigsType0Item] | None | Unset): Alert configurations. diff --git a/seclai/_generated/models/agent_run_file_response.py b/seclai/_generated/models/agent_run_file_response.py new file mode 100644 index 0000000..a508937 --- /dev/null +++ b/seclai/_generated/models/agent_run_file_response.py @@ -0,0 +1,109 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, cast +from uuid import UUID + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="AgentRunFileResponse") + + +@_attrs_define +class AgentRunFileResponse: + """A file in a run's or a step's output. + + Attributes: + bytes_ (int | None): Size of the file in bytes, when known. + download_url (str): `GET` URL that streams the file; accepts an API key or OAuth token. + id (UUID): File identifier, used to download it. + mime (str): MIME type of the file. + name (None | str): The file's name in this run, as sent to email recipients and webhooks and matched by + `{{attachments[...]}}` selectors. + """ + + bytes_: int | None + download_url: str + id: UUID + mime: str + name: None | str + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + bytes_: int | None + bytes_ = self.bytes_ + + download_url = self.download_url + + id = str(self.id) + + mime = self.mime + + name: None | str + name = self.name + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "bytes": bytes_, + "download_url": download_url, + "id": id, + "mime": mime, + "name": name, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + + def _parse_bytes_(data: object) -> int | None: + if data is None: + return data + return cast(int | None, data) + + bytes_ = _parse_bytes_(d.pop("bytes")) + + download_url = d.pop("download_url") + + id = UUID(d.pop("id")) + + mime = d.pop("mime") + + def _parse_name(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + name = _parse_name(d.pop("name")) + + agent_run_file_response = cls( + bytes_=bytes_, + download_url=download_url, + id=id, + mime=mime, + name=name, + ) + + agent_run_file_response.additional_properties = d + return agent_run_file_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/seclai/_generated/models/agent_run_request.py b/seclai/_generated/models/agent_run_request.py index 2c22f9a..7c11e7b 100644 --- a/seclai/_generated/models/agent_run_request.py +++ b/seclai/_generated/models/agent_run_request.py @@ -22,8 +22,9 @@ class AgentRunRequest: Attributes: input_ (None | str | Unset): Input to provide to the agent upon running for agents with dynamic triggers. input_upload_id (None | Unset | UUID): ID of a previously uploaded file (via POST /{agent_id}/upload-input) to - use as the run input for dynamic-input triggers. Mutually exclusive with the 'input' field. Use - ``input_upload_ids`` to attach multiple files. + use as the run input for dynamic-input triggers. Mutually exclusive with ``input_upload_ids`` — use that field + to attach multiple files. May be combined with ``input``: the prompt text leads and the file's extracted text + follows under a ``# {filename}`` heading. **Attachment visibility:** a step only sees the upload when its template references the input — via ``{{input}}`` / ``{{agent.input}}`` / ``{{step..input|output}}`` (implicit, all attachments) or the @@ -38,7 +39,9 @@ class AgentRunRequest: selectors (by index, filename, or fnmatch glob). The batch must satisfy every selector the agent declares — exact names, indexed references (length must exceed the highest index), and glob patterns (each pattern needs at least one match). Mismatches return HTTP 400 with the unmet requirements listed. Mutually exclusive with - ``input`` and ``input_upload_id`` — pass exactly one of the three. Max 20 uploads per run. + ``input_upload_id`` (two spellings of the same batch), but may be combined with ``input`` — the prompt text + leads and the per-file sections follow, so "a photo plus a sentence about it" needs no synthetic text upload. + Max 20 uploads per run. metadata (AgentRunRequestMetadataType0 | None | Unset): Metadata to make available for string substitution expressions in agent tasks. priority (bool | Unset): If true, the agent run will be treated as priority execution. Default: False. diff --git a/seclai/_generated/models/agent_run_response.py b/seclai/_generated/models/agent_run_response.py index 0b5c219..10f95ba 100644 --- a/seclai/_generated/models/agent_run_response.py +++ b/seclai/_generated/models/agent_run_response.py @@ -1,10 +1,12 @@ from __future__ import annotations +import datetime from collections.abc import Mapping from typing import TYPE_CHECKING, Any, TypeVar, cast from attrs import define as _attrs_define from attrs import field as _attrs_field +from dateutil.parser import isoparse from ..models.pending_processing_completed_failed_status import ( PendingProcessingCompletedFailedStatus, @@ -13,6 +15,7 @@ if TYPE_CHECKING: from ..models.agent_run_attempt_response import AgentRunAttemptResponse + from ..models.agent_run_file_response import AgentRunFileResponse from ..models.agent_run_step_response import AgentRunStepResponse from ..models.governance_policy_ref_response import GovernancePolicyRefResponse @@ -25,13 +28,18 @@ class AgentRunResponse: """ Attributes: attempts (list[AgentRunAttemptResponse]): List of attempts made for this agent run. - credits_ (float | None): Credits consumed by the agent run, if applicable. + credits_ (float | None): Credits consumed by the agent run, if applicable. Can still rise briefly after the run + ends, while governance screening finishes. error_count (int): Number of errors encountered during the run. input_ (None | str): Input provided to the agent for this run. - output (None | str): Output produced by the agent run. + output (None | str): The run's output text; its files are in `attachments`. Below `Seclai-Version: 2026-09-30` + an output that has files is instead the manifest JSON `{schema, text, attachments: [{storage_key, mime, name, + label, bytes}]}`; `bytes` is absent on runs made before that version shipped. priority (bool): Indicates if the run was treated as a priority execution. run_id (str): Unique identifier for the agent run. status (PendingProcessingCompletedFailedStatus): + attachments (list[AgentRunFileResponse] | Unset): Files in the run's output, in order. Empty for runs that + produced none, for runs made before files were listed here, and once the run's trace is purged. blocked_policies (list[GovernancePolicyRefResponse] | Unset): Governance policies that produced at least one BLOCK verdict during this run. Deduplicated by policy id. flagged_policies (list[GovernancePolicyRefResponse] | Unset): Governance policies that produced at least one @@ -44,15 +52,18 @@ class AgentRunResponse: input_scan_status (None | str | Unset): Result of the prompt injection scan: safe, unsafe, skipped, timed_out, or error. output_content_type (None | str | Unset): MIME type of `output` — mirrors the terminal step's - `output_content_type`. Consumers interpret `output` differently depending on this value: - `application/vnd.seclai.manifest+json` is a multi-asset manifest with shape `{text, attachments: [{storage_key, - mime, name, bytes}]}` — fetch each attachment via `GET /v2/agent-runs/{run_id}/attachments/{attachment_id}`, - where `attachment_id` is the URL-safe base64 of the attachment's `storage_key` (accepts an API key or OAuth - token). `text/plain` / `text/*` are free-form text. `application/json` is a JSON document. Null on runs that + `output_content_type`. `text/plain` / `text/*` are free-form text and `application/json` is a JSON document. + Below `Seclai-Version: 2026-09-30` an output that has files reads `application/vnd.seclai.manifest+json` (see + `output`); the same files are in `attachments` on every version, each with a `download_url`. Null on runs that produced no terminal output or that pre-date this column. scan_wait_ms (int | None | Unset): Milliseconds spent waiting for prompt injection scan. steps (list[AgentRunStepResponse] | None | Unset): Step outputs and per-step timing/credits. Only included when requested. + trace_purged_at (datetime.datetime | None | Unset): When this run's trace content was deleted under the + account's agent-trace retention window. Non-null means `input`, `output` and every step's and tool call's I/O + are null **by design** and will never be available again — the run aged out, it did not fail. Branch on this + rather than on a null `output`: a run that genuinely produced nothing looks identical. Status, timing and + credits remain accurate. wait_ms (int | None | Unset): Cumulative milliseconds the run was parked on standard-mode wait steps. Subtracted from active duration in run-detail and duration-stats responses, exactly like hitl_wait_ms. Priority waits block inline and are not counted here. @@ -66,6 +77,7 @@ class AgentRunResponse: priority: bool run_id: str status: PendingProcessingCompletedFailedStatus + attachments: list[AgentRunFileResponse] | Unset = UNSET blocked_policies: list[GovernancePolicyRefResponse] | Unset = UNSET flagged_policies: list[GovernancePolicyRefResponse] | Unset = UNSET governance_input_status: None | str | Unset = UNSET @@ -75,6 +87,7 @@ class AgentRunResponse: output_content_type: None | str | Unset = UNSET scan_wait_ms: int | None | Unset = UNSET steps: list[AgentRunStepResponse] | None | Unset = UNSET + trace_purged_at: datetime.datetime | None | Unset = UNSET wait_ms: int | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -101,6 +114,13 @@ def to_dict(self) -> dict[str, Any]: status = self.status.value + attachments: list[dict[str, Any]] | Unset = UNSET + if not isinstance(self.attachments, Unset): + attachments = [] + for attachments_item_data in self.attachments: + attachments_item = attachments_item_data.to_dict() + attachments.append(attachments_item) + blocked_policies: list[dict[str, Any]] | Unset = UNSET if not isinstance(self.blocked_policies, Unset): blocked_policies = [] @@ -163,6 +183,14 @@ def to_dict(self) -> dict[str, Any]: else: steps = self.steps + trace_purged_at: None | str | Unset + if isinstance(self.trace_purged_at, Unset): + trace_purged_at = UNSET + elif isinstance(self.trace_purged_at, datetime.datetime): + trace_purged_at = self.trace_purged_at.isoformat() + else: + trace_purged_at = self.trace_purged_at + wait_ms: int | None | Unset if isinstance(self.wait_ms, Unset): wait_ms = UNSET @@ -183,6 +211,8 @@ def to_dict(self) -> dict[str, Any]: "status": status, } ) + if attachments is not UNSET: + field_dict["attachments"] = attachments if blocked_policies is not UNSET: field_dict["blocked_policies"] = blocked_policies if flagged_policies is not UNSET: @@ -201,6 +231,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["scan_wait_ms"] = scan_wait_ms if steps is not UNSET: field_dict["steps"] = steps + if trace_purged_at is not UNSET: + field_dict["trace_purged_at"] = trace_purged_at if wait_ms is not UNSET: field_dict["wait_ms"] = wait_ms @@ -209,6 +241,7 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: from ..models.agent_run_attempt_response import AgentRunAttemptResponse + from ..models.agent_run_file_response import AgentRunFileResponse from ..models.agent_run_step_response import AgentRunStepResponse from ..models.governance_policy_ref_response import GovernancePolicyRefResponse @@ -249,6 +282,15 @@ def _parse_output(data: object) -> None | str: status = PendingProcessingCompletedFailedStatus(d.pop("status")) + _attachments = d.pop("attachments", UNSET) + attachments: list[AgentRunFileResponse] | Unset = UNSET + if _attachments is not UNSET: + attachments = [] + for attachments_item_data in _attachments: + attachments_item = AgentRunFileResponse.from_dict(attachments_item_data) + + attachments.append(attachments_item) + _blocked_policies = d.pop("blocked_policies", UNSET) blocked_policies: list[GovernancePolicyRefResponse] | Unset = UNSET if _blocked_policies is not UNSET: @@ -355,6 +397,23 @@ def _parse_steps(data: object) -> list[AgentRunStepResponse] | None | Unset: steps = _parse_steps(d.pop("steps", UNSET)) + def _parse_trace_purged_at(data: object) -> datetime.datetime | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + trace_purged_at_type_0 = isoparse(data) + + return trace_purged_at_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(datetime.datetime | None | Unset, data) + + trace_purged_at = _parse_trace_purged_at(d.pop("trace_purged_at", UNSET)) + def _parse_wait_ms(data: object) -> int | None | Unset: if data is None: return data @@ -373,6 +432,7 @@ def _parse_wait_ms(data: object) -> int | None | Unset: priority=priority, run_id=run_id, status=status, + attachments=attachments, blocked_policies=blocked_policies, flagged_policies=flagged_policies, governance_input_status=governance_input_status, @@ -382,6 +442,7 @@ def _parse_wait_ms(data: object) -> int | None | Unset: output_content_type=output_content_type, scan_wait_ms=scan_wait_ms, steps=steps, + trace_purged_at=trace_purged_at, wait_ms=wait_ms, ) diff --git a/seclai/_generated/models/agent_run_step_response.py b/seclai/_generated/models/agent_run_step_response.py index cfc6b7e..74a7327 100644 --- a/seclai/_generated/models/agent_run_step_response.py +++ b/seclai/_generated/models/agent_run_step_response.py @@ -12,6 +12,7 @@ from ..types import UNSET, Unset if TYPE_CHECKING: + from ..models.agent_run_file_response import AgentRunFileResponse from ..models.agent_run_tool_call_response import AgentRunToolCallResponse @@ -23,17 +24,25 @@ class AgentRunStepResponse: """ Attributes: agent_step_id (str): Agent step identifier. - credits_used (float): Credits consumed by the step attempt, if applicable. + credits_used (float): Credits consumed by this step across every attempt it made. Some charges made outside any + step, such as governance screening of the run's input, count toward the run's total but no step's. The + timestamps above and the tool calls below describe the latest attempt only. duration_seconds (float | None): Duration of the step attempt in seconds. ended_at (None | str): Timestamp when the step attempt ended. - input_ (None | str): Input provided to the step, if any. - output (None | str): Output produced by the step, if any. + input_ (None | str): Input text provided to the step, if any. Below `Seclai-Version: 2026-09-30`, the manifest + JSON when the step that produced it output files and is not a `for_each`. + output (None | str): Output text produced by the step, if any; its files are in `attachments`. Below `Seclai- + Version: 2026-09-30`, the manifest JSON when the step output files and is not a `for_each`. output_content_type (None | str): Content type of the step output, if any. started_at (None | str): Timestamp when the step attempt started. status (PendingProcessingCompletedFailedStatus): step_type (str): Type of the agent step. + attachments (list[AgentRunFileResponse] | Unset): Files in this step's output, in order. Empty for steps that + produced none, for steps run before files were listed here, and once the run's trace is purged. tool_calls (list[AgentRunToolCallResponse] | Unset): LLM tool calls made during this step (prompt_call steps only), ordered by execution. Empty for steps that invoked no tools. + warnings (list[str] | None | Unset): Authoring problems the step ran into, whether or not it then failed, such + as a file name selector that matched none of its source's files. """ agent_step_id: str @@ -46,7 +55,9 @@ class AgentRunStepResponse: started_at: None | str status: PendingProcessingCompletedFailedStatus step_type: str + attachments: list[AgentRunFileResponse] | Unset = UNSET tool_calls: list[AgentRunToolCallResponse] | Unset = UNSET + warnings: list[str] | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -76,6 +87,13 @@ def to_dict(self) -> dict[str, Any]: step_type = self.step_type + attachments: list[dict[str, Any]] | Unset = UNSET + if not isinstance(self.attachments, Unset): + attachments = [] + for attachments_item_data in self.attachments: + attachments_item = attachments_item_data.to_dict() + attachments.append(attachments_item) + tool_calls: list[dict[str, Any]] | Unset = UNSET if not isinstance(self.tool_calls, Unset): tool_calls = [] @@ -83,6 +101,15 @@ def to_dict(self) -> dict[str, Any]: tool_calls_item = tool_calls_item_data.to_dict() tool_calls.append(tool_calls_item) + warnings: list[str] | None | Unset + if isinstance(self.warnings, Unset): + warnings = UNSET + elif isinstance(self.warnings, list): + warnings = self.warnings + + else: + warnings = self.warnings + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -99,13 +126,18 @@ def to_dict(self) -> dict[str, Any]: "step_type": step_type, } ) + if attachments is not UNSET: + field_dict["attachments"] = attachments if tool_calls is not UNSET: field_dict["tool_calls"] = tool_calls + if warnings is not UNSET: + field_dict["warnings"] = warnings return field_dict @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.agent_run_file_response import AgentRunFileResponse from ..models.agent_run_tool_call_response import AgentRunToolCallResponse d = dict(src_dict) @@ -159,6 +191,15 @@ def _parse_started_at(data: object) -> None | str: step_type = d.pop("step_type") + _attachments = d.pop("attachments", UNSET) + attachments: list[AgentRunFileResponse] | Unset = UNSET + if _attachments is not UNSET: + attachments = [] + for attachments_item_data in _attachments: + attachments_item = AgentRunFileResponse.from_dict(attachments_item_data) + + attachments.append(attachments_item) + _tool_calls = d.pop("tool_calls", UNSET) tool_calls: list[AgentRunToolCallResponse] | Unset = UNSET if _tool_calls is not UNSET: @@ -170,6 +211,23 @@ def _parse_started_at(data: object) -> None | str: tool_calls.append(tool_calls_item) + def _parse_warnings(data: object) -> list[str] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + warnings_type_0 = cast(list[str], data) + + return warnings_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + warnings = _parse_warnings(d.pop("warnings", UNSET)) + agent_run_step_response = cls( agent_step_id=agent_step_id, credits_used=credits_used, @@ -181,7 +239,9 @@ def _parse_started_at(data: object) -> None | str: started_at=started_at, status=status, step_type=step_type, + attachments=attachments, tool_calls=tool_calls, + warnings=warnings, ) agent_run_step_response.additional_properties = d diff --git a/seclai/_generated/models/agent_run_stream_request.py b/seclai/_generated/models/agent_run_stream_request.py index c3f68b4..003fb80 100644 --- a/seclai/_generated/models/agent_run_stream_request.py +++ b/seclai/_generated/models/agent_run_stream_request.py @@ -24,12 +24,13 @@ class AgentRunStreamRequest: Attributes: input_ (None | str | Unset): Input to provide to the agent upon running for agents with dynamic triggers. input_upload_id (None | Unset | UUID): ID of a previously uploaded file (via POST /{agent_id}/upload-input) to - use as the run input for dynamic-input triggers. Mutually exclusive with the 'input' field. Use - ``input_upload_ids`` to attach multiple files. Subject to the same per-batch attachment-selector validation as - the non-streaming endpoint. + use as the run input for dynamic-input triggers. Mutually exclusive with ``input_upload_ids`` — use that field + to attach multiple files. May be combined with ``input``. Subject to the same per-batch attachment-selector + validation as the non-streaming endpoint. input_upload_ids (list[UUID] | None | Unset): IDs of multiple previously uploaded files. See the non-streaming endpoint for full semantics, including per-batch selector validation (exact names, indexed references, and glob - patterns must all be satisfied or the run is rejected with HTTP 400). Max 20. + patterns must all be satisfied or the run is rejected with HTTP 400) and combining the batch with ``input`` + prompt text. Max 20. metadata (AgentRunStreamRequestMetadataType0 | None | Unset): Metadata to make available for string substitution expressions in agent tasks. replay_of_run_id (None | Unset | UUID): Re-run reusing a prior run's uploaded input files (re-resolved server- diff --git a/seclai/_generated/models/agent_run_tool_call_response.py b/seclai/_generated/models/agent_run_tool_call_response.py index 375f3fb..10fb98c 100644 --- a/seclai/_generated/models/agent_run_tool_call_response.py +++ b/seclai/_generated/models/agent_run_tool_call_response.py @@ -25,7 +25,8 @@ class AgentRunToolCallResponse: input_ (None | str | Unset): JSON arguments the LLM passed to the tool, if persisted. output (None | str | Unset): JSON result the tool returned to the LLM, if persisted. round_index (int | Unset): 0-based tool-loop round this call belonged to. Default: 0. - sequence (int | Unset): 0-based ordinal of this call within its step run. Default: 0. + sequence (int | Unset): 0-based ordinal of this call within one attempt of the step, so it repeats across a + retried step's attempts. This list holds the latest attempt only. Default: 0. started_at (None | str | Unset): Timestamp when the tool call started. succeeded (bool | Unset): Whether the tool call completed without error. Default: True. """ diff --git a/seclai/_generated/models/agent_using_cloud_drive_response_model.py b/seclai/_generated/models/agent_using_cloud_drive_response_model.py new file mode 100644 index 0000000..c0387b1 --- /dev/null +++ b/seclai/_generated/models/agent_using_cloud_drive_response_model.py @@ -0,0 +1,93 @@ +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="AgentUsingCloudDriveResponseModel") + + +@_attrs_define +class AgentUsingCloudDriveResponseModel: + """ + Attributes: + agent_id (str): Agent identifier. + agent_name (str): Agent name. + trigger_types (list[str]): File-change trigger types bound to this drive. + via_prompt_tool (bool): Uses a prompt_call cloud-drive tool. + via_step (bool): Uses a list/read/write cloud-drive step. + """ + + agent_id: str + agent_name: str + trigger_types: list[str] + via_prompt_tool: bool + via_step: bool + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + agent_id = self.agent_id + + agent_name = self.agent_name + + trigger_types = self.trigger_types + + via_prompt_tool = self.via_prompt_tool + + via_step = self.via_step + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "agent_id": agent_id, + "agent_name": agent_name, + "trigger_types": trigger_types, + "via_prompt_tool": via_prompt_tool, + "via_step": via_step, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + agent_id = d.pop("agent_id") + + agent_name = d.pop("agent_name") + + trigger_types = cast(list[str], d.pop("trigger_types")) + + via_prompt_tool = d.pop("via_prompt_tool") + + via_step = d.pop("via_step") + + agent_using_cloud_drive_response_model = cls( + agent_id=agent_id, + agent_name=agent_name, + trigger_types=trigger_types, + via_prompt_tool=via_prompt_tool, + via_step=via_step, + ) + + agent_using_cloud_drive_response_model.additional_properties = d + return agent_using_cloud_drive_response_model + + @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/seclai/_generated/models/ai_assistant_feedback_request.py b/seclai/_generated/models/ai_assistant_feedback_request.py index 0bf4264..dde3c00 100644 --- a/seclai/_generated/models/ai_assistant_feedback_request.py +++ b/seclai/_generated/models/ai_assistant_feedback_request.py @@ -29,6 +29,7 @@ class AiAssistantFeedbackRequest: comment (None | str | Unset): Optional comment. context (AiAssistantFeedbackRequestContextType0 | None | Unset): Additional context. conversation_id (None | Unset | UUID): Conversation ID for the interaction. + governance_conversation_id (None | Unset | UUID): Governance conversation ID, if applicable. prompt_call_id (None | Unset | UUID): Prompt call ID for credit tracking. """ @@ -38,6 +39,7 @@ class AiAssistantFeedbackRequest: comment: None | str | Unset = UNSET context: AiAssistantFeedbackRequestContextType0 | None | Unset = UNSET conversation_id: None | Unset | UUID = UNSET + governance_conversation_id: None | Unset | UUID = UNSET prompt_call_id: None | Unset | UUID = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -80,6 +82,14 @@ def to_dict(self) -> dict[str, Any]: else: conversation_id = self.conversation_id + governance_conversation_id: None | str | Unset + if isinstance(self.governance_conversation_id, Unset): + governance_conversation_id = UNSET + elif isinstance(self.governance_conversation_id, UUID): + governance_conversation_id = str(self.governance_conversation_id) + else: + governance_conversation_id = self.governance_conversation_id + prompt_call_id: None | str | Unset if isinstance(self.prompt_call_id, Unset): prompt_call_id = UNSET @@ -104,6 +114,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["context"] = context if conversation_id is not UNSET: field_dict["conversation_id"] = conversation_id + if governance_conversation_id is not UNSET: + field_dict["governance_conversation_id"] = governance_conversation_id if prompt_call_id is not UNSET: field_dict["prompt_call_id"] = prompt_call_id @@ -184,6 +196,25 @@ def _parse_conversation_id(data: object) -> None | Unset | UUID: conversation_id = _parse_conversation_id(d.pop("conversation_id", UNSET)) + def _parse_governance_conversation_id(data: object) -> None | Unset | UUID: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + governance_conversation_id_type_0 = UUID(data) + + return governance_conversation_id_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | Unset | UUID, data) + + governance_conversation_id = _parse_governance_conversation_id( + d.pop("governance_conversation_id", UNSET) + ) + def _parse_prompt_call_id(data: object) -> None | Unset | UUID: if data is None: return data @@ -208,6 +239,7 @@ def _parse_prompt_call_id(data: object) -> None | Unset | UUID: comment=comment, context=context, conversation_id=conversation_id, + governance_conversation_id=governance_conversation_id, prompt_call_id=prompt_call_id, ) diff --git a/seclai/_generated/models/cloud_drive_access_level_response_model.py b/seclai/_generated/models/cloud_drive_access_level_response_model.py new file mode 100644 index 0000000..c1270e7 --- /dev/null +++ b/seclai/_generated/models/cloud_drive_access_level_response_model.py @@ -0,0 +1,85 @@ +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="CloudDriveAccessLevelResponseModel") + + +@_attrs_define +class CloudDriveAccessLevelResponseModel: + """ + Attributes: + default (bool): Whether connecting without a choice uses it. + description (str): What agents can do at this level. + key (str): Level identifier, e.g. `read_write`/`read_only`. + label (str): Short human-readable name. + """ + + default: bool + description: str + key: str + label: str + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + default = self.default + + description = self.description + + key = self.key + + label = self.label + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "default": default, + "description": description, + "key": key, + "label": label, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + default = d.pop("default") + + description = d.pop("description") + + key = d.pop("key") + + label = d.pop("label") + + cloud_drive_access_level_response_model = cls( + default=default, + description=description, + key=key, + label=label, + ) + + cloud_drive_access_level_response_model.additional_properties = d + return cloud_drive_access_level_response_model + + @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/seclai/_generated/models/cloud_drive_provider_response_model.py b/seclai/_generated/models/cloud_drive_provider_response_model.py new file mode 100644 index 0000000..1d15a59 --- /dev/null +++ b/seclai/_generated/models/cloud_drive_provider_response_model.py @@ -0,0 +1,119 @@ +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 + +if TYPE_CHECKING: + from ..models.cloud_drive_access_level_response_model import ( + CloudDriveAccessLevelResponseModel, + ) + from ..models.cloud_drive_scope_response_model import CloudDriveScopeResponseModel + + +T = TypeVar("T", bound="CloudDriveProviderResponseModel") + + +@_attrs_define +class CloudDriveProviderResponseModel: + """ + Attributes: + access_levels (list[CloudDriveAccessLevelResponseModel]): Mutually-exclusive permission bundles offered when + connecting. Connecting happens in the app, so this is informational here — it explains what a connection's + `access_level` can be. + display_name (str): Human-readable provider name. + key (str): Provider key used as `provider` on a connection. + scopes (list[CloudDriveScopeResponseModel]): OAuth permissions this provider can request. + """ + + access_levels: list[CloudDriveAccessLevelResponseModel] + display_name: str + key: str + scopes: list[CloudDriveScopeResponseModel] + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + access_levels = [] + for access_levels_item_data in self.access_levels: + access_levels_item = access_levels_item_data.to_dict() + access_levels.append(access_levels_item) + + display_name = self.display_name + + key = self.key + + scopes = [] + for scopes_item_data in self.scopes: + scopes_item = scopes_item_data.to_dict() + scopes.append(scopes_item) + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "access_levels": access_levels, + "display_name": display_name, + "key": key, + "scopes": scopes, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.cloud_drive_access_level_response_model import ( + CloudDriveAccessLevelResponseModel, + ) + from ..models.cloud_drive_scope_response_model import ( + CloudDriveScopeResponseModel, + ) + + d = dict(src_dict) + access_levels = [] + _access_levels = d.pop("access_levels") + for access_levels_item_data in _access_levels: + access_levels_item = CloudDriveAccessLevelResponseModel.from_dict( + access_levels_item_data + ) + + access_levels.append(access_levels_item) + + display_name = d.pop("display_name") + + key = d.pop("key") + + scopes = [] + _scopes = d.pop("scopes") + for scopes_item_data in _scopes: + scopes_item = CloudDriveScopeResponseModel.from_dict(scopes_item_data) + + scopes.append(scopes_item) + + cloud_drive_provider_response_model = cls( + access_levels=access_levels, + display_name=display_name, + key=key, + scopes=scopes, + ) + + cloud_drive_provider_response_model.additional_properties = d + return cloud_drive_provider_response_model + + @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/seclai/_generated/models/cloud_drive_rejection_response_model.py b/seclai/_generated/models/cloud_drive_rejection_response_model.py new file mode 100644 index 0000000..5eacd45 --- /dev/null +++ b/seclai/_generated/models/cloud_drive_rejection_response_model.py @@ -0,0 +1,140 @@ +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 + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="CloudDriveRejectionResponseModel") + + +@_attrs_define +class CloudDriveRejectionResponseModel: + """One file the connection deliberately did not process. + + Attributes: + created_at (str): When the file was skipped. + id (str): Rejection identifier. + reason (str): `too_large`, `download_failed`, or `flood`. + detail (None | str | Unset): Extra context, e.g. the cap that was hit. + file_id (None | str | Unset): The provider's file id, when the file was known. + file_path (None | str | Unset): Path of the skipped file, when known. + """ + + created_at: str + id: str + reason: str + detail: None | str | Unset = UNSET + file_id: None | str | Unset = UNSET + file_path: None | str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + created_at = self.created_at + + id = self.id + + reason = self.reason + + detail: None | str | Unset + if isinstance(self.detail, Unset): + detail = UNSET + else: + detail = self.detail + + file_id: None | str | Unset + if isinstance(self.file_id, Unset): + file_id = UNSET + else: + file_id = self.file_id + + file_path: None | str | Unset + if isinstance(self.file_path, Unset): + file_path = UNSET + else: + file_path = self.file_path + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "created_at": created_at, + "id": id, + "reason": reason, + } + ) + if detail is not UNSET: + field_dict["detail"] = detail + if file_id is not UNSET: + field_dict["file_id"] = file_id + if file_path is not UNSET: + field_dict["file_path"] = file_path + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + created_at = d.pop("created_at") + + id = d.pop("id") + + reason = d.pop("reason") + + def _parse_detail(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + detail = _parse_detail(d.pop("detail", UNSET)) + + def _parse_file_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + file_id = _parse_file_id(d.pop("file_id", UNSET)) + + def _parse_file_path(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + file_path = _parse_file_path(d.pop("file_path", UNSET)) + + cloud_drive_rejection_response_model = cls( + created_at=created_at, + id=id, + reason=reason, + detail=detail, + file_id=file_id, + file_path=file_path, + ) + + cloud_drive_rejection_response_model.additional_properties = d + return cloud_drive_rejection_response_model + + @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/seclai/_generated/models/cloud_drive_response_model.py b/seclai/_generated/models/cloud_drive_response_model.py new file mode 100644 index 0000000..291c73a --- /dev/null +++ b/seclai/_generated/models/cloud_drive_response_model.py @@ -0,0 +1,298 @@ +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 + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="CloudDriveResponseModel") + + +@_attrs_define +class CloudDriveResponseModel: + """A cloud-drive connection, without any secret material. + + Attributes: + connected (bool): True when the connection is usable. + created_at (str): When the connection was created. + drive_name_stale (bool): True when `drive_name` could not be re-confirmed (the drive was deleted, access was + lost, or the provider was unreachable). The last known name is still reported — treat it as possibly out of date + rather than current. + folder_path (str): Watched folder; empty string means the drive root. A folder on a shared drive is written + `/Shared drives//`. + id (str): Connection identifier. + provider (str): Provider key, e.g. `dropbox` or `google_drive`. + realtime_updates (bool): True when changes arrive via the provider's push notifications. False means the drive + still syncs, but only on the scheduled backstop sweep rather than within seconds of a change. + status (str): One of `active`, `pending_auth`, `error`, `disconnected`. + updated_at (str): When the connection was last modified. + access_level (None | str | Unset): The permission bundle the granted scopes correspond to — `read_write` or + `read_only`. Null when the grant matches no level the provider currently offers; treat that as unknown rather + than assuming write access. + drive_id (None | str | Unset): Opaque id of the shared drive the folder resolves to, or null for the user's own + drive. Stable across renames — compare on this rather than on the name in `folder_path`. + drive_name (None | str | Unset): Display name the shared drive last resolved to. Presentation only; never match + on it. + external_account_id (None | str | Unset): The provider's own opaque account identifier (never an email). + last_error (None | str | Unset): Most recent sync or authorization error, if any. + last_synced_at (None | str | Unset): When the connection last synced successfully. + name (None | str | Unset): Human-readable name. + oauth_scopes (None | str | Unset): Space-separated OAuth scopes granted to this connection. + """ + + connected: bool + created_at: str + drive_name_stale: bool + folder_path: str + id: str + provider: str + realtime_updates: bool + status: str + updated_at: str + access_level: None | str | Unset = UNSET + drive_id: None | str | Unset = UNSET + drive_name: None | str | Unset = UNSET + external_account_id: None | str | Unset = UNSET + last_error: None | str | Unset = UNSET + last_synced_at: None | str | Unset = UNSET + name: None | str | Unset = UNSET + oauth_scopes: None | str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + connected = self.connected + + created_at = self.created_at + + drive_name_stale = self.drive_name_stale + + folder_path = self.folder_path + + id = self.id + + provider = self.provider + + realtime_updates = self.realtime_updates + + status = self.status + + updated_at = self.updated_at + + access_level: None | str | Unset + if isinstance(self.access_level, Unset): + access_level = UNSET + else: + access_level = self.access_level + + drive_id: None | str | Unset + if isinstance(self.drive_id, Unset): + drive_id = UNSET + else: + drive_id = self.drive_id + + drive_name: None | str | Unset + if isinstance(self.drive_name, Unset): + drive_name = UNSET + else: + drive_name = self.drive_name + + external_account_id: None | str | Unset + if isinstance(self.external_account_id, Unset): + external_account_id = UNSET + else: + external_account_id = self.external_account_id + + last_error: None | str | Unset + if isinstance(self.last_error, Unset): + last_error = UNSET + else: + last_error = self.last_error + + last_synced_at: None | str | Unset + if isinstance(self.last_synced_at, Unset): + last_synced_at = UNSET + else: + last_synced_at = self.last_synced_at + + name: None | str | Unset + if isinstance(self.name, Unset): + name = UNSET + else: + name = self.name + + oauth_scopes: None | str | Unset + if isinstance(self.oauth_scopes, Unset): + oauth_scopes = UNSET + else: + oauth_scopes = self.oauth_scopes + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "connected": connected, + "created_at": created_at, + "drive_name_stale": drive_name_stale, + "folder_path": folder_path, + "id": id, + "provider": provider, + "realtime_updates": realtime_updates, + "status": status, + "updated_at": updated_at, + } + ) + if access_level is not UNSET: + field_dict["access_level"] = access_level + if drive_id is not UNSET: + field_dict["drive_id"] = drive_id + if drive_name is not UNSET: + field_dict["drive_name"] = drive_name + if external_account_id is not UNSET: + field_dict["external_account_id"] = external_account_id + if last_error is not UNSET: + field_dict["last_error"] = last_error + if last_synced_at is not UNSET: + field_dict["last_synced_at"] = last_synced_at + if name is not UNSET: + field_dict["name"] = name + if oauth_scopes is not UNSET: + field_dict["oauth_scopes"] = oauth_scopes + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + connected = d.pop("connected") + + created_at = d.pop("created_at") + + drive_name_stale = d.pop("drive_name_stale") + + folder_path = d.pop("folder_path") + + id = d.pop("id") + + provider = d.pop("provider") + + realtime_updates = d.pop("realtime_updates") + + status = d.pop("status") + + updated_at = d.pop("updated_at") + + def _parse_access_level(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + access_level = _parse_access_level(d.pop("access_level", UNSET)) + + def _parse_drive_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + drive_id = _parse_drive_id(d.pop("drive_id", UNSET)) + + def _parse_drive_name(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + drive_name = _parse_drive_name(d.pop("drive_name", UNSET)) + + def _parse_external_account_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + external_account_id = _parse_external_account_id( + d.pop("external_account_id", UNSET) + ) + + def _parse_last_error(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + last_error = _parse_last_error(d.pop("last_error", UNSET)) + + def _parse_last_synced_at(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + last_synced_at = _parse_last_synced_at(d.pop("last_synced_at", UNSET)) + + def _parse_name(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + name = _parse_name(d.pop("name", UNSET)) + + def _parse_oauth_scopes(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + oauth_scopes = _parse_oauth_scopes(d.pop("oauth_scopes", UNSET)) + + cloud_drive_response_model = cls( + connected=connected, + created_at=created_at, + drive_name_stale=drive_name_stale, + folder_path=folder_path, + id=id, + provider=provider, + realtime_updates=realtime_updates, + status=status, + updated_at=updated_at, + access_level=access_level, + drive_id=drive_id, + drive_name=drive_name, + external_account_id=external_account_id, + last_error=last_error, + last_synced_at=last_synced_at, + name=name, + oauth_scopes=oauth_scopes, + ) + + cloud_drive_response_model.additional_properties = d + return cloud_drive_response_model + + @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/seclai/_generated/models/cloud_drive_scope_response_model.py b/seclai/_generated/models/cloud_drive_scope_response_model.py new file mode 100644 index 0000000..b279b71 --- /dev/null +++ b/seclai/_generated/models/cloud_drive_scope_response_model.py @@ -0,0 +1,85 @@ +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="CloudDriveScopeResponseModel") + + +@_attrs_define +class CloudDriveScopeResponseModel: + """ + Attributes: + description (str): What the scope allows. + key (str): The OAuth scope string sent to the provider. + label (str): Short human-readable name. + recommended (bool): Whether this scope is requested by default on connect. + """ + + description: str + key: str + label: str + recommended: bool + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + description = self.description + + key = self.key + + label = self.label + + recommended = self.recommended + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "description": description, + "key": key, + "label": label, + "recommended": recommended, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + description = d.pop("description") + + key = d.pop("key") + + label = d.pop("label") + + recommended = d.pop("recommended") + + cloud_drive_scope_response_model = cls( + description=description, + key=key, + label=label, + recommended=recommended, + ) + + cloud_drive_scope_response_model.additional_properties = d + return cloud_drive_scope_response_model + + @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/seclai/_generated/models/cloud_drive_update_request.py b/seclai/_generated/models/cloud_drive_update_request.py new file mode 100644 index 0000000..ae75ed0 --- /dev/null +++ b/seclai/_generated/models/cloud_drive_update_request.py @@ -0,0 +1,96 @@ +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 + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="CloudDriveUpdateRequest") + + +@_attrs_define +class CloudDriveUpdateRequest: + """ + Attributes: + folder_path (None | str | Unset): New watched folder; empty means the whole drive. A folder on a shared drive is + written `/Shared drives//`. Changing it resets the sync cursor, so files already in the new + folder are NOT replayed as triggers — only subsequent changes fire, matching connect-time behaviour. Rejected + when the new folder would make an agent that writes there re-trigger itself. + name (None | str | Unset): New display name for the connection. + """ + + folder_path: None | str | Unset = UNSET + name: None | str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + folder_path: None | str | Unset + if isinstance(self.folder_path, Unset): + folder_path = UNSET + else: + folder_path = self.folder_path + + name: None | str | Unset + if isinstance(self.name, Unset): + name = UNSET + else: + name = self.name + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if folder_path is not UNSET: + field_dict["folder_path"] = folder_path + if name is not UNSET: + field_dict["name"] = name + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + + def _parse_folder_path(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + folder_path = _parse_folder_path(d.pop("folder_path", UNSET)) + + def _parse_name(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + name = _parse_name(d.pop("name", UNSET)) + + cloud_drive_update_request = cls( + folder_path=folder_path, + name=name, + ) + + cloud_drive_update_request.additional_properties = d + return cloud_drive_update_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/seclai/_generated/models/content_detail_response.py b/seclai/_generated/models/content_detail_response.py index 7e5fbff..ea34be0 100644 --- a/seclai/_generated/models/content_detail_response.py +++ b/seclai/_generated/models/content_detail_response.py @@ -6,6 +6,8 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..types import UNSET, Unset + if TYPE_CHECKING: from ..models.content_detail_response_metadata_type_0_item import ( ContentDetailResponseMetadataType0Item, @@ -42,6 +44,18 @@ class ContentDetailResponse: text_content_start (int): Start position of the text content. text_content_total_length (int): Total length of the text content. title (None | str): Title of the content. + extracted_media_capped (bool | Unset): True when extraction stopped with media still unread, so the item + references more media than was indexed and media search will not match anything past the cut. Two causes: a web + page that ran out of the budget for fetching remote assets, or a container that could not be read to the end (a + truncated or hostile archive). An uploaded document that reads cleanly is never capped, however much media it + holds — there is no limit on that. Default: False. + extracted_media_count (int | None | Unset): Number of embedded images / videos extracted from inside this item + and indexed as their own chunks. There is no limit on this — a document contributes as many as it holds. Null + when there is no media record for the item: the extraction pass has not run, does not apply to this container, + or found nothing. Treat null as 'unknown', never as zero. + extracted_media_limit (int | None | Unset): The bound that was reached, when extracted_media_capped is true and + the stop was a bound — a number of fetch attempts, or a number of seconds. Null when extraction was not capped, + or when it stopped because the container could not be read rather than because a bound fired. """ content_duration: int | None @@ -66,6 +80,9 @@ class ContentDetailResponse: text_content_start: int text_content_total_length: int title: None | str + extracted_media_capped: bool | Unset = False + extracted_media_count: int | None | Unset = UNSET + extracted_media_limit: int | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -129,6 +146,20 @@ def to_dict(self) -> dict[str, Any]: title: None | str title = self.title + extracted_media_capped = self.extracted_media_capped + + extracted_media_count: int | None | Unset + if isinstance(self.extracted_media_count, Unset): + extracted_media_count = UNSET + else: + extracted_media_count = self.extracted_media_count + + extracted_media_limit: int | None | Unset + if isinstance(self.extracted_media_limit, Unset): + extracted_media_limit = UNSET + else: + extracted_media_limit = self.extracted_media_limit + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -157,6 +188,12 @@ def to_dict(self) -> dict[str, Any]: "title": title, } ) + if extracted_media_capped is not UNSET: + field_dict["extracted_media_capped"] = extracted_media_capped + if extracted_media_count is not UNSET: + field_dict["extracted_media_count"] = extracted_media_count + if extracted_media_limit is not UNSET: + field_dict["extracted_media_limit"] = extracted_media_limit return field_dict @@ -280,6 +317,30 @@ def _parse_title(data: object) -> None | str: title = _parse_title(d.pop("title")) + extracted_media_capped = d.pop("extracted_media_capped", UNSET) + + def _parse_extracted_media_count(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + extracted_media_count = _parse_extracted_media_count( + d.pop("extracted_media_count", UNSET) + ) + + def _parse_extracted_media_limit(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + extracted_media_limit = _parse_extracted_media_limit( + d.pop("extracted_media_limit", UNSET) + ) + content_detail_response = cls( content_duration=content_duration, content_duration_display=content_duration_display, @@ -303,6 +364,9 @@ def _parse_title(data: object) -> None | str: text_content_start=text_content_start, text_content_total_length=text_content_total_length, title=title, + extracted_media_capped=extracted_media_capped, + extracted_media_count=extracted_media_count, + extracted_media_limit=extracted_media_limit, ) content_detail_response.additional_properties = d diff --git a/seclai/_generated/models/content_embedding_response.py b/seclai/_generated/models/content_embedding_response.py index ea22bf7..b12f233 100644 --- a/seclai/_generated/models/content_embedding_response.py +++ b/seclai/_generated/models/content_embedding_response.py @@ -6,6 +6,8 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..types import UNSET, Unset + T = TypeVar("T", bound="ContentEmbeddingResponse") @@ -21,6 +23,10 @@ class ContentEmbeddingResponse: text_end (int): text_start (int): vector (list[float]): + media_name (None | str | Unset): + page_number (int | None | Unset): + source_mime (None | str | Unset): + source_url (None | str | Unset): """ batch_duration: float @@ -30,6 +36,10 @@ class ContentEmbeddingResponse: text_end: int text_start: int vector: list[float] + media_name: None | str | Unset = UNSET + page_number: int | None | Unset = UNSET + source_mime: None | str | Unset = UNSET + source_url: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -47,6 +57,30 @@ def to_dict(self) -> dict[str, Any]: vector = self.vector + media_name: None | str | Unset + if isinstance(self.media_name, Unset): + media_name = UNSET + else: + media_name = self.media_name + + page_number: int | None | Unset + if isinstance(self.page_number, Unset): + page_number = UNSET + else: + page_number = self.page_number + + source_mime: None | str | Unset + if isinstance(self.source_mime, Unset): + source_mime = UNSET + else: + source_mime = self.source_mime + + source_url: None | str | Unset + if isinstance(self.source_url, Unset): + source_url = UNSET + else: + source_url = self.source_url + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -60,6 +94,14 @@ def to_dict(self) -> dict[str, Any]: "vector": vector, } ) + if media_name is not UNSET: + field_dict["media_name"] = media_name + if page_number is not UNSET: + field_dict["page_number"] = page_number + if source_mime is not UNSET: + field_dict["source_mime"] = source_mime + if source_url is not UNSET: + field_dict["source_url"] = source_url return field_dict @@ -80,6 +122,42 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: vector = cast(list[float], d.pop("vector")) + def _parse_media_name(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + media_name = _parse_media_name(d.pop("media_name", UNSET)) + + def _parse_page_number(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + page_number = _parse_page_number(d.pop("page_number", UNSET)) + + def _parse_source_mime(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + source_mime = _parse_source_mime(d.pop("source_mime", UNSET)) + + def _parse_source_url(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + source_url = _parse_source_url(d.pop("source_url", UNSET)) + content_embedding_response = cls( batch_duration=batch_duration, batch_size=batch_size, @@ -88,6 +166,10 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: text_end=text_end, text_start=text_start, vector=vector, + media_name=media_name, + page_number=page_number, + source_mime=source_mime, + source_url=source_url, ) content_embedding_response.additional_properties = d diff --git a/seclai/_generated/models/create_alert_config_request.py b/seclai/_generated/models/create_alert_config_request.py index aacc073..2d9d184 100644 --- a/seclai/_generated/models/create_alert_config_request.py +++ b/seclai/_generated/models/create_alert_config_request.py @@ -23,7 +23,8 @@ class CreateAlertConfigRequest: Attributes: alert_type (str): Alert type agent_id (None | str | Unset): Agent ID (for agent alerts) - cooldown_minutes (int | Unset): Cooldown period in minutes Default: 60. + cooldown_minutes (int | None | Unset): Cooldown period in minutes. Omit to use the per-alert-type default (1440 + for credit alerts, 60 otherwise). distribution_type (str | Unset): Distribution type (owner, owner_admins, selected_members) Default: 'owner'. enabled (bool | Unset): Whether the alert config is enabled Default: True. recipient_user_ids (list[str] | None | Unset): User IDs for selected_members distribution @@ -33,7 +34,7 @@ class CreateAlertConfigRequest: alert_type: str agent_id: None | str | Unset = UNSET - cooldown_minutes: int | Unset = 60 + cooldown_minutes: int | None | Unset = UNSET distribution_type: str | Unset = "owner" enabled: bool | Unset = True recipient_user_ids: list[str] | None | Unset = UNSET @@ -54,7 +55,11 @@ def to_dict(self) -> dict[str, Any]: else: agent_id = self.agent_id - cooldown_minutes = self.cooldown_minutes + cooldown_minutes: int | None | Unset + if isinstance(self.cooldown_minutes, Unset): + cooldown_minutes = UNSET + else: + cooldown_minutes = self.cooldown_minutes distribution_type = self.distribution_type @@ -125,7 +130,14 @@ def _parse_agent_id(data: object) -> None | str | Unset: agent_id = _parse_agent_id(d.pop("agent_id", UNSET)) - cooldown_minutes = d.pop("cooldown_minutes", UNSET) + def _parse_cooldown_minutes(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + cooldown_minutes = _parse_cooldown_minutes(d.pop("cooldown_minutes", UNSET)) distribution_type = d.pop("distribution_type", UNSET) diff --git a/seclai/_generated/models/create_knowledge_base_body.py b/seclai/_generated/models/create_knowledge_base_body.py index ab3e793..2ebec19 100644 --- a/seclai/_generated/models/create_knowledge_base_body.py +++ b/seclai/_generated/models/create_knowledge_base_body.py @@ -18,11 +18,17 @@ class CreateKnowledgeBaseBody: Attributes: name (str): Knowledge base name. source_ids (list[str]): List of source connection IDs to link. - default_score_threshold (float | None | Unset): Default minimum rerank score threshold. - default_top_k (int | None | Unset): Default results after reranking. - default_top_n (int | None | Unset): Default number of results. + default_score_threshold (float | None | Unset): Prefilled into Minimum Rerank Score on a new retrieval step in + the editor. Not applied at retrieval time — the step's own value is used. + default_top_k (int | None | Unset): Prefilled into Top K on a new retrieval step in the editor. Not applied at + retrieval time. + default_top_n (int | None | Unset): Prefilled into Top N on a new retrieval step in the editor. Not applied at + retrieval time — the step's own value is used. description (None | str | Unset): Optional description. - reranker_model (None | str | Unset): Reranker model to use (null for no reranking). + reranker_model (None | str | Unset): Reranker model to use — a `model_type` from `GET /models/rerankers`. Pass + "none" to disable reranking (not a value from that list). Omit it for a default chosen from the sources ("none" + when every source embeds media natively, whose chunks carry no text for a reranker to score). "" is accepted as + a synonym for "none". """ name: str diff --git a/seclai/_generated/models/create_memory_bank_body.py b/seclai/_generated/models/create_memory_bank_body.py index 9526b45..34dc514 100644 --- a/seclai/_generated/models/create_memory_bank_body.py +++ b/seclai/_generated/models/create_memory_bank_body.py @@ -24,15 +24,29 @@ class CreateMemoryBankBody: description (None | str | Unset): Optional description of the bank's purpose. dimensions (int | None | Unset): Embedding dimensions (custom mode only). embedding_model (None | str | Unset): Custom embedding model (custom mode only). - max_age_days (int | None | Unset): Max entry age in days before compaction. Checked inline after each write and - by the hourly background sweep. + max_age_days (int | None | Unset): DEPRECATED and no longer applied. Age used to trigger compaction, which + duplicated retention_days — both removed the same entries at the same age. Age now belongs solely to + retention_days, which deletes; compaction triggers on max_size_tokens and max_turns. Rejected with 400 for + clients sending Seclai-Version 2026-08-03 or later; accepted and stored but inert for older clients. max_size_tokens (int | None | Unset): Max total tokens (per partition) before compaction. Checked inline after each write and by the hourly background sweep. max_turns (int | None | Unset): Max conversation turns (per partition) before compaction. Checked inline after each write and by the hourly background sweep. mode (str | Unset): Embedding quality / cost trade-off. One of: fast_and_cheap, balanced, slow_and_thorough, custom. Default: 'fast_and_cheap'. - retention_days (int | None | Unset): Content source retention in days. Default: 30. + retention_days (int | None | Unset): Retention in days — when entries are deleted outright, text and embeddings. + This is the only age-based control; compaction triggers on max_size_tokens and max_turns. For clients sending + Seclai-Version 2026-08-03 or later, omitting the field resolves per bank type: 90 days for a conversation bank, + indefinite for a general bank. Older clients keep the previous default of 30 days for a conversation bank — + unless a longer max_age_days was sent, which wins, since the window is never lowered beneath the only age the + caller expressed — while a general bank keeps entries indefinitely. Send an explicit value (or null for + indefinite) to be unambiguous on every version. + strip_quoted_reply_chains (bool | Unset): Conversation banks only. When true, a conversation turn written to + this bank has the quoted reply chain an email client prepends to a reply dropped from it. Only inbound (user) + turns are affected, and only words in a run of at least ~40 matching a recent turn word for word are dropped + (line wrapping and punctuation at a word's edge are ignored). A word the sender changed is kept, including a + one-character change inside a link, address or amount, unless the change is only to that edge punctuation. + Default: False. type_ (str | Unset): Bank type. 'conversation' for chat-turn data with conversation_key + speaker; 'general' for flat entries with optional group_key. Default: 'conversation'. """ @@ -48,7 +62,8 @@ class CreateMemoryBankBody: max_size_tokens: int | None | Unset = UNSET max_turns: int | None | Unset = UNSET mode: str | Unset = "fast_and_cheap" - retention_days: int | None | Unset = 30 + retention_days: int | None | Unset = UNSET + strip_quoted_reply_chains: bool | Unset = False type_: str | Unset = "conversation" additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -117,6 +132,8 @@ def to_dict(self) -> dict[str, Any]: else: retention_days = self.retention_days + strip_quoted_reply_chains = self.strip_quoted_reply_chains + type_ = self.type_ field_dict: dict[str, Any] = {} @@ -148,6 +165,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["mode"] = mode if retention_days is not UNSET: field_dict["retention_days"] = retention_days + if strip_quoted_reply_chains is not UNSET: + field_dict["strip_quoted_reply_chains"] = strip_quoted_reply_chains if type_ is not UNSET: field_dict["type"] = type_ @@ -250,6 +269,8 @@ def _parse_retention_days(data: object) -> int | None | Unset: retention_days = _parse_retention_days(d.pop("retention_days", UNSET)) + strip_quoted_reply_chains = d.pop("strip_quoted_reply_chains", UNSET) + type_ = d.pop("type", UNSET) create_memory_bank_body = cls( @@ -265,6 +286,7 @@ def _parse_retention_days(data: object) -> int | None | Unset: max_turns=max_turns, mode=mode, retention_days=retention_days, + strip_quoted_reply_chains=strip_quoted_reply_chains, type_=type_, ) diff --git a/seclai/_generated/models/create_source_body.py b/seclai/_generated/models/create_source_body.py index 41bb672..1c14469 100644 --- a/seclai/_generated/models/create_source_body.py +++ b/seclai/_generated/models/create_source_body.py @@ -24,12 +24,15 @@ class CreateSourceBody: chunk_size (int | None | Unset): Chunk size for content processing. content_filter (None | str | Unset): Content filter type. dimensions (int | None | Unset): Embedding dimensions override. - embedding_model (None | str | Unset): Embedding model override. + embedding_model (None | str | Unset): Embedding model override — a `model_type` from `GET /models/embedders`, + which also reports each embedder's `supported_input_media`. Defaults to the platform embedder + (`default_model_type` on that endpoint) when omitted. Indexing images or video requires an embedder that lists + that modality. index_mode (None | SourceIndexMode | Unset): Index mode for custom_index sources: fast_and_cheap (default), balanced, slow_and_thorough, or custom. media_types (list[str] | None | Unset): Media kinds to extract from indexed content and embed as multi-modal KB - chunks. Subset of ['images', 'video']. Only kinds the source's embedder can index are honored; unsupported - values are dropped. Omit / [] for text-only. + chunks. Subset of ['images', 'video']. Only kinds the source's embedder can index are honored (see + `supported_input_media` on GET /models/embedders); unsupported values are dropped. Omit / [] for text-only. polling (None | str | Unset): Polling interval (e.g. hourly, daily). polling_action (None | str | Unset): Polling action. polling_max_items (int | None | Unset): Max items per poll. diff --git a/seclai/_generated/models/effort_options_response.py b/seclai/_generated/models/effort_options_response.py new file mode 100644 index 0000000..789b579 --- /dev/null +++ b/seclai/_generated/models/effort_options_response.py @@ -0,0 +1,95 @@ +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 + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="EffortOptionsResponse") + + +@_attrs_define +class EffortOptionsResponse: + """The reasoning-effort values a model accepts. + + Attributes: + kind (str): `levels` today: `values` lists them. + default (None | str | Unset): The vendor's default level, when known. + values (list[str] | Unset): Accepted values, weakest first. + """ + + kind: str + default: None | str | Unset = UNSET + values: list[str] | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + kind = self.kind + + default: None | str | Unset + if isinstance(self.default, Unset): + default = UNSET + else: + default = self.default + + values: list[str] | Unset = UNSET + if not isinstance(self.values, Unset): + values = self.values + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "kind": kind, + } + ) + if default is not UNSET: + field_dict["default"] = default + if values is not UNSET: + field_dict["values"] = values + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + kind = d.pop("kind") + + def _parse_default(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + default = _parse_default(d.pop("default", UNSET)) + + values = cast(list[str], d.pop("values", UNSET)) + + effort_options_response = cls( + kind=kind, + default=default, + values=values, + ) + + effort_options_response.additional_properties = d + return effort_options_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/seclai/_generated/models/embedding_modality_rate_response.py b/seclai/_generated/models/embedding_modality_rate_response.py new file mode 100644 index 0000000..e0d2c12 --- /dev/null +++ b/seclai/_generated/models/embedding_modality_rate_response.py @@ -0,0 +1,85 @@ +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="EmbeddingModalityRateResponse") + + +@_attrs_define +class EmbeddingModalityRateResponse: + """Per-modality rate for a multi-modal embedder. + + The default ``credits`` field on :class:`EmbeddingModelResponse` is the + text rate (credits per ~1k English words). Embedders that index image or + video chunks natively charge those modalities at a different rate and unit + — e.g. Cohere Embed v4 prices images per record; Nova 2 Multimodal prices + video per second. Surfacing the modality and unit lets a caller render an + honest cost breakdown alongside the text rate. + + Attributes: + credits_ (float): Rate value in the unit below + modality (str): Modality kind, e.g. image / video + unit (str): Billing unit for this rate (credit_per_record / credit_per_second / credit_per_1000_tokens). + """ + + credits_: float + modality: str + unit: str + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + credits_ = self.credits_ + + modality = self.modality + + unit = self.unit + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "credits": credits_, + "modality": modality, + "unit": unit, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + credits_ = d.pop("credits") + + modality = d.pop("modality") + + unit = d.pop("unit") + + embedding_modality_rate_response = cls( + credits_=credits_, + modality=modality, + unit=unit, + ) + + embedding_modality_rate_response.additional_properties = d + return embedding_modality_rate_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/seclai/_generated/models/embedding_model_list_response.py b/seclai/_generated/models/embedding_model_list_response.py new file mode 100644 index 0000000..4a00a12 --- /dev/null +++ b/seclai/_generated/models/embedding_model_list_response.py @@ -0,0 +1,152 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.embedding_model_response import EmbeddingModelResponse + from ..models.embedding_storage_credits_response import ( + EmbeddingStorageCreditsResponse, + ) + + +T = TypeVar("T", bound="EmbeddingModelListResponse") + + +@_attrs_define +class EmbeddingModelListResponse: + """Legacy (header-less) response shape for the embedder catalog. + + Attributes: + file_processing_credits_per_mb (float): Credits per MB for file processing at ingest + models (list[EmbeddingModelResponse]): Available embedding models + storage_credits (list[EmbeddingStorageCreditsResponse]): Monthly storage credits per dimension count + default_dimension (int | None | Unset): Dimensions used with the default embedding model + default_model_type (None | str | Unset): Embedding model used when a source does not override it + """ + + file_processing_credits_per_mb: float + models: list[EmbeddingModelResponse] + storage_credits: list[EmbeddingStorageCreditsResponse] + default_dimension: int | None | Unset = UNSET + default_model_type: None | str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + file_processing_credits_per_mb = self.file_processing_credits_per_mb + + models = [] + for models_item_data in self.models: + models_item = models_item_data.to_dict() + models.append(models_item) + + storage_credits = [] + for storage_credits_item_data in self.storage_credits: + storage_credits_item = storage_credits_item_data.to_dict() + storage_credits.append(storage_credits_item) + + default_dimension: int | None | Unset + if isinstance(self.default_dimension, Unset): + default_dimension = UNSET + else: + default_dimension = self.default_dimension + + default_model_type: None | str | Unset + if isinstance(self.default_model_type, Unset): + default_model_type = UNSET + else: + default_model_type = self.default_model_type + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "file_processing_credits_per_mb": file_processing_credits_per_mb, + "models": models, + "storage_credits": storage_credits, + } + ) + if default_dimension is not UNSET: + field_dict["default_dimension"] = default_dimension + if default_model_type is not UNSET: + field_dict["default_model_type"] = default_model_type + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.embedding_model_response import EmbeddingModelResponse + from ..models.embedding_storage_credits_response import ( + EmbeddingStorageCreditsResponse, + ) + + d = dict(src_dict) + file_processing_credits_per_mb = d.pop("file_processing_credits_per_mb") + + models = [] + _models = d.pop("models") + for models_item_data in _models: + models_item = EmbeddingModelResponse.from_dict(models_item_data) + + models.append(models_item) + + storage_credits = [] + _storage_credits = d.pop("storage_credits") + for storage_credits_item_data in _storage_credits: + storage_credits_item = EmbeddingStorageCreditsResponse.from_dict( + storage_credits_item_data + ) + + storage_credits.append(storage_credits_item) + + def _parse_default_dimension(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + default_dimension = _parse_default_dimension(d.pop("default_dimension", UNSET)) + + def _parse_default_model_type(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + default_model_type = _parse_default_model_type( + d.pop("default_model_type", UNSET) + ) + + embedding_model_list_response = cls( + file_processing_credits_per_mb=file_processing_credits_per_mb, + models=models, + storage_credits=storage_credits, + default_dimension=default_dimension, + default_model_type=default_model_type, + ) + + embedding_model_list_response.additional_properties = d + return embedding_model_list_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/seclai/_generated/models/embedding_model_response.py b/seclai/_generated/models/embedding_model_response.py new file mode 100644 index 0000000..db09fb1 --- /dev/null +++ b/seclai/_generated/models/embedding_model_response.py @@ -0,0 +1,340 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.embedding_modality_rate_response import EmbeddingModalityRateResponse + + +T = TypeVar("T", bound="EmbeddingModelResponse") + + +@_attrs_define +class EmbeddingModelResponse: + """Information about an embedding model. + + Attributes: + credits_ (float): Estimated credits per 1,000 English words + dimensions (list[int]): Dimensions options + model_id (str): Model identifier + model_type (str): Full model type identifier (enum value). This is the value to send as embedding_model when + creating a source. + description (None | str | Unset): Model description + is_new (bool | Unset): Whether the model is newly released Default: False. + max_input_tokens (int | None | Unset): Max input tokens per request + mteb_retrieval_score (float | None | Unset): MTEB retrieval score + name (None | str | Unset): Human-readable model name + per_modality_rates (list[EmbeddingModalityRateResponse] | Unset): Non-text rates the vendor charges for this + embedder (image, video, audio). Empty for text-only embedders. + provider (None | str | Unset): Model provider identifier + speed (None | str | Unset): Model processing speed + supported_input_media (list[str] | None | Unset): Modalities the embedder accepts on input (short kinds like + text / image / video, or full MIMEs). null means text-only. A source only honours a media_types entry its + embedder lists here. + supported_languages (list[str] | None | Unset): Supported languages + url (None | str | Unset): Model documentation URL + """ + + credits_: float + dimensions: list[int] + model_id: str + model_type: str + description: None | str | Unset = UNSET + is_new: bool | Unset = False + max_input_tokens: int | None | Unset = UNSET + mteb_retrieval_score: float | None | Unset = UNSET + name: None | str | Unset = UNSET + per_modality_rates: list[EmbeddingModalityRateResponse] | Unset = UNSET + provider: None | str | Unset = UNSET + speed: None | str | Unset = UNSET + supported_input_media: list[str] | None | Unset = UNSET + supported_languages: list[str] | None | Unset = UNSET + url: None | str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + credits_ = self.credits_ + + dimensions = self.dimensions + + model_id = self.model_id + + model_type = self.model_type + + description: None | str | Unset + if isinstance(self.description, Unset): + description = UNSET + else: + description = self.description + + is_new = self.is_new + + max_input_tokens: int | None | Unset + if isinstance(self.max_input_tokens, Unset): + max_input_tokens = UNSET + else: + max_input_tokens = self.max_input_tokens + + mteb_retrieval_score: float | None | Unset + if isinstance(self.mteb_retrieval_score, Unset): + mteb_retrieval_score = UNSET + else: + mteb_retrieval_score = self.mteb_retrieval_score + + name: None | str | Unset + if isinstance(self.name, Unset): + name = UNSET + else: + name = self.name + + per_modality_rates: list[dict[str, Any]] | Unset = UNSET + if not isinstance(self.per_modality_rates, Unset): + per_modality_rates = [] + for per_modality_rates_item_data in self.per_modality_rates: + per_modality_rates_item = per_modality_rates_item_data.to_dict() + per_modality_rates.append(per_modality_rates_item) + + provider: None | str | Unset + if isinstance(self.provider, Unset): + provider = UNSET + else: + provider = self.provider + + speed: None | str | Unset + if isinstance(self.speed, Unset): + speed = UNSET + else: + speed = self.speed + + supported_input_media: list[str] | None | Unset + if isinstance(self.supported_input_media, Unset): + supported_input_media = UNSET + elif isinstance(self.supported_input_media, list): + supported_input_media = self.supported_input_media + + else: + supported_input_media = self.supported_input_media + + supported_languages: list[str] | None | Unset + if isinstance(self.supported_languages, Unset): + supported_languages = UNSET + elif isinstance(self.supported_languages, list): + supported_languages = self.supported_languages + + else: + supported_languages = self.supported_languages + + url: None | str | Unset + if isinstance(self.url, Unset): + url = UNSET + else: + url = self.url + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "credits": credits_, + "dimensions": dimensions, + "model_id": model_id, + "model_type": model_type, + } + ) + if description is not UNSET: + field_dict["description"] = description + if is_new is not UNSET: + field_dict["is_new"] = is_new + if max_input_tokens is not UNSET: + field_dict["max_input_tokens"] = max_input_tokens + if mteb_retrieval_score is not UNSET: + field_dict["mteb_retrieval_score"] = mteb_retrieval_score + if name is not UNSET: + field_dict["name"] = name + if per_modality_rates is not UNSET: + field_dict["per_modality_rates"] = per_modality_rates + if provider is not UNSET: + field_dict["provider"] = provider + if speed is not UNSET: + field_dict["speed"] = speed + if supported_input_media is not UNSET: + field_dict["supported_input_media"] = supported_input_media + if supported_languages is not UNSET: + field_dict["supported_languages"] = supported_languages + if url is not UNSET: + field_dict["url"] = url + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.embedding_modality_rate_response import ( + EmbeddingModalityRateResponse, + ) + + d = dict(src_dict) + credits_ = d.pop("credits") + + dimensions = cast(list[int], d.pop("dimensions")) + + model_id = d.pop("model_id") + + model_type = d.pop("model_type") + + def _parse_description(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + description = _parse_description(d.pop("description", UNSET)) + + is_new = d.pop("is_new", UNSET) + + def _parse_max_input_tokens(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + max_input_tokens = _parse_max_input_tokens(d.pop("max_input_tokens", UNSET)) + + def _parse_mteb_retrieval_score(data: object) -> float | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(float | None | Unset, data) + + mteb_retrieval_score = _parse_mteb_retrieval_score( + d.pop("mteb_retrieval_score", UNSET) + ) + + def _parse_name(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + name = _parse_name(d.pop("name", UNSET)) + + _per_modality_rates = d.pop("per_modality_rates", UNSET) + per_modality_rates: list[EmbeddingModalityRateResponse] | Unset = UNSET + if _per_modality_rates is not UNSET: + per_modality_rates = [] + for per_modality_rates_item_data in _per_modality_rates: + per_modality_rates_item = EmbeddingModalityRateResponse.from_dict( + per_modality_rates_item_data + ) + + per_modality_rates.append(per_modality_rates_item) + + def _parse_provider(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + provider = _parse_provider(d.pop("provider", UNSET)) + + def _parse_speed(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + speed = _parse_speed(d.pop("speed", UNSET)) + + def _parse_supported_input_media(data: object) -> list[str] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + supported_input_media_type_0 = cast(list[str], data) + + return supported_input_media_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + supported_input_media = _parse_supported_input_media( + d.pop("supported_input_media", UNSET) + ) + + def _parse_supported_languages(data: object) -> list[str] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + supported_languages_type_0 = cast(list[str], data) + + return supported_languages_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + supported_languages = _parse_supported_languages( + d.pop("supported_languages", UNSET) + ) + + def _parse_url(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + url = _parse_url(d.pop("url", UNSET)) + + embedding_model_response = cls( + credits_=credits_, + dimensions=dimensions, + model_id=model_id, + model_type=model_type, + description=description, + is_new=is_new, + max_input_tokens=max_input_tokens, + mteb_retrieval_score=mteb_retrieval_score, + name=name, + per_modality_rates=per_modality_rates, + provider=provider, + speed=speed, + supported_input_media=supported_input_media, + supported_languages=supported_languages, + url=url, + ) + + embedding_model_response.additional_properties = d + return embedding_model_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/seclai/_generated/models/embedding_storage_credits_response.py b/seclai/_generated/models/embedding_storage_credits_response.py new file mode 100644 index 0000000..c5dd359 --- /dev/null +++ b/seclai/_generated/models/embedding_storage_credits_response.py @@ -0,0 +1,70 @@ +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="EmbeddingStorageCreditsResponse") + + +@_attrs_define +class EmbeddingStorageCreditsResponse: + """Monthly storage credits per stored record at a dimension count. + + Attributes: + credits_ (int): Credits per record per month + dimensions (int): Number of embedding dimensions + """ + + credits_: int + dimensions: int + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + credits_ = self.credits_ + + dimensions = self.dimensions + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "credits": credits_, + "dimensions": dimensions, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + credits_ = d.pop("credits") + + dimensions = d.pop("dimensions") + + embedding_storage_credits_response = cls( + credits_=credits_, + dimensions=dimensions, + ) + + embedding_storage_credits_response.additional_properties = d + return embedding_storage_credits_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/seclai/_generated/models/experiment_detail_response.py b/seclai/_generated/models/experiment_detail_response.py index 61004e5..b7de7e3 100644 --- a/seclai/_generated/models/experiment_detail_response.py +++ b/seclai/_generated/models/experiment_detail_response.py @@ -6,7 +6,12 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..types import UNSET, Unset + if TYPE_CHECKING: + from ..models.experiment_detail_response_effort import ( + ExperimentDetailResponseEffort, + ) from ..models.experiment_detail_response_result_data_type_0 import ( ExperimentDetailResponseResultDataType0, ) @@ -38,6 +43,7 @@ class ExperimentDetailResponse: started_at (None | str): status (str): system_prompt (str): + effort (ExperimentDetailResponseEffort | Unset): The reasoning effort each model was run at, by model ID. """ completed_at: None | str @@ -59,6 +65,7 @@ class ExperimentDetailResponse: started_at: None | str status: str system_prompt: str + effort: ExperimentDetailResponseEffort | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -117,6 +124,10 @@ def to_dict(self) -> dict[str, Any]: system_prompt = self.system_prompt + effort: dict[str, Any] | Unset = UNSET + if not isinstance(self.effort, Unset): + effort = self.effort.to_dict() + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -142,11 +153,16 @@ def to_dict(self) -> dict[str, Any]: "system_prompt": system_prompt, } ) + if effort is not UNSET: + field_dict["effort"] = effort return field_dict @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.experiment_detail_response_effort import ( + ExperimentDetailResponseEffort, + ) from ..models.experiment_detail_response_result_data_type_0 import ( ExperimentDetailResponseResultDataType0, ) @@ -255,6 +271,13 @@ def _parse_started_at(data: object) -> None | str: system_prompt = d.pop("system_prompt") + _effort = d.pop("effort", UNSET) + effort: ExperimentDetailResponseEffort | Unset + if isinstance(_effort, Unset): + effort = UNSET + else: + effort = ExperimentDetailResponseEffort.from_dict(_effort) + experiment_detail_response = cls( completed_at=completed_at, created_at=created_at, @@ -275,6 +298,7 @@ def _parse_started_at(data: object) -> None | str: started_at=started_at, status=status, system_prompt=system_prompt, + effort=effort, ) experiment_detail_response.additional_properties = d diff --git a/seclai/_generated/models/experiment_detail_response_effort.py b/seclai/_generated/models/experiment_detail_response_effort.py new file mode 100644 index 0000000..a720193 --- /dev/null +++ b/seclai/_generated/models/experiment_detail_response_effort.py @@ -0,0 +1,46 @@ +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="ExperimentDetailResponseEffort") + + +@_attrs_define +class ExperimentDetailResponseEffort: + """The reasoning effort each model was run at, by model ID.""" + + additional_properties: dict[str, str] = _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) + experiment_detail_response_effort = cls() + + experiment_detail_response_effort.additional_properties = d + return experiment_detail_response_effort + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> str: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: str) -> 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/seclai/_generated/models/file_upload_response.py b/seclai/_generated/models/file_upload_response.py index 3d58165..8734a88 100644 --- a/seclai/_generated/models/file_upload_response.py +++ b/seclai/_generated/models/file_upload_response.py @@ -6,6 +6,8 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..types import UNSET, Unset + T = TypeVar("T", bound="FileUploadResponse") @@ -14,16 +16,22 @@ class FileUploadResponse: """Response model for content file replacement upload. Attributes: - content_version_id (None | str): ID of the content version being replaced + content_version_id (None | str): ID of the newly created content version. A replacement creates a new version + rather than overwriting the previous one. filename (str): Original filename - source_connection_content_version_id (None | str): ID of the source connection content version - status (str): Processing status + source_connection_content_version_id (None | str): ID of the source connection content version. Unchanged by a + replacement, so it stays a stable handle for the content. + status (str): Always `uploaded`. Unlike the create endpoints, a replacement is never rejected as a duplicate of + another item. + embedder_warning (None | str | Unset): Set when the file's type is not embedded directly on this source, so + indexing relies on extracted text. Content with none (e.g. a photograph) will be marked FAILED. """ content_version_id: None | str filename: str source_connection_content_version_id: None | str status: str + embedder_warning: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -37,6 +45,12 @@ def to_dict(self) -> dict[str, Any]: status = self.status + embedder_warning: None | str | Unset + if isinstance(self.embedder_warning, Unset): + embedder_warning = UNSET + else: + embedder_warning = self.embedder_warning + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -47,6 +61,8 @@ def to_dict(self) -> dict[str, Any]: "status": status, } ) + if embedder_warning is not UNSET: + field_dict["embedder_warning"] = embedder_warning return field_dict @@ -76,11 +92,21 @@ def _parse_source_connection_content_version_id(data: object) -> None | str: status = d.pop("status") + def _parse_embedder_warning(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + embedder_warning = _parse_embedder_warning(d.pop("embedder_warning", UNSET)) + file_upload_response = cls( content_version_id=content_version_id, filename=filename, source_connection_content_version_id=source_connection_content_version_id, status=status, + embedder_warning=embedder_warning, ) file_upload_response.additional_properties = d diff --git a/seclai/_generated/models/knowledge_base.py b/seclai/_generated/models/knowledge_base.py index a2dfc00..385544b 100644 --- a/seclai/_generated/models/knowledge_base.py +++ b/seclai/_generated/models/knowledge_base.py @@ -24,9 +24,9 @@ class KnowledgeBase: id (str): Unique knowledge base identifier. name (str): Human-readable name. updated_at (str): ISO-8601 last-update timestamp. - default_score_threshold (float | None | Unset): Default minimum rerank score. - default_top_k (int | None | Unset): Default results after reranking. - default_top_n (int | None | Unset): Default number of results to return. + default_score_threshold (float | None | Unset): Editor default for a new retrieval step's Minimum Rerank Score. + default_top_k (int | None | Unset): Editor default for a new retrieval step's Top K. + default_top_n (int | None | Unset): Editor default for a new retrieval step's Top N. description (None | str | Unset): Optional description. readonly (bool | Unset): Whether the knowledge base is read-only. Default: False. reranker_model (None | str | Unset): Reranker model in use. diff --git a/seclai/_generated/models/memory_bank.py b/seclai/_generated/models/memory_bank.py index e420e28..56b98f3 100644 --- a/seclai/_generated/models/memory_bank.py +++ b/seclai/_generated/models/memory_bank.py @@ -29,14 +29,21 @@ class MemoryBank: description (None | str | Unset): Optional description of the memory bank's purpose. dimensions (int | None | Unset): Vector embedding dimensions. embedding_model (None | str | Unset): Embedding model identifier. - max_age_days (int | None | Unset): Max entry age in days before compaction. Checked both inline after each write - and by the hourly background sweep. + max_age_days (int | None | Unset): DEPRECATED and no longer applied. Age now belongs solely to retention_days, + which deletes; compaction triggers on max_size_tokens and max_turns. Always null for clients sending Seclai- + Version 2026-08-03 or later; older clients keep reading whatever value was stored. max_size_tokens (int | None | Unset): Max total tokens (per partition) before compaction. Checked both inline after each write and by the hourly background sweep. max_turns (int | None | Unset): Max conversation turns (per partition) before compaction. Checked both inline after each write and by the hourly background sweep. retention_days (int | None | Unset): Content retention period in days (null = indefinite). source_connection_id (None | str | Unset): Linked content source ID (null if not yet provisioned). + strip_quoted_reply_chains (bool | Unset): Conversation banks only. When true, a conversation turn written to + this bank has the quoted reply chain an email client prepends to a reply dropped from it. Only inbound (user) + turns are affected, and only words in a run of at least ~40 matching a recent turn word for word are dropped + (line wrapping and punctuation at a word's edge are ignored). A word the sender changed is kept, including a + one-character change inside a link, address or amount, unless the change is only to that edge punctuation. + Default: False. """ created_at: str @@ -56,6 +63,7 @@ class MemoryBank: max_turns: int | None | Unset = UNSET retention_days: int | None | Unset = UNSET source_connection_id: None | str | Unset = UNSET + strip_quoted_reply_chains: bool | Unset = False additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -137,6 +145,8 @@ def to_dict(self) -> dict[str, Any]: else: source_connection_id = self.source_connection_id + strip_quoted_reply_chains = self.strip_quoted_reply_chains + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -171,6 +181,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["retention_days"] = retention_days if source_connection_id is not UNSET: field_dict["source_connection_id"] = source_connection_id + if strip_quoted_reply_chains is not UNSET: + field_dict["strip_quoted_reply_chains"] = strip_quoted_reply_chains return field_dict @@ -290,6 +302,8 @@ def _parse_source_connection_id(data: object) -> None | str | Unset: d.pop("source_connection_id", UNSET) ) + strip_quoted_reply_chains = d.pop("strip_quoted_reply_chains", UNSET) + memory_bank = cls( created_at=created_at, id=id, @@ -308,6 +322,7 @@ def _parse_source_connection_id(data: object) -> None | str | Unset: max_turns=max_turns, retention_days=retention_days, source_connection_id=source_connection_id, + strip_quoted_reply_chains=strip_quoted_reply_chains, ) memory_bank.additional_properties = d diff --git a/seclai/_generated/models/memory_bank_config_response.py b/seclai/_generated/models/memory_bank_config_response.py index 246cdfa..c52b8a3 100644 --- a/seclai/_generated/models/memory_bank_config_response.py +++ b/seclai/_generated/models/memory_bank_config_response.py @@ -21,7 +21,8 @@ class MemoryBankConfigResponse: type_ (str): Memory bank type: conversation or general. compaction_prompt (None | str | Unset): Suggested compaction prompt. description (None | str | Unset): Suggested description. - max_age_days (int | None | Unset): Max age in days. + max_age_days (int | None | Unset): Always null. Age-based compaction is retired — the assistant never suggests + it. Kept so an SDK generated before the change still validates this response. max_size_tokens (int | None | Unset): Max size in tokens. max_turns (int | None | Unset): Max conversation turns. retention_days (int | None | Unset): Retention in days. diff --git a/seclai/_generated/models/model_recommendation_response.py b/seclai/_generated/models/model_recommendation_response.py index 0334ec7..dae2825 100644 --- a/seclai/_generated/models/model_recommendation_response.py +++ b/seclai/_generated/models/model_recommendation_response.py @@ -1,13 +1,17 @@ from __future__ import annotations from collections.abc import Mapping -from typing import Any, TypeVar, cast +from typing import TYPE_CHECKING, Any, TypeVar, cast from attrs import define as _attrs_define from attrs import field as _attrs_field from ..types import UNSET, Unset +if TYPE_CHECKING: + from ..models.effort_options_response import EffortOptionsResponse + + T = TypeVar("T", bound="ModelRecommendationResponse") @@ -30,6 +34,7 @@ class ModelRecommendationResponse: supports_thinking (bool): supports_tool_use (bool): deprecated_at (None | str | Unset): + effort_options (EffortOptionsResponse | None | Unset): family (None | str | Unset): family_generation (float | None | Unset): released_at (None | str | Unset): @@ -51,6 +56,7 @@ class ModelRecommendationResponse: supports_thinking: bool supports_tool_use: bool deprecated_at: None | str | Unset = UNSET + effort_options: EffortOptionsResponse | None | Unset = UNSET family: None | str | Unset = UNSET family_generation: float | None | Unset = UNSET released_at: None | str | Unset = UNSET @@ -58,6 +64,8 @@ class ModelRecommendationResponse: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: + from ..models.effort_options_response import EffortOptionsResponse + description = self.description id = self.id @@ -92,6 +100,14 @@ def to_dict(self) -> dict[str, Any]: else: deprecated_at = self.deprecated_at + effort_options: dict[str, Any] | None | Unset + if isinstance(self.effort_options, Unset): + effort_options = UNSET + elif isinstance(self.effort_options, EffortOptionsResponse): + effort_options = self.effort_options.to_dict() + else: + effort_options = self.effort_options + family: None | str | Unset if isinstance(self.family, Unset): family = UNSET @@ -138,6 +154,8 @@ def to_dict(self) -> dict[str, Any]: ) if deprecated_at is not UNSET: field_dict["deprecated_at"] = deprecated_at + if effort_options is not UNSET: + field_dict["effort_options"] = effort_options if family is not UNSET: field_dict["family"] = family if family_generation is not UNSET: @@ -151,6 +169,8 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.effort_options_response import EffortOptionsResponse + d = dict(src_dict) description = d.pop("description") @@ -189,6 +209,23 @@ def _parse_deprecated_at(data: object) -> None | str | Unset: deprecated_at = _parse_deprecated_at(d.pop("deprecated_at", UNSET)) + def _parse_effort_options(data: object) -> EffortOptionsResponse | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + effort_options_type_0 = EffortOptionsResponse.from_dict(data) + + return effort_options_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(EffortOptionsResponse | None | Unset, data) + + effort_options = _parse_effort_options(d.pop("effort_options", UNSET)) + def _parse_family(data: object) -> None | str | Unset: if data is None: return data @@ -241,6 +278,7 @@ def _parse_sunset_at(data: object) -> None | str | Unset: supports_thinking=supports_thinking, supports_tool_use=supports_tool_use, deprecated_at=deprecated_at, + effort_options=effort_options, family=family, family_generation=family_generation, released_at=released_at, diff --git a/seclai/_generated/models/playground_create_request.py b/seclai/_generated/models/playground_create_request.py index f94c14e..e3c7437 100644 --- a/seclai/_generated/models/playground_create_request.py +++ b/seclai/_generated/models/playground_create_request.py @@ -1,7 +1,7 @@ from __future__ import annotations from collections.abc import Mapping -from typing import Any, TypeVar, cast +from typing import TYPE_CHECKING, Any, TypeVar, cast from attrs import define as _attrs_define from attrs import field as _attrs_field @@ -14,6 +14,12 @@ ) from ..types import UNSET, Unset +if TYPE_CHECKING: + from ..models.playground_create_request_effort_type_0 import ( + PlaygroundCreateRequestEffortType0, + ) + + T = TypeVar("T", bound="PlaygroundCreateRequest") @@ -24,6 +30,8 @@ class PlaygroundCreateRequest: Attributes: model_ids (list[str]): Selected model IDs (1-10). prompt (str): Prompt text for the experiment. + effort (None | PlaygroundCreateRequestEffortType0 | Unset): Reasoning effort per model id, each one of that + model's `effort_options` values. Not combinable with `json_template`. evaluation_complexity (PlaygroundCreateRequestEvaluationComplexity | Unset): simple, medium, or complex Default: PlaygroundCreateRequestEvaluationComplexity.MEDIUM. evaluation_mode (PlaygroundCreateRequestEvaluationMode | Unset): manual or prompt Default: @@ -38,6 +46,7 @@ class PlaygroundCreateRequest: model_ids: list[str] prompt: str + effort: None | PlaygroundCreateRequestEffortType0 | Unset = UNSET evaluation_complexity: PlaygroundCreateRequestEvaluationComplexity | Unset = ( PlaygroundCreateRequestEvaluationComplexity.MEDIUM ) @@ -52,10 +61,22 @@ class PlaygroundCreateRequest: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: + from ..models.playground_create_request_effort_type_0 import ( + PlaygroundCreateRequestEffortType0, + ) + model_ids = self.model_ids prompt = self.prompt + effort: dict[str, Any] | None | Unset + if isinstance(self.effort, Unset): + effort = UNSET + elif isinstance(self.effort, PlaygroundCreateRequestEffortType0): + effort = self.effort.to_dict() + else: + effort = self.effort + evaluation_complexity: str | Unset = UNSET if not isinstance(self.evaluation_complexity, Unset): evaluation_complexity = self.evaluation_complexity.value @@ -94,6 +115,8 @@ def to_dict(self) -> dict[str, Any]: "prompt": prompt, } ) + if effort is not UNSET: + field_dict["effort"] = effort if evaluation_complexity is not UNSET: field_dict["evaluation_complexity"] = evaluation_complexity if evaluation_mode is not UNSET: @@ -115,11 +138,34 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.playground_create_request_effort_type_0 import ( + PlaygroundCreateRequestEffortType0, + ) + d = dict(src_dict) model_ids = cast(list[str], d.pop("model_ids")) prompt = d.pop("prompt") + def _parse_effort( + data: object, + ) -> None | PlaygroundCreateRequestEffortType0 | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + effort_type_0 = PlaygroundCreateRequestEffortType0.from_dict(data) + + return effort_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | PlaygroundCreateRequestEffortType0 | Unset, data) + + effort = _parse_effort(d.pop("effort", UNSET)) + _evaluation_complexity = d.pop("evaluation_complexity", UNSET) evaluation_complexity: PlaygroundCreateRequestEvaluationComplexity | Unset if isinstance(_evaluation_complexity, Unset): @@ -176,6 +222,7 @@ def _parse_selected_step_output(data: object) -> None | str | Unset: playground_create_request = cls( model_ids=model_ids, prompt=prompt, + effort=effort, evaluation_complexity=evaluation_complexity, evaluation_mode=evaluation_mode, evaluator_model_id=evaluator_model_id, diff --git a/seclai/_generated/models/playground_create_request_effort_type_0.py b/seclai/_generated/models/playground_create_request_effort_type_0.py new file mode 100644 index 0000000..a070572 --- /dev/null +++ b/seclai/_generated/models/playground_create_request_effort_type_0.py @@ -0,0 +1,46 @@ +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="PlaygroundCreateRequestEffortType0") + + +@_attrs_define +class PlaygroundCreateRequestEffortType0: + """ """ + + additional_properties: dict[str, str] = _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) + playground_create_request_effort_type_0 = cls() + + playground_create_request_effort_type_0.additional_properties = d + return playground_create_request_effort_type_0 + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> str: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: str) -> 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/seclai/_generated/models/prompt_model_response.py b/seclai/_generated/models/prompt_model_response.py index 62954d0..5ae8d7b 100644 --- a/seclai/_generated/models/prompt_model_response.py +++ b/seclai/_generated/models/prompt_model_response.py @@ -11,7 +11,11 @@ from ..types import UNSET, Unset if TYPE_CHECKING: + from ..models.effort_options_response import EffortOptionsResponse from ..models.modality_rate_response import ModalityRateResponse + from ..models.prompt_model_response_generation_credits_per_variant_type_0 import ( + PromptModelResponseGenerationCreditsPerVariantType0, + ) from ..models.prompt_model_response_generation_params_type_0 import ( PromptModelResponseGenerationParamsType0, ) @@ -40,16 +44,35 @@ class PromptModelResponse: model_id (str): name (str): provider (str): + chat_capable (bool | Unset): Whether this model can serve a chat request (`prompt_call`, `extract_data`). True + for every plain text LLM, and for a dual-capability model that generates media AND holds a conversation; false + for a dedicated generator (Imagen, Veo, a TTS voice), which bills per produced unit and has no chat interface. + Authoritative: consumers must read this rather than inferring it from `generation_params` or + `supported_output_media`, because the answer also depends on which inference interface serves the model — + something no response field exposes. Default: True. deprecated_at (datetime.datetime | None | Unset): + effort_options (EffortOptionsResponse | None | Unset): The reasoning-effort values a prompt_call or extract_data + step may set as `effort` with this model. Null when the model takes none. family (None | str | Unset): family_generation (float | None | Unset): generation_credits_per_unit (float | None | Unset): Per-unit credit cost for a dedicated media-generation model, in the unit named by ``generation_params.pricing_unit`` (per image / per second / per character / per output - token). Multiply by the produced unit count (images, seconds, characters) for the run cost. None for token- - billed (non-generation) models. + token). Multiply by the produced unit count (images, seconds, characters) for the run cost. None for models with + no generation descriptor. This rate applies when the model is used in a generate_image/audio/video step; a model + that also serves the chat path is billed per token there instead, using the input/output token rates on this + same record. When `generation_params.price_varies_by` is set the model has one rate per value of that option and + this is the **highest** of them — read `generation_credits_per_variant` for the real spread rather than + presenting this as the price. + generation_credits_per_variant (None | PromptModelResponseGenerationCreditsPerVariantType0 | Unset): Per-unit + credit cost keyed by the value of the option named in `generation_params.price_varies_by` (e.g. `{'720p': 1330, + '1080p': 1995}`). None for a model with a single rate, where `generation_credits_per_unit` already describes it + exactly. generation_params (None | PromptModelResponseGenerationParamsType0 | Unset): Media-generation descriptor (modality, pricing_unit, and modality-specific constraints). NULL for text LLMs; present for image/audio/video - generation models. See schemas.generation_params. + generation models. See schemas.generation_params. A present descriptor does NOT imply the model is generation- + only: some models serve both paths (they generate media AND hold a chat conversation). Read `chat_capable` to + tell whether a model with a descriptor can also be used as a chat model — do not branch on this field being non- + null alone, and do not re-derive the answer from `supported_output_media`. generation_unit_label (None | str | Unset): Human suffix for the per-unit generation rate (e.g. ``/image``, ``/second``, ``/1k chars``, ``/1k tokens``) — single-sourced from the pricing unit so clients render cost without re-deriving the mapping. None for non-generation models. Char/token rates are shown per 1,000 (the ``/1k @@ -57,9 +80,14 @@ class PromptModelResponse: image_generation_tool_credits_per_image (float | None | Unset): Per-image credit cost of using the built-in image_generation tool (it runs gpt-image-1). Set only for models that actually support the tool (tool-use capable); None otherwise. - input_1h_cache_write_credits_per_1000_tokens (float | None | Unset): - input_5m_cache_write_credits_per_1000_tokens (float | None | Unset): - input_cache_hit_credits_per_1000_tokens (float | None | Unset): + input_1h_cache_write_credits_per_1000_tokens (float | None | Unset): Credits per 1,000 input tokens written to a + 1-hour prompt cache. + input_30m_cache_write_credits_per_1000_tokens (float | None | Unset): Credits per 1,000 input tokens written to + a 30-minute prompt cache. + input_5m_cache_write_credits_per_1000_tokens (float | None | Unset): Credits per 1,000 input tokens written to a + 5-minute prompt cache. + input_cache_hit_credits_per_1000_tokens (float | None | Unset): Credits per 1,000 input tokens read from a + prompt cache. input_credits_per_1000_tokens (float | None | Unset): is_new (bool | Unset): Default: False. last_used (bool | Unset): Default: False. @@ -99,14 +127,20 @@ class PromptModelResponse: model_id: str name: str provider: str + chat_capable: bool | Unset = True deprecated_at: datetime.datetime | None | Unset = UNSET + effort_options: EffortOptionsResponse | None | Unset = UNSET family: None | str | Unset = UNSET family_generation: float | None | Unset = UNSET generation_credits_per_unit: float | None | Unset = UNSET + generation_credits_per_variant: ( + None | PromptModelResponseGenerationCreditsPerVariantType0 | Unset + ) = UNSET generation_params: None | PromptModelResponseGenerationParamsType0 | Unset = UNSET generation_unit_label: None | str | Unset = UNSET image_generation_tool_credits_per_image: float | None | Unset = UNSET input_1h_cache_write_credits_per_1000_tokens: float | None | Unset = UNSET + input_30m_cache_write_credits_per_1000_tokens: float | None | Unset = UNSET input_5m_cache_write_credits_per_1000_tokens: float | None | Unset = UNSET input_cache_hit_credits_per_1000_tokens: float | None | Unset = UNSET input_credits_per_1000_tokens: float | None | Unset = UNSET @@ -137,6 +171,10 @@ class PromptModelResponse: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: + from ..models.effort_options_response import EffortOptionsResponse + from ..models.prompt_model_response_generation_credits_per_variant_type_0 import ( + PromptModelResponseGenerationCreditsPerVariantType0, + ) from ..models.prompt_model_response_generation_params_type_0 import ( PromptModelResponseGenerationParamsType0, ) @@ -164,6 +202,8 @@ def to_dict(self) -> dict[str, Any]: provider = self.provider + chat_capable = self.chat_capable + deprecated_at: None | str | Unset if isinstance(self.deprecated_at, Unset): deprecated_at = UNSET @@ -172,6 +212,14 @@ def to_dict(self) -> dict[str, Any]: else: deprecated_at = self.deprecated_at + effort_options: dict[str, Any] | None | Unset + if isinstance(self.effort_options, Unset): + effort_options = UNSET + elif isinstance(self.effort_options, EffortOptionsResponse): + effort_options = self.effort_options.to_dict() + else: + effort_options = self.effort_options + family: None | str | Unset if isinstance(self.family, Unset): family = UNSET @@ -190,6 +238,19 @@ def to_dict(self) -> dict[str, Any]: else: generation_credits_per_unit = self.generation_credits_per_unit + generation_credits_per_variant: dict[str, Any] | None | Unset + if isinstance(self.generation_credits_per_variant, Unset): + generation_credits_per_variant = UNSET + elif isinstance( + self.generation_credits_per_variant, + PromptModelResponseGenerationCreditsPerVariantType0, + ): + generation_credits_per_variant = ( + self.generation_credits_per_variant.to_dict() + ) + else: + generation_credits_per_variant = self.generation_credits_per_variant + generation_params: dict[str, Any] | None | Unset if isinstance(self.generation_params, Unset): generation_params = UNSET @@ -222,6 +283,14 @@ def to_dict(self) -> dict[str, Any]: self.input_1h_cache_write_credits_per_1000_tokens ) + input_30m_cache_write_credits_per_1000_tokens: float | None | Unset + if isinstance(self.input_30m_cache_write_credits_per_1000_tokens, Unset): + input_30m_cache_write_credits_per_1000_tokens = UNSET + else: + input_30m_cache_write_credits_per_1000_tokens = ( + self.input_30m_cache_write_credits_per_1000_tokens + ) + input_5m_cache_write_credits_per_1000_tokens: float | None | Unset if isinstance(self.input_5m_cache_write_credits_per_1000_tokens, Unset): input_5m_cache_write_credits_per_1000_tokens = UNSET @@ -402,14 +471,22 @@ def to_dict(self) -> dict[str, Any]: "provider": provider, } ) + if chat_capable is not UNSET: + field_dict["chat_capable"] = chat_capable if deprecated_at is not UNSET: field_dict["deprecated_at"] = deprecated_at + if effort_options is not UNSET: + field_dict["effort_options"] = effort_options if family is not UNSET: field_dict["family"] = family if family_generation is not UNSET: field_dict["family_generation"] = family_generation if generation_credits_per_unit is not UNSET: field_dict["generation_credits_per_unit"] = generation_credits_per_unit + if generation_credits_per_variant is not UNSET: + field_dict["generation_credits_per_variant"] = ( + generation_credits_per_variant + ) if generation_params is not UNSET: field_dict["generation_params"] = generation_params if generation_unit_label is not UNSET: @@ -422,6 +499,10 @@ def to_dict(self) -> dict[str, Any]: field_dict["input_1h_cache_write_credits_per_1000_tokens"] = ( input_1h_cache_write_credits_per_1000_tokens ) + if input_30m_cache_write_credits_per_1000_tokens is not UNSET: + field_dict["input_30m_cache_write_credits_per_1000_tokens"] = ( + input_30m_cache_write_credits_per_1000_tokens + ) if input_5m_cache_write_credits_per_1000_tokens is not UNSET: field_dict["input_5m_cache_write_credits_per_1000_tokens"] = ( input_5m_cache_write_credits_per_1000_tokens @@ -487,7 +568,11 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.effort_options_response import EffortOptionsResponse from ..models.modality_rate_response import ModalityRateResponse + from ..models.prompt_model_response_generation_credits_per_variant_type_0 import ( + PromptModelResponseGenerationCreditsPerVariantType0, + ) from ..models.prompt_model_response_generation_params_type_0 import ( PromptModelResponseGenerationParamsType0, ) @@ -518,6 +603,8 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: provider = d.pop("provider") + chat_capable = d.pop("chat_capable", UNSET) + def _parse_deprecated_at(data: object) -> datetime.datetime | None | Unset: if data is None: return data @@ -535,6 +622,23 @@ def _parse_deprecated_at(data: object) -> datetime.datetime | None | Unset: deprecated_at = _parse_deprecated_at(d.pop("deprecated_at", UNSET)) + def _parse_effort_options(data: object) -> EffortOptionsResponse | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + effort_options_type_0 = EffortOptionsResponse.from_dict(data) + + return effort_options_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(EffortOptionsResponse | None | Unset, data) + + effort_options = _parse_effort_options(d.pop("effort_options", UNSET)) + def _parse_family(data: object) -> None | str | Unset: if data is None: return data @@ -564,6 +668,31 @@ def _parse_generation_credits_per_unit(data: object) -> float | None | Unset: d.pop("generation_credits_per_unit", UNSET) ) + def _parse_generation_credits_per_variant( + data: object, + ) -> None | PromptModelResponseGenerationCreditsPerVariantType0 | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + generation_credits_per_variant_type_0 = ( + PromptModelResponseGenerationCreditsPerVariantType0.from_dict(data) + ) + + return generation_credits_per_variant_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast( + None | PromptModelResponseGenerationCreditsPerVariantType0 | Unset, data + ) + + generation_credits_per_variant = _parse_generation_credits_per_variant( + d.pop("generation_credits_per_variant", UNSET) + ) + def _parse_generation_params( data: object, ) -> None | PromptModelResponseGenerationParamsType0 | Unset: @@ -626,6 +755,21 @@ def _parse_input_1h_cache_write_credits_per_1000_tokens( ) ) + def _parse_input_30m_cache_write_credits_per_1000_tokens( + data: object, + ) -> float | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(float | None | Unset, data) + + input_30m_cache_write_credits_per_1000_tokens = ( + _parse_input_30m_cache_write_credits_per_1000_tokens( + d.pop("input_30m_cache_write_credits_per_1000_tokens", UNSET) + ) + ) + def _parse_input_5m_cache_write_credits_per_1000_tokens( data: object, ) -> float | None | Unset: @@ -944,14 +1088,18 @@ def _parse_variants( model_id=model_id, name=name, provider=provider, + chat_capable=chat_capable, deprecated_at=deprecated_at, + effort_options=effort_options, family=family, family_generation=family_generation, generation_credits_per_unit=generation_credits_per_unit, + generation_credits_per_variant=generation_credits_per_variant, generation_params=generation_params, generation_unit_label=generation_unit_label, image_generation_tool_credits_per_image=image_generation_tool_credits_per_image, input_1h_cache_write_credits_per_1000_tokens=input_1h_cache_write_credits_per_1000_tokens, + input_30m_cache_write_credits_per_1000_tokens=input_30m_cache_write_credits_per_1000_tokens, input_5m_cache_write_credits_per_1000_tokens=input_5m_cache_write_credits_per_1000_tokens, input_cache_hit_credits_per_1000_tokens=input_cache_hit_credits_per_1000_tokens, input_credits_per_1000_tokens=input_credits_per_1000_tokens, diff --git a/seclai/_generated/models/prompt_model_response_generation_credits_per_variant_type_0.py b/seclai/_generated/models/prompt_model_response_generation_credits_per_variant_type_0.py new file mode 100644 index 0000000..407af96 --- /dev/null +++ b/seclai/_generated/models/prompt_model_response_generation_credits_per_variant_type_0.py @@ -0,0 +1,48 @@ +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="PromptModelResponseGenerationCreditsPerVariantType0") + + +@_attrs_define +class PromptModelResponseGenerationCreditsPerVariantType0: + """ """ + + additional_properties: dict[str, float] = _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) + prompt_model_response_generation_credits_per_variant_type_0 = cls() + + prompt_model_response_generation_credits_per_variant_type_0.additional_properties = ( + d + ) + return prompt_model_response_generation_credits_per_variant_type_0 + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> float: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: float) -> 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/seclai/_generated/models/reranker_model_list_response.py b/seclai/_generated/models/reranker_model_list_response.py new file mode 100644 index 0000000..bc0e960 --- /dev/null +++ b/seclai/_generated/models/reranker_model_list_response.py @@ -0,0 +1,92 @@ +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 + +if TYPE_CHECKING: + from ..models.reranker_model_response import RerankerModelResponse + + +T = TypeVar("T", bound="RerankerModelListResponse") + + +@_attrs_define +class RerankerModelListResponse: + """Legacy (header-less) response shape for the reranker catalog. + + Attributes: + default_model_type (str): Reranker used when a knowledge base does not choose one + models (list[RerankerModelResponse]): Available reranker models + search_processing_credits (float): Credits charged for processing a search request + """ + + default_model_type: str + models: list[RerankerModelResponse] + search_processing_credits: float + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + default_model_type = self.default_model_type + + models = [] + for models_item_data in self.models: + models_item = models_item_data.to_dict() + models.append(models_item) + + search_processing_credits = self.search_processing_credits + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "default_model_type": default_model_type, + "models": models, + "search_processing_credits": search_processing_credits, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.reranker_model_response import RerankerModelResponse + + d = dict(src_dict) + default_model_type = d.pop("default_model_type") + + models = [] + _models = d.pop("models") + for models_item_data in _models: + models_item = RerankerModelResponse.from_dict(models_item_data) + + models.append(models_item) + + search_processing_credits = d.pop("search_processing_credits") + + reranker_model_list_response = cls( + default_model_type=default_model_type, + models=models, + search_processing_credits=search_processing_credits, + ) + + reranker_model_list_response.additional_properties = d + return reranker_model_list_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/seclai/_generated/models/reranker_model_response.py b/seclai/_generated/models/reranker_model_response.py new file mode 100644 index 0000000..b5a0a87 --- /dev/null +++ b/seclai/_generated/models/reranker_model_response.py @@ -0,0 +1,211 @@ +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 + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="RerankerModelResponse") + + +@_attrs_define +class RerankerModelResponse: + """Information about a reranker model. + + Attributes: + credits_per_action (float): Credits charged per rerank action + is_default (bool): Whether this is the platform default reranker + model_type (str): Full model type identifier. This is the value to send as reranker_model on a knowledge base; + send "none" or an empty string to disable reranking. + name (str): Human-readable model name + description (None | str | Unset): Model description + is_new (bool | Unset): Whether the model is newly released Default: False. + max_input_tokens (int | None | Unset): Max input tokens per request + provider (None | str | Unset): Model provider identifier + supported_languages (list[str] | None | Unset): Supported languages + url (None | str | Unset): Model documentation URL + """ + + credits_per_action: float + is_default: bool + model_type: str + name: str + description: None | str | Unset = UNSET + is_new: bool | Unset = False + max_input_tokens: int | None | Unset = UNSET + provider: None | str | Unset = UNSET + supported_languages: list[str] | None | Unset = UNSET + url: None | str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + credits_per_action = self.credits_per_action + + is_default = self.is_default + + model_type = self.model_type + + name = self.name + + description: None | str | Unset + if isinstance(self.description, Unset): + description = UNSET + else: + description = self.description + + is_new = self.is_new + + max_input_tokens: int | None | Unset + if isinstance(self.max_input_tokens, Unset): + max_input_tokens = UNSET + else: + max_input_tokens = self.max_input_tokens + + provider: None | str | Unset + if isinstance(self.provider, Unset): + provider = UNSET + else: + provider = self.provider + + supported_languages: list[str] | None | Unset + if isinstance(self.supported_languages, Unset): + supported_languages = UNSET + elif isinstance(self.supported_languages, list): + supported_languages = self.supported_languages + + else: + supported_languages = self.supported_languages + + url: None | str | Unset + if isinstance(self.url, Unset): + url = UNSET + else: + url = self.url + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "credits_per_action": credits_per_action, + "is_default": is_default, + "model_type": model_type, + "name": name, + } + ) + if description is not UNSET: + field_dict["description"] = description + if is_new is not UNSET: + field_dict["is_new"] = is_new + if max_input_tokens is not UNSET: + field_dict["max_input_tokens"] = max_input_tokens + if provider is not UNSET: + field_dict["provider"] = provider + if supported_languages is not UNSET: + field_dict["supported_languages"] = supported_languages + if url is not UNSET: + field_dict["url"] = url + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + credits_per_action = d.pop("credits_per_action") + + is_default = d.pop("is_default") + + model_type = d.pop("model_type") + + name = d.pop("name") + + def _parse_description(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + description = _parse_description(d.pop("description", UNSET)) + + is_new = d.pop("is_new", UNSET) + + def _parse_max_input_tokens(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + max_input_tokens = _parse_max_input_tokens(d.pop("max_input_tokens", UNSET)) + + def _parse_provider(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + provider = _parse_provider(d.pop("provider", UNSET)) + + def _parse_supported_languages(data: object) -> list[str] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + supported_languages_type_0 = cast(list[str], data) + + return supported_languages_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + supported_languages = _parse_supported_languages( + d.pop("supported_languages", UNSET) + ) + + def _parse_url(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + url = _parse_url(d.pop("url", UNSET)) + + reranker_model_response = cls( + credits_per_action=credits_per_action, + is_default=is_default, + model_type=model_type, + name=name, + description=description, + is_new=is_new, + max_input_tokens=max_input_tokens, + provider=provider, + supported_languages=supported_languages, + url=url, + ) + + reranker_model_response.additional_properties = d + return reranker_model_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/seclai/_generated/models/service_unavailable_error.py b/seclai/_generated/models/service_unavailable_error.py new file mode 100644 index 0000000..f8f5909 --- /dev/null +++ b/seclai/_generated/models/service_unavailable_error.py @@ -0,0 +1,69 @@ +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 + +if TYPE_CHECKING: + from ..models.service_unavailable_error_error import ServiceUnavailableErrorError + + +T = TypeVar("T", bound="ServiceUnavailableError") + + +@_attrs_define +class ServiceUnavailableError: + """ + Attributes: + error (ServiceUnavailableErrorError): + """ + + error: ServiceUnavailableErrorError + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + error = self.error.to_dict() + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "error": error, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.service_unavailable_error_error import ( + ServiceUnavailableErrorError, + ) + + d = dict(src_dict) + error = ServiceUnavailableErrorError.from_dict(d.pop("error")) + + service_unavailable_error = cls( + error=error, + ) + + service_unavailable_error.additional_properties = d + return service_unavailable_error + + @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/seclai/_generated/models/service_unavailable_error_error.py b/seclai/_generated/models/service_unavailable_error_error.py new file mode 100644 index 0000000..c968e2f --- /dev/null +++ b/seclai/_generated/models/service_unavailable_error_error.py @@ -0,0 +1,73 @@ +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 + +from ..models.service_unavailable_error_error_code import ( + ServiceUnavailableErrorErrorCode, +) + +T = TypeVar("T", bound="ServiceUnavailableErrorError") + + +@_attrs_define +class ServiceUnavailableErrorError: + """ + Attributes: + code (ServiceUnavailableErrorErrorCode): + message (str): + """ + + code: ServiceUnavailableErrorErrorCode + message: str + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + code = self.code.value + + message = self.message + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "code": code, + "message": message, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + code = ServiceUnavailableErrorErrorCode(d.pop("code")) + + message = d.pop("message") + + service_unavailable_error_error = cls( + code=code, + message=message, + ) + + service_unavailable_error_error.additional_properties = d + return service_unavailable_error_error + + @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/seclai/_generated/models/service_unavailable_error_error_code.py b/seclai/_generated/models/service_unavailable_error_error_code.py new file mode 100644 index 0000000..1759fa0 --- /dev/null +++ b/seclai/_generated/models/service_unavailable_error_error_code.py @@ -0,0 +1,9 @@ +from enum import Enum + + +class ServiceUnavailableErrorErrorCode(str, Enum): + DATABASE_UNAVAILABLE = "database_unavailable" + VECTOR_STORE_UNAVAILABLE = "vector_store_unavailable" + + def __str__(self) -> str: + return str(self.value) diff --git a/seclai/_generated/models/set_email_trigger_config_request.py b/seclai/_generated/models/set_email_trigger_config_request.py index ec192a6..056b04c 100644 --- a/seclai/_generated/models/set_email_trigger_config_request.py +++ b/seclai/_generated/models/set_email_trigger_config_request.py @@ -19,9 +19,10 @@ class SetEmailTriggerConfigRequest: ``alias``) clears it. Attributes: - alias (None | str | Unset): Custom alias for the address `.@agent.seclai.com` (alphanumeric - plus '+', '.', '-'; 1–32 chars; not starting/ending with '+', '.', '-'; not UUID-shaped). Pass null/empty to - clear. + alias (None | str | Unset): Custom alias, unique per account, answering as + `.@agent.seclai.com` and as `@` on each verified account email domain + (alphanumeric plus '+', '.', '-'; 1–32 chars; not starting/ending with '+', '.', '-'; not UUID-shaped). Pass + null/empty to clear. allowed_senders (list[str] | None | Unset): Allowlist of full sender addresses and/or bare domains (a bare domain also matches sub-domains). Empty/null accepts any sender. ignore_auto_generated (bool | None | Unset): When true (default for new triggers), machine-generated inbound diff --git a/seclai/_generated/models/source_content_status_list_response.py b/seclai/_generated/models/source_content_status_list_response.py new file mode 100644 index 0000000..a2bc03f --- /dev/null +++ b/seclai/_generated/models/source_content_status_list_response.py @@ -0,0 +1,86 @@ +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 + +if TYPE_CHECKING: + from ..models.pagination_response import PaginationResponse + from ..models.source_content_status_response import SourceContentStatusResponse + + +T = TypeVar("T", bound="SourceContentStatusListResponse") + + +@_attrs_define +class SourceContentStatusListResponse: + """Response model for a paginated per-item indexing status list. + + Attributes: + data (list[SourceContentStatusResponse]): + pagination (PaginationResponse): Pagination information. + """ + + data: list[SourceContentStatusResponse] + pagination: PaginationResponse + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data = [] + for data_item_data in self.data: + data_item = data_item_data.to_dict() + data.append(data_item) + + pagination = self.pagination.to_dict() + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "data": data, + "pagination": pagination, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.pagination_response import PaginationResponse + from ..models.source_content_status_response import SourceContentStatusResponse + + d = dict(src_dict) + data = [] + _data = d.pop("data") + for data_item_data in _data: + data_item = SourceContentStatusResponse.from_dict(data_item_data) + + data.append(data_item) + + pagination = PaginationResponse.from_dict(d.pop("pagination")) + + source_content_status_list_response = cls( + data=data, + pagination=pagination, + ) + + source_content_status_list_response.additional_properties = d + return source_content_status_list_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/seclai/_generated/models/source_content_status_response.py b/seclai/_generated/models/source_content_status_response.py new file mode 100644 index 0000000..3e8033d --- /dev/null +++ b/seclai/_generated/models/source_content_status_response.py @@ -0,0 +1,301 @@ +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 + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="SourceContentStatusResponse") + + +@_attrs_define +class SourceContentStatusResponse: + """Response model for one content item's indexing status. + + Attributes: + content_status (str): Indexing status: pending, fetching, transcribing, scanning, indexing, completed, or + failed. + content_token_count (int | None): Extracted token count. + content_type (str): Content type group: text, audio, video, image, or document. + content_url (None | str): Internal URL identifying the item. Uploaded files use a `file-upload://` URL. + content_version_id (str): ID of the content version. This is the `content_version_id` returned by the upload + endpoints, so it is what you match an upload against. + content_word_count (int | None): Extracted word count. + error (None | str): Why the item failed, when `content_status` is `failed`. + indexed_at (None | str): Timestamp when the item finished indexing and became retrievable. `null` until then. + mime_type (None | str): MIME type the item was ingested as, when known. + published_at (None | str): Publication timestamp of the item, when known. + pulled_at (str): Timestamp when the item was uploaded or pulled. + source_connection_content_version_id (None | str): ID to pass to `GET /contents/{id}`. `null` until the item has + finished indexing — an item that is still processing, or that failed, has no retrievable content and keeps this + `null`. + title (None | str): Title of the content item. + awaiting_reindex (bool | Unset): True when the item is linked and reports completed but its content is not yet + embedded under the index the source connection currently uses, because it still sits under the index that + connection used before an embedding migration switched it. Anything ingested while a migration ran can land in + this state. Semantic and content search will not match it until it is re-embedded; a title keyword match can + still return it, so the item may appear in results while its body is unsearchable. It clears on its own — a + reconciliation pass re-embeds the item under the current index, typically within minutes of the migration + finishing, and a daily sweep retries whatever is still outstanding, so a large backlog can take more than one + sweep to drain. The re-embedding is not charged to your account: nothing you did caused it, so Seclai absorbs + the cost. Never true for an item that is simply still indexing; content_status covers that. Default: False. + extracted_media_capped (bool | Unset): True when extraction stopped with media still unread, so the item + references more media than was indexed and media search will not match anything past the cut. Two causes: a web + page that ran out of the budget for fetching remote assets, or a container that could not be read to the end (a + truncated or hostile archive). An uploaded document that reads cleanly is never capped, however much media it + holds — there is no limit on that. Default: False. + extracted_media_count (int | None | Unset): Number of embedded images / videos extracted from inside this item + and indexed as their own chunks. There is no limit on this — a document contributes as many as it holds. Null + when there is no media record for the item: the extraction pass has not run, does not apply to this container, + or found nothing. Treat null as 'unknown', never as zero. + extracted_media_limit (int | None | Unset): The bound that was reached, when extracted_media_capped is true and + the stop was a bound — a number of fetch attempts, or a number of seconds. Null when extraction was not capped, + or when it stopped because the container could not be read rather than because a bound fired. + """ + + content_status: str + content_token_count: int | None + content_type: str + content_url: None | str + content_version_id: str + content_word_count: int | None + error: None | str + indexed_at: None | str + mime_type: None | str + published_at: None | str + pulled_at: str + source_connection_content_version_id: None | str + title: None | str + awaiting_reindex: bool | Unset = False + extracted_media_capped: bool | Unset = False + extracted_media_count: int | None | Unset = UNSET + extracted_media_limit: int | None | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + content_status = self.content_status + + content_token_count: int | None + content_token_count = self.content_token_count + + content_type = self.content_type + + content_url: None | str + content_url = self.content_url + + content_version_id = self.content_version_id + + content_word_count: int | None + content_word_count = self.content_word_count + + error: None | str + error = self.error + + indexed_at: None | str + indexed_at = self.indexed_at + + mime_type: None | str + mime_type = self.mime_type + + published_at: None | str + published_at = self.published_at + + pulled_at = self.pulled_at + + source_connection_content_version_id: None | str + source_connection_content_version_id = self.source_connection_content_version_id + + title: None | str + title = self.title + + awaiting_reindex = self.awaiting_reindex + + extracted_media_capped = self.extracted_media_capped + + extracted_media_count: int | None | Unset + if isinstance(self.extracted_media_count, Unset): + extracted_media_count = UNSET + else: + extracted_media_count = self.extracted_media_count + + extracted_media_limit: int | None | Unset + if isinstance(self.extracted_media_limit, Unset): + extracted_media_limit = UNSET + else: + extracted_media_limit = self.extracted_media_limit + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "content_status": content_status, + "content_token_count": content_token_count, + "content_type": content_type, + "content_url": content_url, + "content_version_id": content_version_id, + "content_word_count": content_word_count, + "error": error, + "indexed_at": indexed_at, + "mime_type": mime_type, + "published_at": published_at, + "pulled_at": pulled_at, + "source_connection_content_version_id": source_connection_content_version_id, + "title": title, + } + ) + if awaiting_reindex is not UNSET: + field_dict["awaiting_reindex"] = awaiting_reindex + if extracted_media_capped is not UNSET: + field_dict["extracted_media_capped"] = extracted_media_capped + if extracted_media_count is not UNSET: + field_dict["extracted_media_count"] = extracted_media_count + if extracted_media_limit is not UNSET: + field_dict["extracted_media_limit"] = extracted_media_limit + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + content_status = d.pop("content_status") + + def _parse_content_token_count(data: object) -> int | None: + if data is None: + return data + return cast(int | None, data) + + content_token_count = _parse_content_token_count(d.pop("content_token_count")) + + content_type = d.pop("content_type") + + def _parse_content_url(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + content_url = _parse_content_url(d.pop("content_url")) + + content_version_id = d.pop("content_version_id") + + def _parse_content_word_count(data: object) -> int | None: + if data is None: + return data + return cast(int | None, data) + + content_word_count = _parse_content_word_count(d.pop("content_word_count")) + + def _parse_error(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + error = _parse_error(d.pop("error")) + + def _parse_indexed_at(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + indexed_at = _parse_indexed_at(d.pop("indexed_at")) + + def _parse_mime_type(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + mime_type = _parse_mime_type(d.pop("mime_type")) + + def _parse_published_at(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + published_at = _parse_published_at(d.pop("published_at")) + + pulled_at = d.pop("pulled_at") + + def _parse_source_connection_content_version_id(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + source_connection_content_version_id = ( + _parse_source_connection_content_version_id( + d.pop("source_connection_content_version_id") + ) + ) + + def _parse_title(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + title = _parse_title(d.pop("title")) + + awaiting_reindex = d.pop("awaiting_reindex", UNSET) + + extracted_media_capped = d.pop("extracted_media_capped", UNSET) + + def _parse_extracted_media_count(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + extracted_media_count = _parse_extracted_media_count( + d.pop("extracted_media_count", UNSET) + ) + + def _parse_extracted_media_limit(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + extracted_media_limit = _parse_extracted_media_limit( + d.pop("extracted_media_limit", UNSET) + ) + + source_content_status_response = cls( + content_status=content_status, + content_token_count=content_token_count, + content_type=content_type, + content_url=content_url, + content_version_id=content_version_id, + content_word_count=content_word_count, + error=error, + indexed_at=indexed_at, + mime_type=mime_type, + published_at=published_at, + pulled_at=pulled_at, + source_connection_content_version_id=source_connection_content_version_id, + title=title, + awaiting_reindex=awaiting_reindex, + extracted_media_capped=extracted_media_capped, + extracted_media_count=extracted_media_count, + extracted_media_limit=extracted_media_limit, + ) + + source_content_status_response.additional_properties = d + return source_content_status_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/seclai/_generated/models/start_source_embedding_migration_request.py b/seclai/_generated/models/start_source_embedding_migration_request.py index 74eb819..9cd57e3 100644 --- a/seclai/_generated/models/start_source_embedding_migration_request.py +++ b/seclai/_generated/models/start_source_embedding_migration_request.py @@ -17,7 +17,8 @@ class StartSourceEmbeddingMigrationRequest: Attributes: target_dimensions (int): Target embedding dimensions - target_embedding_model (str): Target embedding model enum + target_embedding_model (str): Target embedding model — a `model_type` from `GET /models/embedders`, which also + reports the `dimensions` each embedder supports and the modalities it can index. chunk_language (None | str | Unset): Language-specific chunking language code chunk_overlap (int | None | Unset): Override chunk overlap (characters) chunk_regex_separators (bool | None | Unset): Whether chunk separators are regex patterns diff --git a/seclai/_generated/models/update_knowledge_base_body.py b/seclai/_generated/models/update_knowledge_base_body.py index 82f4048..286f50e 100644 --- a/seclai/_generated/models/update_knowledge_base_body.py +++ b/seclai/_generated/models/update_knowledge_base_body.py @@ -16,12 +16,16 @@ class UpdateKnowledgeBaseBody: """Request body for updating a knowledge base. Attributes: - default_score_threshold (float | None | Unset): Default score threshold (-1 to clear). - default_top_k (int | None | Unset): Default reranked results (0 to clear). - default_top_n (int | None | Unset): Default results (0 to clear). + default_score_threshold (float | None | Unset): Prefilled into Minimum Rerank Score on a new retrieval step (-1 + to clear). + default_top_k (int | None | Unset): Prefilled into Top K on a new retrieval step (0 to clear). + default_top_n (int | None | Unset): Prefilled into Top N on a new retrieval step (0 to clear). description (None | str | Unset): New description. name (None | str | Unset): New name. - reranker_model (None | str | Unset): Reranker model (empty string for no reranking). + reranker_model (None | str | Unset): New reranker model — a `model_type` from `GET /models/rerankers`. Pass + "none" to turn reranking off (not a value from that list). Omitting the field (or sending null) leaves the + current reranker in place — it does NOT turn it off. "" is accepted as a synonym for "none", but prefer "none": + an empty string does not survive every client's serialization. source_ids (list[str] | None | Unset): New list of source connection IDs. """ diff --git a/seclai/_generated/models/update_memory_bank_body.py b/seclai/_generated/models/update_memory_bank_body.py index 30fa14d..19bd30a 100644 --- a/seclai/_generated/models/update_memory_bank_body.py +++ b/seclai/_generated/models/update_memory_bank_body.py @@ -23,14 +23,21 @@ class UpdateMemoryBankBody: exceed a threshold are summarized into a new entry before being soft-deleted. Send empty string "" to clear and disable summarisation. description (None | str | Unset): Optional description. Send empty string "" to clear. - max_age_days (int | None | Unset): Max entry age in days before compaction. Checked inline after each write and - by the hourly background sweep. Send 0 to disable. + max_age_days (int | None | Unset): DEPRECATED and no longer applied. Age now belongs solely to retention_days, + which deletes; compaction triggers on max_size_tokens and max_turns. Rejected with 400 for clients sending + Seclai-Version 2026-08-03 or later, except 0, which clears a value stored earlier. Accepted and stored but inert + for older clients. max_size_tokens (int | None | Unset): Max total tokens (per partition) before compaction. Checked inline after each write and by the hourly background sweep. Send 0 to disable. max_turns (int | None | Unset): Max conversation turns (per partition) before compaction. Checked inline after each write and by the hourly background sweep. Send 0 to disable. name (None | str | Unset): New name. retention_days (int | None | Unset): Content source retention in days. Send 0 to clear (indefinite). + strip_quoted_reply_chains (bool | None | Unset): Conversation banks only. When true, a conversation turn written + to this bank has the quoted reply chain an email client prepends to a reply dropped from it. Only inbound (user) + turns are affected, and only words in a run of at least ~40 matching a recent turn word for word are dropped + (line wrapping and punctuation at a word's edge are ignored). A word the sender changed is kept, including a + one-character change inside a link, address or amount, unless the change is only to that edge punctuation. """ compaction_prompt: None | str | Unset = UNSET @@ -40,6 +47,7 @@ class UpdateMemoryBankBody: max_turns: int | None | Unset = UNSET name: None | str | Unset = UNSET retention_days: int | None | Unset = UNSET + strip_quoted_reply_chains: bool | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -85,6 +93,12 @@ def to_dict(self) -> dict[str, Any]: else: retention_days = self.retention_days + strip_quoted_reply_chains: bool | None | Unset + if isinstance(self.strip_quoted_reply_chains, Unset): + strip_quoted_reply_chains = UNSET + else: + strip_quoted_reply_chains = self.strip_quoted_reply_chains + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) @@ -102,6 +116,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["name"] = name if retention_days is not UNSET: field_dict["retention_days"] = retention_days + if strip_quoted_reply_chains is not UNSET: + field_dict["strip_quoted_reply_chains"] = strip_quoted_reply_chains return field_dict @@ -172,6 +188,17 @@ def _parse_retention_days(data: object) -> int | None | Unset: retention_days = _parse_retention_days(d.pop("retention_days", UNSET)) + def _parse_strip_quoted_reply_chains(data: object) -> bool | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(bool | None | Unset, data) + + strip_quoted_reply_chains = _parse_strip_quoted_reply_chains( + d.pop("strip_quoted_reply_chains", UNSET) + ) + update_memory_bank_body = cls( compaction_prompt=compaction_prompt, description=description, @@ -180,6 +207,7 @@ def _parse_retention_days(data: object) -> int | None | Unset: max_turns=max_turns, name=name, retention_days=retention_days, + strip_quoted_reply_chains=strip_quoted_reply_chains, ) update_memory_bank_body.additional_properties = d diff --git a/seclai/_generated/models/update_source_body.py b/seclai/_generated/models/update_source_body.py index 19039bc..f946686 100644 --- a/seclai/_generated/models/update_source_body.py +++ b/seclai/_generated/models/update_source_body.py @@ -17,17 +17,20 @@ class UpdateSourceBody: Attributes: media_types (list[str] | None | Unset): Media kinds to extract from indexed content and embed as multi-modal KB - chunks. Subset of ['images', 'video']. Only kinds the source's embedder can index are honored; unsupported - values are dropped. [] disables media extraction (text-only). + chunks. Subset of ['images', 'video']. Only kinds the source's embedder can index are honored (see + `supported_input_media` on GET /models/embedders); unsupported values are dropped. [] disables media extraction + (text-only). name (None | str | Unset): New name. polling (None | str | Unset): New polling interval. - retention_days (int | None | Unset): New retention period in days (null for unlimited). Default: -1. + retention_days (int | None | Unset): New retention period in days — content older than this is deleted + permanently. Send null to clear the window: content is then kept indefinitely. Omit the field to leave it + unchanged. """ media_types: list[str] | None | Unset = UNSET name: None | str | Unset = UNSET polling: None | str | Unset = UNSET - retention_days: int | None | Unset = -1 + retention_days: int | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: diff --git a/seclai/_generated/models/variant_option_response.py b/seclai/_generated/models/variant_option_response.py index 4c86dec..4be2180 100644 --- a/seclai/_generated/models/variant_option_response.py +++ b/seclai/_generated/models/variant_option_response.py @@ -20,11 +20,17 @@ class VariantOptionResponse: title (str): value (str): description (None | str | Unset): - input_1h_cache_write_credits_per_1000_tokens (float | None | Unset): - input_5m_cache_write_credits_per_1000_tokens (float | None | Unset): - input_cache_hit_credits_per_1000_tokens (float | None | Unset): + input_1h_cache_write_credits_per_1000_tokens (float | None | Unset): Credits per 1,000 input tokens written to a + 1-hour prompt cache. + input_30m_cache_write_credits_per_1000_tokens (float | None | Unset): Credits per 1,000 input tokens written to + a 30-minute prompt cache. + input_5m_cache_write_credits_per_1000_tokens (float | None | Unset): Credits per 1,000 input tokens written to a + 5-minute prompt cache. + input_cache_hit_credits_per_1000_tokens (float | None | Unset): Credits per 1,000 input tokens read from a + prompt cache. input_credits_per_1000_tokens (float | None | Unset): - long_context_input_cache_hit_credits_per_1000_tokens (float | None | Unset): + long_context_input_cache_hit_credits_per_1000_tokens (float | None | Unset): Credits per 1,000 input tokens read + from a prompt cache, on a call whose input exceeds `long_context_threshold` tokens. long_context_input_credits_per_1000_tokens (float | None | Unset): long_context_output_credits_per_1000_tokens (float | None | Unset): long_context_threshold (int | None | Unset): @@ -36,6 +42,7 @@ class VariantOptionResponse: value: str description: None | str | Unset = UNSET input_1h_cache_write_credits_per_1000_tokens: float | None | Unset = UNSET + input_30m_cache_write_credits_per_1000_tokens: float | None | Unset = UNSET input_5m_cache_write_credits_per_1000_tokens: float | None | Unset = UNSET input_cache_hit_credits_per_1000_tokens: float | None | Unset = UNSET input_credits_per_1000_tokens: float | None | Unset = UNSET @@ -67,6 +74,14 @@ def to_dict(self) -> dict[str, Any]: self.input_1h_cache_write_credits_per_1000_tokens ) + input_30m_cache_write_credits_per_1000_tokens: float | None | Unset + if isinstance(self.input_30m_cache_write_credits_per_1000_tokens, Unset): + input_30m_cache_write_credits_per_1000_tokens = UNSET + else: + input_30m_cache_write_credits_per_1000_tokens = ( + self.input_30m_cache_write_credits_per_1000_tokens + ) + input_5m_cache_write_credits_per_1000_tokens: float | None | Unset if isinstance(self.input_5m_cache_write_credits_per_1000_tokens, Unset): input_5m_cache_write_credits_per_1000_tokens = UNSET @@ -140,6 +155,10 @@ def to_dict(self) -> dict[str, Any]: field_dict["input_1h_cache_write_credits_per_1000_tokens"] = ( input_1h_cache_write_credits_per_1000_tokens ) + if input_30m_cache_write_credits_per_1000_tokens is not UNSET: + field_dict["input_30m_cache_write_credits_per_1000_tokens"] = ( + input_30m_cache_write_credits_per_1000_tokens + ) if input_5m_cache_write_credits_per_1000_tokens is not UNSET: field_dict["input_5m_cache_write_credits_per_1000_tokens"] = ( input_5m_cache_write_credits_per_1000_tokens @@ -204,6 +223,21 @@ def _parse_input_1h_cache_write_credits_per_1000_tokens( ) ) + def _parse_input_30m_cache_write_credits_per_1000_tokens( + data: object, + ) -> float | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(float | None | Unset, data) + + input_30m_cache_write_credits_per_1000_tokens = ( + _parse_input_30m_cache_write_credits_per_1000_tokens( + d.pop("input_30m_cache_write_credits_per_1000_tokens", UNSET) + ) + ) + def _parse_input_5m_cache_write_credits_per_1000_tokens( data: object, ) -> float | None | Unset: @@ -318,6 +352,7 @@ def _parse_output_credits_per_1000_tokens(data: object) -> float | None | Unset: value=value, description=description, input_1h_cache_write_credits_per_1000_tokens=input_1h_cache_write_credits_per_1000_tokens, + input_30m_cache_write_credits_per_1000_tokens=input_30m_cache_write_credits_per_1000_tokens, input_5m_cache_write_credits_per_1000_tokens=input_5m_cache_write_credits_per_1000_tokens, input_cache_hit_credits_per_1000_tokens=input_cache_hit_credits_per_1000_tokens, input_credits_per_1000_tokens=input_credits_per_1000_tokens, diff --git a/seclai/seclai.py b/seclai/seclai.py index 80269dc..5fe4377 100644 --- a/seclai/seclai.py +++ b/seclai/seclai.py @@ -46,7 +46,7 @@ from http import HTTPStatus from io import BytesIO from pathlib import Path -from typing import Any, BinaryIO, Self, TypedDict, cast, overload +from typing import Any, BinaryIO, Literal, Self, TypedDict, TypeVar, cast, overload import httpx @@ -95,9 +95,9 @@ class AgentRunStreamRequest(TypedDict): def unwrap_items(payload: Any, *legacy_keys: str) -> list[dict[str, Any]]: """Return the items of a version-gated list endpoint, whichever shape it used. - Six endpoints key their list differently depending on the ``Seclai-Version`` + Some endpoints key their list differently depending on the ``Seclai-Version`` the request resolves to. On the legacy baseline it is a bare JSON array or a - per-resource key (``configs``, ``alerts``, ``tiers``, ``experiments``); from + per-resource key (``configs``, ``alerts``, ``models`` and the like); from ``2026-07-27`` it is the canonical ``{"data": [...], "pagination": {...}}`` envelope. Both are live during the rollout, so reading only one breaks the day the other arrives. @@ -140,8 +140,31 @@ def unwrap_items(payload: Any, *legacy_keys: str) -> list[dict[str, Any]]: ) -#: Deprecated alias kept for internal call sites; use :func:`unwrap_items`. -_unwrap_data = unwrap_items +def _as_page(result: Any) -> dict[str, Any]: + """Normalise a version-gated list response to the ``{data, ...}`` envelope. + + The canonical envelope is passed through untouched, including its + ``pagination`` key; the legacy bare array is wrapped so callers can read + ``["data"]`` either way and use ``.get("pagination")`` to tell them apart. + """ + if isinstance(result, dict): + return cast(dict[str, Any], result) + return {"data": result} + + +def _empty_page(*, page: int, limit: int) -> dict[str, Any]: + """The canonical envelope for a listing that matched nothing.""" + return { + "data": [], + "pagination": { + "page": page, + "limit": limit, + "total": 0, + "pages": 0, + "has_next": False, + "has_prev": False, + }, + } def _strip_none(params: dict[str, Any]) -> dict[str, Any]: @@ -149,6 +172,22 @@ def _strip_none(params: dict[str, Any]) -> dict[str, Any]: return {k: v for k, v in params.items() if v is not None} +_ModelT = TypeVar("_ModelT") + + +def _expect_model(parsed: object, model: type[_ModelT]) -> _ModelT: + """Narrow a generated-client result to the success model its caller declares. + + The generated union also carries each documented error body, which the + status check before this call has already raised on. + """ + if not isinstance(parsed, model): + raise SeclaiError( + f"Expected {model.__name__} in the response, got {type(parsed).__name__}." + ) + return parsed + + class SeclaiError(Exception): """Base error for the Seclai SDK.""" @@ -274,6 +313,40 @@ class ClientOptions: allow_unknown_api_version: bool = False +def _merge_headers( + base: dict[str, str], overrides: Mapping[str, str] | None +) -> dict[str, str]: + """Apply ``overrides`` onto ``base`` case-insensitively, in place. + + Header names are case-insensitive on the wire but dict keys are not, so a + plain ``dict.update`` leaves two spellings of one header in the mapping; + httpx then emits both and the server picks one arbitrarily. + + The match is recomputed per key rather than once up front: ``overrides`` may + itself carry two spellings of one header, and a snapshot taken before the + loop would not see the first of them being added. + """ + if not overrides: + return base + for key, value in overrides.items(): + lowered = key.lower() + for existing in [k for k in base if k.lower() == lowered]: + del base[existing] + base[key] = value + return base + + +def _setdefault_header(headers: dict[str, str], name: str, value: str) -> None: + """Set ``name`` only when no spelling of it is already present. + + ``dict.setdefault`` is case-sensitive, so a caller-supplied ``Accept`` would + not stop the SDK adding its own lowercase ``accept`` and both would go out. + """ + lowered = name.lower() + if not any(k.lower() == lowered for k in headers): + headers[name] = value + + def _build_default_headers( *, auth_state: AuthState, @@ -303,19 +376,7 @@ def _build_default_headers( # against, so upgrading the SDK alone never changes the wire contract. if api_version: headers["seclai-version"] = api_version - if default_headers: - # Case-insensitively, so a caller-supplied `Seclai-Version` (or any other - # differently-cased default) replaces ours rather than joining it. httpx - # emits both keys otherwise and the server picks one arbitrarily. - # - # Recomputed per key rather than once up front: `default_headers` may - # itself carry two spellings of one header, and a snapshot taken before - # the loop would not see the first of them being added. - for key, value in default_headers.items(): - for existing in [k for k in headers if k.lower() == key.lower()]: - del headers[existing] - headers[key] = value - return headers + return _merge_headers(headers, default_headers) def _merge_request_headers( @@ -337,9 +398,9 @@ def _merge_request_headers( raise SeclaiConfigurationError(str(exc)) from exc except Exception as exc: raise SeclaiConfigurationError(f"Auth resolution failed: {exc}") from exc - merged.update(auth_headers) - if request_headers: - merged.update(request_headers) + _merge_headers(merged, auth_headers) + _validate_request_version(options, request_headers) + _merge_headers(merged, request_headers) return merged @@ -362,20 +423,14 @@ async def _merge_request_headers_async( raise SeclaiConfigurationError(str(exc)) from exc except Exception as exc: raise SeclaiConfigurationError(f"Auth resolution failed: {exc}") from exc - merged.update(auth_headers) - if request_headers: - merged.update(request_headers) + _merge_headers(merged, auth_headers) + _validate_request_version(options, request_headers) + _merge_headers(merged, request_headers) return merged def _raise_for_status(response: httpx.Response) -> None: - """Raise on a non-success status, `SeclaiAPIValidationError` for a 422. - - The generated-client path has always distinguished the two; this one did not, - so every method built on :meth:`Seclai.request` — most of the SDK — reported a - validation failure as a bare status error and discarded the field-level - detail the API returned. - """ + """Raise on a non-success status, `SeclaiAPIValidationError` for a 422.""" if 200 <= response.status_code < 400: return try: @@ -388,14 +443,26 @@ def _raise_for_status(response: httpx.Response) -> None: except Exception: payload = None if isinstance(payload, dict) and "detail" in payload: - raise SeclaiAPIValidationError( - message="Validation error", - status_code=response.status_code, - method=response.request.method, - url=str(response.request.url), - response_text=response_text, - validation_error=HTTPValidationError.from_dict(payload), - ) + # `detail` only holds a list of `{loc, msg, type}` objects when the + # 422 came from request-model validation. A hand-raised + # `HTTPException(422, detail="...")` puts a bare string there, and + # `from_dict` then iterates it and raises ValueError/TypeError/ + # KeyError from inside the generated models. Fall through to the + # status error rather than replacing an API failure with a decoding + # one that no `except SeclaiError` handler catches. + try: + validation_error = HTTPValidationError.from_dict(payload) + except Exception: + validation_error = None + if validation_error is not None: + raise SeclaiAPIValidationError( + message="Validation error", + status_code=response.status_code, + method=response.request.method, + url=str(response.request.url), + response_text=response_text, + validation_error=validation_error, + ) raise SeclaiAPIStatusError( message=f"Request failed with status {response.status_code}", status_code=response.status_code, @@ -405,6 +472,40 @@ def _raise_for_status(response: httpx.Response) -> None: ) +def _raise_on_error_status(response: httpx.Response) -> None: + """httpx response hook: raise for an error status before its body is decoded.""" + if response.status_code >= 400: + response.read() + _raise_for_status(response) + + +async def _raise_on_error_status_async(response: httpx.Response) -> None: + """Async twin of :func:`_raise_on_error_status`.""" + if response.status_code >= 400: + await response.aread() + _raise_for_status(response) + + +def _validate_request_version( + options: ClientOptions, request_headers: Mapping[str, str] | None +) -> None: + """Apply the unknown-version guard to a per-request ``Seclai-Version``.""" + # The last spelling is the one `_merge_headers` leaves on the wire. + versions = [ + value + for key, value in (request_headers or {}).items() + if key.lower() == "seclai-version" + ] + if not versions: + return + try: + validate_api_version( + versions[-1], allow_unknown=options.allow_unknown_api_version + ) + except ValueError as e: + raise SeclaiConfigurationError(f"{e} (via headers['Seclai-Version'])") from e + + class _SeclaiBase: """Shared implementation for Seclai sync/async clients. @@ -476,6 +577,12 @@ def __init__( except RuntimeError as e: raise SeclaiConfigurationError(str(e)) from e + # Snapshotted, not aliased: `_build_default_headers` re-reads this on + # every request, so keeping the caller's mapping would let a later + # `hdrs["Seclai-Version"] = ...` put an unvalidated version on the wire + # and defeat the guard below. + frozen_headers: dict[str, str] = dict(default_headers or {}) + # `default_headers` is applied last so an explicit header wins, which # means it can also carry a Seclai-Version. Validate whichever value # actually reaches the wire, not just the argument — otherwise the guard @@ -483,17 +590,23 @@ def __init__( # The LAST matching key, because that is the one the header merge keeps. # Taking the first match would approve a value the client never sends # when `default_headers` carries two spellings of the same header. - header_version = None - for k, v in (default_headers or {}).items(): + header_version: str | None = None + for k, v in frozen_headers.items(): if k.lower() == "seclai-version": header_version = v + # `is None`, not truthiness: an empty `Seclai-Version` still reaches the + # wire and still suppresses the `api_version` opt-in, so it has to be + # validated (and rejected) rather than read as "no header supplied". try: validate_api_version( - header_version or api_version, allow_unknown=allow_unknown_api_version + api_version if header_version is None else header_version, + allow_unknown=allow_unknown_api_version, ) except ValueError as e: source = ( - "default_headers['Seclai-Version']" if header_version else "api_version" + "default_headers['Seclai-Version']" + if header_version is not None + else "api_version" ) raise SeclaiConfigurationError(f"{e} (via {source})") from e @@ -501,7 +614,7 @@ def __init__( auth_state=auth_state, timeout=timeout, api_key_header=api_key_header, - default_headers=default_headers or {}, + default_headers=frozen_headers, api_version=api_version, allow_unknown_api_version=allow_unknown_api_version, ) @@ -529,8 +642,9 @@ def _default_headers(self) -> dict[str, str]: def _generated_client(self) -> GeneratedClient: """Return a cached generated OpenAPI client configured with this client's auth. - This is primarily used internally by the wrapper methods in this file. Advanced - usage may call this to access generated request helpers. + Used by the wrapper methods in this file. Once one of them has run, the + client's httpx client raises `SeclaiAPIStatusError` for a 4xx/5xx rather + than returning it to a generated request helper. """ if self._generated_client_instance is None: self._generated_client_instance = GeneratedClient( @@ -541,11 +655,10 @@ def _generated_client(self) -> GeneratedClient: return self._generated_client_instance def _sync_generated_client(self) -> GeneratedClient: - """Return the generated client with dynamic auth headers applied (sync). + """Return the generated client, ready to send (sync). - For ``bearer_provider`` and ``sso`` modes, this resolves fresh auth headers - and updates the generated client before returning it. For static modes - (``api_key``, ``bearer_static``) this is identical to :meth:`_generated_client`. + Resolves fresh auth headers for the ``bearer_provider`` and ``sso`` modes, + and makes its httpx client raise through :func:`_raise_for_status`. """ gc = self._generated_client() if self._options.auth_state.mode in ("bearer_provider", "sso"): @@ -568,14 +681,17 @@ def _sync_generated_client(self) -> GeneratedClient: # so pre-configured transports (e.g. in tests) aren't lost. if gc._client is not None: evolved.set_httpx_client(gc._client) - return self._generated_client_instance # type: ignore[return-value] + client = self._generated_client() + hooks = client.get_httpx_client().event_hooks["response"] + if _raise_on_error_status not in hooks: + hooks.append(_raise_on_error_status) + return client async def _async_generated_client(self) -> GeneratedClient: - """Return the generated client with dynamic auth headers applied (async). + """Return the generated client, ready to send (async). - For ``bearer_provider`` and ``sso`` modes, this resolves fresh auth headers - and updates the generated client before returning it. For static modes - (``api_key``, ``bearer_static``) this is identical to :meth:`_generated_client`. + Resolves fresh auth headers for the ``bearer_provider`` and ``sso`` modes, + and makes its httpx client raise through :func:`_raise_for_status`. """ gc = self._generated_client() if self._options.auth_state.mode in ("bearer_provider", "sso"): @@ -593,7 +709,11 @@ async def _async_generated_client(self) -> GeneratedClient: self._generated_client_instance = evolved if gc._async_client is not None: evolved.set_async_httpx_client(gc._async_client) - return self._generated_client_instance # type: ignore[return-value] + client = self._generated_client() + hooks = client.get_async_httpx_client().event_hooks["response"] + if _raise_on_error_status_async not in hooks: + hooks.append(_raise_on_error_status_async) + return client def _build_url(self, path: str) -> str: """Build an absolute URL string from a request path. @@ -891,7 +1011,7 @@ def run_streaming_agent_and_wait( merged_headers = _merge_request_headers( options=self._options, request_headers=headers ) - merged_headers.setdefault("accept", "text/event-stream") + _setdefault_header(merged_headers, "accept", "text/event-stream") timeout_seconds = self._options.timeout if timeout is None else timeout start = _time.monotonic() @@ -904,16 +1024,10 @@ def run_streaming_agent_and_wait( headers=merged_headers, timeout=timeout_seconds, ) as response: - if response.status_code == HTTPStatus.UNPROCESSABLE_ENTITY: - payload = response.json() - raise SeclaiAPIValidationError( - message=f"Request failed with status {response.status_code}", - status_code=int(response.status_code), - method="POST", - url=self._build_url(path), - response_text=response.text, - validation_error=HTTPValidationError.from_dict(payload), - ) + if response.status_code >= 400: + # Lazy body inside `stream()`; read it so the error carries + # its text and a 422 its field-level detail. + response.read() _raise_for_status(response) current_event: str | None = None @@ -1027,7 +1141,7 @@ def list_agent_runs( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, AgentRunListResponse) @overload def get_agent_run( @@ -1101,7 +1215,7 @@ def get_agent_run( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, AgentRunResponse) @overload def delete_agent_run(self, run_id: str, /) -> AgentRunResponse: ... @@ -1163,7 +1277,7 @@ def delete_agent_run(self, *args: str) -> AgentRunResponse: response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, AgentRunResponse) def get_content_detail( self, @@ -1223,7 +1337,7 @@ def get_content_detail( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, ContentDetailResponse) def delete_content(self, source_connection_content_version: str) -> None: """Delete a specific content version. @@ -1312,7 +1426,7 @@ def list_content_embeddings( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, ContentEmbeddingsListResponse) def list_sources( self, @@ -1378,7 +1492,7 @@ def list_sources( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, SourceListResponse) def upload_file_to_source( self, @@ -1670,7 +1784,7 @@ def upload_file_to_content( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, FileUploadResponse) finally: if created_payload is not None: created_payload.close() @@ -2216,7 +2330,7 @@ def list_evaluation_criteria( page_result = self.list_evaluation_criteria_page( agent_id, page=page, limit=limit ) - return _unwrap_data(page_result) + return unwrap_items(page_result) def list_evaluation_criteria_page( self, agent_id: str, *, page: int = 1, limit: int = 50 @@ -2243,9 +2357,7 @@ def list_evaluation_criteria_page( f"/agents/{agent_id}/evaluation-criteria", params=_strip_none({"page": page, "limit": limit}), ) - if isinstance(result, dict): - return cast(dict[str, Any], result) - return {"data": result} + return _as_page(result) def create_evaluation_criteria( self, agent_id: str, body: dict[str, Any] @@ -2459,7 +2571,7 @@ def list_run_evaluation_results( page_result = self.list_run_evaluation_results_page( agent_id, run_id, page=page, limit=limit ) - return _unwrap_data(page_result) + return unwrap_items(page_result) def list_run_evaluation_results_page( self, agent_id: str, run_id: str, *, page: int = 1, limit: int = 50 @@ -2483,9 +2595,7 @@ def list_run_evaluation_results_page( f"/agents/{agent_id}/runs/{run_id}/evaluation-results", params=_strip_none({"page": page, "limit": limit}), ) - if isinstance(result, dict): - return cast(dict[str, Any], result) - return {"data": result} + return _as_page(result) def list_evaluation_runs( self, agent_id: str, *, page: int = 1, limit: int = 50 @@ -3111,6 +3221,74 @@ def upload_inline_text_to_source( ), ) + def list_source_contents( + self, + source_id: str, + *, + page: int | None = None, + limit: int | None = None, + sort: str | None = None, + order: str | None = None, + status: str | None = None, + content_version_ids: list[str] | None = None, + ) -> dict[str, Any]: + """List a source's content items and their indexing status. + + Args: + source_id: Source identifier. + page: Page number (1-indexed, default 1). + limit: Items per page (1-100, default 20). + sort: Sort field — ``created_at``, ``title`` or ``status``. + order: ``asc`` or ``desc``. + status: Keep only one status: ``pending``, ``fetching``, + ``transcribing``, ``scanning``, ``indexing``, ``completed`` or + ``failed``. + content_version_ids: Keep only these items — the + ``content_version_id`` values the upload methods return — to + poll a batch of uploads in one request. At most 500. + + Returns: + ``{"data": [...], "pagination": {...}}`` on every API version. An + empty ``content_version_ids`` matches nothing: an empty page is + returned without sending a request. + """ + if content_version_ids is not None and not content_version_ids: + return _empty_page(page=page or 1, limit=limit or 20) + return cast( + dict[str, Any], + self.request( + "GET", + f"/sources/{source_id}/contents", + params=_strip_none( + { + "page": page, + "limit": limit, + "sort": sort, + "order": order, + "status": status, + "content_version_id": content_version_ids, + } + ), + ), + ) + + def get_source_content_status( + self, source_id: str, content_version_id: str + ) -> dict[str, Any]: + """Get one content item's indexing status. + + Args: + source_id: Source identifier. + content_version_id: The ``content_version_id`` an upload returned. + + Returns: + The item and its indexing status. + """ + return cast( + dict[str, Any], + self.request("GET", f"/sources/{source_id}/contents/{content_version_id}"), + ) + # ── Source Exports ──────────────────────────────────────────────────────── def list_source_exports( @@ -4057,6 +4235,47 @@ def get_generation_tiers(self) -> dict[str, Any]: """ return cast(dict[str, Any], self.request("GET", "/models/generation-tiers")) + def list_embedding_models( + self, *, supports_input_media: str | None = None + ) -> dict[str, Any]: + """List the embedding models a source can index with, and their pricing. + + Args: + supports_input_media: Keep only embedders that can index this input + modality. + + Returns: + The embedders under ``models`` by default, and under ``data`` with + ``pagination`` once the client opts in with + ``api_version="2026-07-27"`` or later; the defaults and pricing sit + beside them on either shape. Read the list with + :func:`unwrap_items`:: + + items = unwrap_items(client.list_embedding_models(), "models") + """ + return cast( + dict[str, Any], + self.request( + "GET", + "/models/embedders", + params=_strip_none({"supports_input_media": supports_input_media}), + ), + ) + + def list_reranker_models(self) -> dict[str, Any]: + """List the reranker models a knowledge base can use, and their pricing. + + Returns: + The rerankers under ``models`` by default, and under ``data`` with + ``pagination`` once the client opts in with + ``api_version="2026-07-27"`` or later; the default and pricing sit + beside them on either shape. Read the list with + :func:`unwrap_items`:: + + items = unwrap_items(client.list_reranker_models(), "models") + """ + return cast(dict[str, Any], self.request("GET", "/models/rerankers")) + # ── Model Playground Experiments ────────────────────────────────────────── def list_experiments( @@ -4145,6 +4364,112 @@ def delete_experiment(self, experiment_id: str) -> None: """ self.request("DELETE", f"/models/playground/experiments/{experiment_id}") + # ── Cloud Drives ────────────────────────────────────────────────────────── + + def list_cloud_drive_providers(self) -> list[dict[str, Any]]: + """List the cloud-drive providers available to the account. + + Returns: + The providers, read from either response shape. + """ + return unwrap_items(self.request("GET", "/cloud-drives/providers")) + + def list_cloud_drives(self) -> list[dict[str, Any]]: + """List the account's cloud-drive connections. + + Returns: + The connections, read from either response shape. + """ + return unwrap_items(self.request("GET", "/cloud-drives")) + + def get_cloud_drive(self, connection_id: str) -> dict[str, Any]: + """Get a cloud-drive connection. + + Args: + connection_id: Cloud-drive connection identifier. + + Returns: + The connection. + """ + return cast( + dict[str, Any], self.request("GET", f"/cloud-drives/{connection_id}") + ) + + def update_cloud_drive( + self, connection_id: str, body: dict[str, Any] + ) -> dict[str, Any]: + """Update a cloud-drive connection. + + Args: + connection_id: Cloud-drive connection identifier. + body: Fields to change — ``name`` and/or ``folder_path``. + + Returns: + The updated connection. + """ + return cast( + dict[str, Any], + self.request("PATCH", f"/cloud-drives/{connection_id}", json=body), + ) + + def disconnect_cloud_drive(self, connection_id: str) -> dict[str, Any]: + """Disconnect a cloud-drive connection, keeping the connection itself. + + Args: + connection_id: Cloud-drive connection identifier. + + Returns: + The connection in its disconnected state. + """ + return cast( + dict[str, Any], + self.request("POST", f"/cloud-drives/{connection_id}/disconnect"), + ) + + def delete_cloud_drive(self, connection_id: str) -> None: + """Delete a cloud-drive connection. + + Args: + connection_id: Cloud-drive connection identifier. + """ + self.request("DELETE", f"/cloud-drives/{connection_id}") + + def get_agents_using_cloud_drive(self, connection_id: str) -> list[dict[str, Any]]: + """List the agents that use a cloud-drive connection. + + Args: + connection_id: Cloud-drive connection identifier. + + Returns: + The agents, read from either response shape. + """ + return unwrap_items( + self.request("GET", f"/cloud-drives/{connection_id}/agents") + ) + + def list_cloud_drive_rejections( + self, connection_id: str, *, limit: int | None = None + ) -> list[dict[str, Any]]: + """List the files a cloud-drive connection skipped, newest first. + + A skipped file fires no trigger, so this is where to look when an agent + did not run for a file. + + Args: + connection_id: Cloud-drive connection identifier. + limit: Maximum number of rejections (1-200, default 50). + + Returns: + The rejections with their reasons, read from either response shape. + """ + return unwrap_items( + self.request( + "GET", + f"/cloud-drives/{connection_id}/rejections", + params=_strip_none({"limit": limit}), + ) + ) + # ── Search ──────────────────────────────────────────────────────────────── def search( @@ -4472,6 +4797,7 @@ def paginate( params: dict[str, Any] | None = None, limit: int = 50, items_key: str = "data", + param_style: Literal["page", "offset"] = "page", ) -> Generator[dict[str, Any]]: """Auto-paginate a list endpoint. @@ -4481,26 +4807,47 @@ def paginate( Args: method: HTTP method (typically ``"GET"``). path: API path. - params: Extra query parameters (``page`` and ``limit`` are managed automatically). + params: Extra query parameters (the cursor and ``limit`` are managed + automatically). limit: Items per page. - items_key: JSON key containing the list of items (default ``"data"``). + items_key: Per-resource key the items sit under when the response + is not the ``data`` envelope, which is always read first. + param_style: ``"page"`` (default) sends a 1-indexed ``page``; + ``"offset"`` sends a 0-based ``offset``. A few endpoints — + ``/models/alerts`` among them — declare only ``offset`` and + reject or ignore ``page``, which makes every request after the + first return page 1. Yields: Individual item dicts from each page. + + Raises: + ValueError: If ``param_style`` is neither ``"page"`` nor ``"offset"``. + SeclaiError: If a page is neither a list nor an object carrying + ``data`` or ``items_key``. """ + if param_style not in ("page", "offset"): + raise ValueError( + f"param_style must be 'page' or 'offset', not {param_style!r}" + ) page = 1 base_params = dict(params) if params else {} while True: - base_params["page"] = page + if param_style == "offset": + base_params["offset"] = (page - 1) * limit + else: + base_params["page"] = page base_params["limit"] = limit result = self.request(method, path, params=base_params) - if not isinstance(result, dict): - return - items = result.get(items_key, []) - if not isinstance(items, list): + # A bare array is an unpaginated response: it is everything, so + # asking for a second page would return the same items again. + if isinstance(result, list): + for item in result: + yield cast(dict[str, Any], item) return + items = unwrap_items(result, items_key) for item in items: - yield cast(dict[str, Any], item) + yield item if len(items) < limit: return page += 1 @@ -4574,7 +4921,7 @@ def run_streaming_agent( merged_headers = _merge_request_headers( options=self._options, request_headers=headers ) - merged_headers.setdefault("accept", "text/event-stream") + _setdefault_header(merged_headers, "accept", "text/event-stream") timeout_seconds = self._options.timeout if timeout is None else timeout start = time.monotonic() @@ -4586,6 +4933,10 @@ def run_streaming_agent( headers=merged_headers, timeout=timeout_seconds, ) as response: + if response.status_code >= 400: + # Lazy body inside `stream()`; read it so a 422's field-level + # detail survives into SeclaiAPIValidationError. + response.read() _raise_for_status(response) current_event: str | None = None data_lines: list[str] = [] @@ -4887,7 +5238,7 @@ async def run_streaming_agent_and_wait( merged_headers = await _merge_request_headers_async( options=self._options, request_headers=headers ) - merged_headers.setdefault("accept", "text/event-stream") + _setdefault_header(merged_headers, "accept", "text/event-stream") timeout_seconds = self._options.timeout if timeout is None else timeout start = _time.monotonic() @@ -4900,16 +5251,10 @@ async def run_streaming_agent_and_wait( headers=merged_headers, timeout=timeout_seconds, ) as response: - if response.status_code == HTTPStatus.UNPROCESSABLE_ENTITY: - payload = response.json() - raise SeclaiAPIValidationError( - message=f"Request failed with status {response.status_code}", - status_code=int(response.status_code), - method="POST", - url=self._build_url(path), - response_text=response.text, - validation_error=HTTPValidationError.from_dict(payload), - ) + if response.status_code >= 400: + # Lazy body inside `stream()`; read it so the error carries + # its text and a 422 its field-level detail. + await response.aread() _raise_for_status(response) current_event: str | None = None @@ -5023,7 +5368,7 @@ async def list_agent_runs( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, AgentRunListResponse) @overload async def get_agent_run( @@ -5097,7 +5442,7 @@ async def get_agent_run( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, AgentRunResponse) @overload async def delete_agent_run(self, run_id: str, /) -> AgentRunResponse: ... @@ -5164,7 +5509,7 @@ async def delete_agent_run(self, *args: str) -> AgentRunResponse: response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, AgentRunResponse) async def get_content_detail( self, @@ -5224,7 +5569,7 @@ async def get_content_detail( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, ContentDetailResponse) async def delete_content(self, source_connection_content_version: str) -> None: """Delete a specific content version. @@ -5313,7 +5658,7 @@ async def list_content_embeddings( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, ContentEmbeddingsListResponse) async def list_sources( self, @@ -5379,7 +5724,7 @@ async def list_sources( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, SourceListResponse) async def upload_file_to_source( self, @@ -5668,7 +6013,7 @@ async def upload_file_to_content( response_text=None, validation_error=parsed, ) - return parsed + return _expect_model(parsed, FileUploadResponse) finally: if created_payload is not None: created_payload.close() @@ -6232,7 +6577,7 @@ async def list_evaluation_criteria( page_result = await self.list_evaluation_criteria_page( agent_id, page=page, limit=limit ) - return _unwrap_data(page_result) + return unwrap_items(page_result) async def list_evaluation_criteria_page( self, agent_id: str, *, page: int = 1, limit: int = 50 @@ -6259,9 +6604,7 @@ async def list_evaluation_criteria_page( f"/agents/{agent_id}/evaluation-criteria", params=_strip_none({"page": page, "limit": limit}), ) - if isinstance(result, dict): - return cast(dict[str, Any], result) - return {"data": result} + return _as_page(result) async def create_evaluation_criteria( self, agent_id: str, body: dict[str, Any] @@ -6475,7 +6818,7 @@ async def list_run_evaluation_results( page_result = await self.list_run_evaluation_results_page( agent_id, run_id, page=page, limit=limit ) - return _unwrap_data(page_result) + return unwrap_items(page_result) async def list_run_evaluation_results_page( self, agent_id: str, run_id: str, *, page: int = 1, limit: int = 50 @@ -6499,9 +6842,7 @@ async def list_run_evaluation_results_page( f"/agents/{agent_id}/runs/{run_id}/evaluation-results", params=_strip_none({"page": page, "limit": limit}), ) - if isinstance(result, dict): - return cast(dict[str, Any], result) - return {"data": result} + return _as_page(result) async def list_evaluation_runs( self, agent_id: str, *, page: int = 1, limit: int = 50 @@ -7138,6 +7479,76 @@ async def upload_inline_text_to_source( ), ) + async def list_source_contents( + self, + source_id: str, + *, + page: int | None = None, + limit: int | None = None, + sort: str | None = None, + order: str | None = None, + status: str | None = None, + content_version_ids: list[str] | None = None, + ) -> dict[str, Any]: + """List a source's content items and their indexing status. + + Args: + source_id: Source identifier. + page: Page number (1-indexed, default 1). + limit: Items per page (1-100, default 20). + sort: Sort field — ``created_at``, ``title`` or ``status``. + order: ``asc`` or ``desc``. + status: Keep only one status: ``pending``, ``fetching``, + ``transcribing``, ``scanning``, ``indexing``, ``completed`` or + ``failed``. + content_version_ids: Keep only these items — the + ``content_version_id`` values the upload methods return — to + poll a batch of uploads in one request. At most 500. + + Returns: + ``{"data": [...], "pagination": {...}}`` on every API version. An + empty ``content_version_ids`` matches nothing: an empty page is + returned without sending a request. + """ + if content_version_ids is not None and not content_version_ids: + return _empty_page(page=page or 1, limit=limit or 20) + return cast( + dict[str, Any], + await self.request( + "GET", + f"/sources/{source_id}/contents", + params=_strip_none( + { + "page": page, + "limit": limit, + "sort": sort, + "order": order, + "status": status, + "content_version_id": content_version_ids, + } + ), + ), + ) + + async def get_source_content_status( + self, source_id: str, content_version_id: str + ) -> dict[str, Any]: + """Get one content item's indexing status. + + Args: + source_id: Source identifier. + content_version_id: The ``content_version_id`` an upload returned. + + Returns: + The item and its indexing status. + """ + return cast( + dict[str, Any], + await self.request( + "GET", f"/sources/{source_id}/contents/{content_version_id}" + ), + ) + # ── Source Exports ──────────────────────────────────────────────────────── async def list_source_exports( @@ -7901,7 +8312,7 @@ async def list_alert_configs(self, *, page: int = 1, limit: int = 50) -> JSONVal ``api_version="2026-07-27"`` or later. Read either with :func:`unwrap_items`:: - items = unwrap_items(client.list_alert_configs(), "configs") + items = unwrap_items(await client.list_alert_configs(), "configs") """ return await self.request( "GET", @@ -8099,13 +8510,54 @@ async def get_generation_tiers(self) -> dict[str, Any]: ``api_version="2026-07-27"`` or later. Read either with :func:`unwrap_items`:: - items = unwrap_items(client.get_generation_tiers(), "tiers") + items = unwrap_items(await client.get_generation_tiers(), "tiers") """ return cast( dict[str, Any], await self.request("GET", "/models/generation-tiers"), ) + async def list_embedding_models( + self, *, supports_input_media: str | None = None + ) -> dict[str, Any]: + """List the embedding models a source can index with, and their pricing. + + Args: + supports_input_media: Keep only embedders that can index this input + modality. + + Returns: + The embedders under ``models`` by default, and under ``data`` with + ``pagination`` once the client opts in with + ``api_version="2026-07-27"`` or later; the defaults and pricing sit + beside them on either shape. Read the list with + :func:`unwrap_items`:: + + items = unwrap_items(await client.list_embedding_models(), "models") + """ + return cast( + dict[str, Any], + await self.request( + "GET", + "/models/embedders", + params=_strip_none({"supports_input_media": supports_input_media}), + ), + ) + + async def list_reranker_models(self) -> dict[str, Any]: + """List the reranker models a knowledge base can use, and their pricing. + + Returns: + The rerankers under ``models`` by default, and under ``data`` with + ``pagination`` once the client opts in with + ``api_version="2026-07-27"`` or later; the default and pricing sit + beside them on either shape. Read the list with + :func:`unwrap_items`:: + + items = unwrap_items(await client.list_reranker_models(), "models") + """ + return cast(dict[str, Any], await self.request("GET", "/models/rerankers")) + # ── Model Playground Experiments ────────────────────────────────────────── async def list_experiments( @@ -8127,7 +8579,12 @@ async def list_experiments( offset: Pagination offset. Returns: - Paginated list of experiments. + The experiments, under ``experiments`` alongside ``total`` by default, + and under ``data`` with ``pagination`` once the client opts in with + ``api_version="2026-07-27"`` or later. Read either with + :func:`unwrap_items`:: + + items = unwrap_items(await client.list_experiments(), "experiments") """ return await self.request( "GET", @@ -8191,6 +8648,115 @@ async def delete_experiment(self, experiment_id: str) -> None: """ await self.request("DELETE", f"/models/playground/experiments/{experiment_id}") + # ── Cloud Drives ────────────────────────────────────────────────────────── + + async def list_cloud_drive_providers(self) -> list[dict[str, Any]]: + """List the cloud-drive providers available to the account. + + Returns: + The providers, read from either response shape. + """ + return unwrap_items(await self.request("GET", "/cloud-drives/providers")) + + async def list_cloud_drives(self) -> list[dict[str, Any]]: + """List the account's cloud-drive connections. + + Returns: + The connections, read from either response shape. + """ + return unwrap_items(await self.request("GET", "/cloud-drives")) + + async def get_cloud_drive(self, connection_id: str) -> dict[str, Any]: + """Get a cloud-drive connection. + + Args: + connection_id: Cloud-drive connection identifier. + + Returns: + The connection. + """ + return cast( + dict[str, Any], + await self.request("GET", f"/cloud-drives/{connection_id}"), + ) + + async def update_cloud_drive( + self, connection_id: str, body: dict[str, Any] + ) -> dict[str, Any]: + """Update a cloud-drive connection. + + Args: + connection_id: Cloud-drive connection identifier. + body: Fields to change — ``name`` and/or ``folder_path``. + + Returns: + The updated connection. + """ + return cast( + dict[str, Any], + await self.request("PATCH", f"/cloud-drives/{connection_id}", json=body), + ) + + async def disconnect_cloud_drive(self, connection_id: str) -> dict[str, Any]: + """Disconnect a cloud-drive connection, keeping the connection itself. + + Args: + connection_id: Cloud-drive connection identifier. + + Returns: + The connection in its disconnected state. + """ + return cast( + dict[str, Any], + await self.request("POST", f"/cloud-drives/{connection_id}/disconnect"), + ) + + async def delete_cloud_drive(self, connection_id: str) -> None: + """Delete a cloud-drive connection. + + Args: + connection_id: Cloud-drive connection identifier. + """ + await self.request("DELETE", f"/cloud-drives/{connection_id}") + + async def get_agents_using_cloud_drive( + self, connection_id: str + ) -> list[dict[str, Any]]: + """List the agents that use a cloud-drive connection. + + Args: + connection_id: Cloud-drive connection identifier. + + Returns: + The agents, read from either response shape. + """ + return unwrap_items( + await self.request("GET", f"/cloud-drives/{connection_id}/agents") + ) + + async def list_cloud_drive_rejections( + self, connection_id: str, *, limit: int | None = None + ) -> list[dict[str, Any]]: + """List the files a cloud-drive connection skipped, newest first. + + A skipped file fires no trigger, so this is where to look when an agent + did not run for a file. + + Args: + connection_id: Cloud-drive connection identifier. + limit: Maximum number of rejections (1-200, default 50). + + Returns: + The rejections with their reasons, read from either response shape. + """ + return unwrap_items( + await self.request( + "GET", + f"/cloud-drives/{connection_id}/rejections", + params=_strip_none({"limit": limit}), + ) + ) + # ── Search ──────────────────────────────────────────────────────────────── async def search( @@ -8522,6 +9088,7 @@ async def paginate( params: dict[str, Any] | None = None, limit: int = 50, items_key: str = "data", + param_style: Literal["page", "offset"] = "page", ) -> AsyncGenerator[dict[str, Any]]: """Auto-paginate a list endpoint, yielding items lazily. @@ -8532,26 +9099,47 @@ async def paginate( Args: method: HTTP method (typically ``"GET"``). path: API path. - params: Extra query parameters (``page`` and ``limit`` are managed automatically). + params: Extra query parameters (the cursor and ``limit`` are managed + automatically). limit: Items per page. - items_key: JSON key containing the list of items (default ``"data"``). + items_key: Per-resource key the items sit under when the response + is not the ``data`` envelope, which is always read first. + param_style: ``"page"`` (default) sends a 1-indexed ``page``; + ``"offset"`` sends a 0-based ``offset``. A few endpoints — + ``/models/alerts`` among them — declare only ``offset`` and + reject or ignore ``page``, which makes every request after the + first return page 1. Yields: Individual items from each page. + + Raises: + ValueError: If ``param_style`` is neither ``"page"`` nor ``"offset"``. + SeclaiError: If a page is neither a list nor an object carrying + ``data`` or ``items_key``. """ + if param_style not in ("page", "offset"): + raise ValueError( + f"param_style must be 'page' or 'offset', not {param_style!r}" + ) page = 1 base_params = dict(params) if params else {} while True: - base_params["page"] = page + if param_style == "offset": + base_params["offset"] = (page - 1) * limit + else: + base_params["page"] = page base_params["limit"] = limit result = await self.request(method, path, params=base_params) - if not isinstance(result, dict): - break - items = result.get(items_key, []) - if not isinstance(items, list): + # A bare array is an unpaginated response: it is everything, so + # asking for a second page would return the same items again. + if isinstance(result, list): + for item in result: + yield cast(dict[str, Any], item) break + items = unwrap_items(result, items_key) for item in items: - yield cast(dict[str, Any], item) + yield item if len(items) < limit: break page += 1 @@ -8627,7 +9215,7 @@ async def run_streaming_agent( merged_headers = await _merge_request_headers_async( options=self._options, request_headers=headers ) - merged_headers.setdefault("accept", "text/event-stream") + _setdefault_header(merged_headers, "accept", "text/event-stream") timeout_seconds = self._options.timeout if timeout is None else timeout start = time.monotonic() @@ -8639,6 +9227,10 @@ async def run_streaming_agent( headers=merged_headers, timeout=timeout_seconds, ) as response: + if response.status_code >= 400: + # Lazy body inside `stream()`; read it so a 422's field-level + # detail survives into SeclaiAPIValidationError. + await response.aread() _raise_for_status(response) current_event: str | None = None data_lines: list[str] = [] diff --git a/seclai/versions.py b/seclai/versions.py index 6305958..7ebfb70 100644 --- a/seclai/versions.py +++ b/seclai/versions.py @@ -1,10 +1,12 @@ """Dated API versions known to this release. -The set is open: the API adds versions without an SDK release, and the -``api_version`` client option is typed ``str | None``, so a date newer than this -release knows about can be passed directly. Treat these as convenience constants -rather than an exhaustive list — :meth:`Seclai.get_api_version` reports what the -server actually supports. +The API adds versions without an SDK release, so the server's set is always a +superset of this one — :meth:`Seclai.get_api_version` reports what it actually +supports. This list is nonetheless the client's **allowlist**, not a set of +convenience constants: :func:`validate_api_version` fails closed on anything +absent from it, because a newer version can reshape responses that this release +would then mis-decode rather than reject. To move ahead of the SDK, pass +``allow_unknown_api_version=True`` to the client. """ from __future__ import annotations @@ -18,13 +20,18 @@ class ApiVersion(StrEnum): V2026_07_01 = "2026-07-01" V2026_07_27 = "2026-07-27" + V2026_08_03 = "2026-08-03" + V2026_08_21 = "2026-08-21" + V2026_09_28 = "2026-09-28" + V2026_09_30 = "2026-09-30" + V2026_10_03 = "2026-10-03" #: Baseline applied to an unpinned, header-less caller. DEFAULT_API_VERSION = ApiVersion.V2026_07_01 #: Newest version known to this SDK release. May lag the server. -LATEST_API_VERSION = ApiVersion.V2026_07_27 +LATEST_API_VERSION = ApiVersion.V2026_10_03 def validate_api_version(version: str | None, *, allow_unknown: bool) -> str | None: diff --git a/tests/test_error_and_guard_paths.py b/tests/test_error_and_guard_paths.py new file mode 100644 index 0000000..1aa5cba --- /dev/null +++ b/tests/test_error_and_guard_paths.py @@ -0,0 +1,218 @@ +"""Error mapping on the generated-client path, and the guards on ``paginate()`` +and on a per-request ``Seclai-Version``.""" + +from __future__ import annotations + +from typing import Any + +import httpx +import pytest + +import seclai +from seclai import AgentRunStreamRequest, AsyncSeclai, Seclai + +_BASE_URL = "https://example.invalid" + +_FIELD_DETAIL = {"detail": [{"loc": ["query", "page"], "msg": "bad", "type": "x"}]} + + +def _typed_client(handler: Any) -> Seclai: + """A client whose typed (generated-client) methods answer from ``handler``.""" + client = Seclai(api_key="k") + client._generated_client().set_httpx_client( + httpx.Client(transport=httpx.MockTransport(handler), base_url=_BASE_URL) + ) + return client + + +def _request_client(handler: Any, **options: Any) -> Seclai: + return Seclai( + api_key="k", + http_client=httpx.Client( + transport=httpx.MockTransport(handler), base_url=_BASE_URL + ), + **options, + ) + + +class TestTypedMethodErrorBodies: + @pytest.mark.parametrize( + "response", + [ + httpx.Response(503, text="Service Unavailable"), + httpx.Response(503, json={"message": "upstream down"}), + httpx.Response( + 503, + json={"error": {"code": "database_unavailable", "message": "retry"}}, + ), + ], + ids=["html", "foreign-json", "documented-body"], + ) + def test_a_503_is_a_status_error_whatever_its_body( + self, response: httpx.Response + ) -> None: + client = _typed_client(lambda req: response) + with pytest.raises(seclai.SeclaiAPIStatusError) as exc: + client.list_sources() + assert exc.value.status_code == 503 + assert exc.value.response_text + + def test_a_422_with_a_string_detail_is_a_status_error(self) -> None: + client = _typed_client(lambda req: httpx.Response(422, json={"detail": "no"})) + with pytest.raises(seclai.SeclaiAPIStatusError) as exc: + client.list_sources() + assert exc.value.status_code == 422 + assert not isinstance(exc.value, seclai.SeclaiAPIValidationError) + + def test_a_422_with_field_detail_is_a_validation_error(self) -> None: + client = _typed_client(lambda req: httpx.Response(422, json=_FIELD_DETAIL)) + with pytest.raises(seclai.SeclaiAPIValidationError) as exc: + client.list_sources() + assert exc.value.validation_error is not None + + def test_an_upload_422_with_a_string_detail_is_a_status_error(self) -> None: + client = _typed_client(lambda req: httpx.Response(422, json={"detail": "no"})) + with pytest.raises(seclai.SeclaiAPIStatusError) as exc: + client.upload_file_to_source("s1", file=b"x", file_name="a.txt") + assert exc.value.status_code == 422 + + def test_a_success_still_decodes(self) -> None: + body = { + "data": [], + "pagination": { + "page": 1, + "limit": 20, + "total": 0, + "pages": 0, + "has_next": False, + "has_prev": False, + }, + } + client = _typed_client(lambda req: httpx.Response(200, json=body)) + assert client.list_sources().data == [] + + @pytest.mark.asyncio + async def test_async_503_html_is_a_status_error(self) -> None: + client = AsyncSeclai(api_key="k") + client._generated_client().set_async_httpx_client( + httpx.AsyncClient( + transport=httpx.MockTransport( + lambda req: httpx.Response(503, text="down") + ), + base_url=_BASE_URL, + ) + ) + with pytest.raises(seclai.SeclaiAPIStatusError) as exc: + await client.list_sources() + assert exc.value.status_code == 503 + + +class TestPaginateGuards: + def test_the_legacy_key_also_reads_the_canonical_envelope(self) -> None: + client = _request_client( + lambda req: httpx.Response(200, json={"data": [{"id": "c1"}]}) + ) + items = list(client.paginate("GET", "/alerts/configs", items_key="configs")) + assert items == [{"id": "c1"}] + + def test_the_legacy_key_is_still_read(self) -> None: + client = _request_client( + lambda req: httpx.Response(200, json={"configs": [{"id": "c1"}]}) + ) + items = list(client.paginate("GET", "/alerts/configs", items_key="configs")) + assert items == [{"id": "c1"}] + + def test_an_unreadable_shape_raises_instead_of_yielding_nothing(self) -> None: + client = _request_client( + lambda req: httpx.Response(200, json={"rows": [{"id": "c1"}]}) + ) + with pytest.raises(seclai.SeclaiError): + list(client.paginate("GET", "/alerts/configs", items_key="configs")) + + def test_an_unknown_param_style_is_refused(self) -> None: + requests: list[httpx.Request] = [] + + def handler(req: httpx.Request) -> httpx.Response: + requests.append(req) + return httpx.Response(200, json={"data": []}) + + client = _request_client(handler) + with pytest.raises(ValueError, match="param_style"): + list( + client.paginate( + "GET", + "/models/alerts", + param_style="Offset", # type: ignore[arg-type] + ) + ) + assert requests == [] + + +class TestPerRequestVersionHeader: + def test_an_unknown_version_is_refused(self) -> None: + requests: list[httpx.Request] = [] + + def handler(req: httpx.Request) -> httpx.Response: + requests.append(req) + return httpx.Response(200, json={"data": []}) + + client = _request_client(handler) + with pytest.raises(seclai.SeclaiConfigurationError, match="2099-01-01"): + client.request("GET", "/agents", headers={"seclai-version": "2099-01-01"}) + assert requests == [] + + def test_an_unknown_version_is_refused_on_a_streaming_method(self) -> None: + client = _request_client(lambda req: httpx.Response(200, text="")) + with pytest.raises(seclai.SeclaiConfigurationError, match="2099-01-01"): + client.run_streaming_agent_and_wait( + "a1", + AgentRunStreamRequest(input="hi", metadata={}), + headers={"Seclai-Version": "2099-01-01"}, + ) + + def test_the_escape_hatch_allows_it(self) -> None: + seen: dict[str, Any] = {} + + def handler(req: httpx.Request) -> httpx.Response: + seen["version"] = req.headers.get("seclai-version") + return httpx.Response(200, json={"data": []}) + + client = _request_client(handler, allow_unknown_api_version=True) + client.request("GET", "/agents", headers={"Seclai-Version": "2099-01-01"}) + assert seen["version"] == "2099-01-01" + + def test_a_known_version_still_overrides(self) -> None: + seen: dict[str, Any] = {} + + def handler(req: httpx.Request) -> httpx.Response: + seen["version"] = req.headers.get("seclai-version") + return httpx.Response(200, json={"data": []}) + + client = _request_client(handler, api_version="2026-07-01") + client.request("GET", "/agents", headers={"Seclai-Version": "2026-10-03"}) + assert seen["version"] == "2026-10-03" + + def test_the_spelling_that_reaches_the_wire_is_the_one_checked(self) -> None: + seen: dict[str, Any] = {} + + def handler(req: httpx.Request) -> httpx.Response: + seen["versions"] = req.headers.get_list("seclai-version") + return httpx.Response(200, json={"data": []}) + + client = _request_client(handler) + client.request( + "GET", + "/agents", + headers={"seclai-version": "2099-01-01", "Seclai-Version": "2026-10-03"}, + ) + assert seen["versions"] == ["2026-10-03"] + + with pytest.raises(seclai.SeclaiConfigurationError, match="2099-01-01"): + client.request( + "GET", + "/agents", + headers={ + "Seclai-Version": "2026-10-03", + "seclai-version": "2099-01-01", + }, + ) diff --git a/tests/test_new_methods.py b/tests/test_new_methods.py index 19644e9..53e0461 100644 --- a/tests/test_new_methods.py +++ b/tests/test_new_methods.py @@ -14,7 +14,7 @@ import pytest import seclai -from seclai import AsyncSeclai, Seclai +from seclai import AgentRunStreamRequest, AsyncSeclai, Seclai from seclai import versions as seclai_versions # --------------------------------------------------------------------------- @@ -3101,13 +3101,20 @@ def test_get_generation_tiers(self) -> None: def handler(req: httpx.Request) -> httpx.Response: seen["method"] = req.method seen["path"] = req.url.path - return _json_response({"image": {"fast": {"model": "m1"}}}, status=200) + # The legacy shape the endpoint actually serves. The previous + # fixture used a nested modality->tier mapping the API never sends, + # which the documented `unwrap_items(..., "tiers")` cannot read. + return _json_response( + {"tiers": [{"modality": "image", "tier": "fast"}]}, status=200 + ) client = _sync_client(handler) result = client.get_generation_tiers() assert seen["method"] == "GET" assert seen["path"] == "/models/generation-tiers" - assert result == {"image": {"fast": {"model": "m1"}}} + assert seclai.unwrap_items(result, "tiers") == [ + {"modality": "image", "tier": "fast"} + ] def test_search_docs(self) -> None: seen: dict[str, Any] = {} @@ -3455,6 +3462,296 @@ def handler(req: httpx.Request) -> httpx.Response: assert seen["body"] == {"version": "2099-01-01"} +_ENVELOPE_PAGINATION = { + "page": 1, + "limit": 1, + "total": 1, + "pages": 1, + "has_next": False, + "has_prev": False, +} + +# (method, args, kwargs, verb, path, query, body) for every 2026-10 endpoint. +# One table drives the sync and async tests, so the two classes cannot be +# asserted against different expectations. +_SYNC_2026_10_CALLS: list[ + tuple[str, tuple[Any, ...], dict[str, Any], str, str, list[tuple[str, str]], Any] +] = [ + ("list_cloud_drive_providers", (), {}, "GET", "/cloud-drives/providers", [], None), + ("list_cloud_drives", (), {}, "GET", "/cloud-drives", [], None), + ("get_cloud_drive", ("c1",), {}, "GET", "/cloud-drives/c1", [], None), + ( + "update_cloud_drive", + ("c1", {"name": "Contracts"}), + {}, + "PATCH", + "/cloud-drives/c1", + [], + {"name": "Contracts"}, + ), + ( + "disconnect_cloud_drive", + ("c1",), + {}, + "POST", + "/cloud-drives/c1/disconnect", + [], + None, + ), + ("delete_cloud_drive", ("c1",), {}, "DELETE", "/cloud-drives/c1", [], None), + ( + "get_agents_using_cloud_drive", + ("c1",), + {}, + "GET", + "/cloud-drives/c1/agents", + [], + None, + ), + ( + "list_cloud_drive_rejections", + ("c1",), + {"limit": 20}, + "GET", + "/cloud-drives/c1/rejections", + [("limit", "20")], + None, + ), + ( + "list_cloud_drive_rejections", + ("c1",), + {}, + "GET", + "/cloud-drives/c1/rejections", + [], + None, + ), + ( + "list_embedding_models", + (), + {"supports_input_media": "image"}, + "GET", + "/models/embedders", + [("supports_input_media", "image")], + None, + ), + ("list_reranker_models", (), {}, "GET", "/models/rerankers", [], None), + ( + "list_source_contents", + ("s1",), + { + "page": 2, + "limit": 10, + "sort": "title", + "order": "asc", + "status": "failed", + "content_version_ids": ["cv1", "cv2"], + }, + "GET", + "/sources/s1/contents", + [ + ("page", "2"), + ("limit", "10"), + ("sort", "title"), + ("order", "asc"), + ("status", "failed"), + ("content_version_id", "cv1"), + ("content_version_id", "cv2"), + ], + None, + ), + ("list_source_contents", ("s1",), {}, "GET", "/sources/s1/contents", [], None), + ( + "get_source_content_status", + ("s1", "cv1"), + {}, + "GET", + "/sources/s1/contents/cv1", + [], + None, + ), +] + +# Methods that return the items of a version-gated list, and so must read both +# the legacy bare array and the canonical envelope. +_LIST_2026_10_METHODS = [ + ("list_cloud_drive_providers", ()), + ("list_cloud_drives", ()), + ("get_agents_using_cloud_drive", ("c1",)), + ("list_cloud_drive_rejections", ("c1",)), +] + + +def _recording_handler(seen: dict[str, Any], body: Any) -> Any: + def handler(req: httpx.Request) -> httpx.Response: + seen["method"] = req.method + seen["path"] = req.url.path + seen["query"] = list(req.url.params.multi_items()) + seen["body"] = json.loads(req.content) if req.content else None + return _json_response(body) + + return handler + + +class TestCloudDrivesModelsAndSourceContents: + @pytest.mark.parametrize( + ("name", "args", "kwargs", "verb", "path", "query", "body"), + _SYNC_2026_10_CALLS, + ) + def test_request( + self, + name: str, + args: tuple[Any, ...], + kwargs: dict[str, Any], + verb: str, + path: str, + query: list[tuple[str, str]], + body: Any, + ) -> None: + seen: dict[str, Any] = {} + client = _sync_client(_recording_handler(seen, {"data": []})) + getattr(client, name)(*args, **kwargs) + assert seen == {"method": verb, "path": path, "query": query, "body": body} + + @pytest.mark.asyncio + @pytest.mark.parametrize( + ("name", "args", "kwargs", "verb", "path", "query", "body"), + _SYNC_2026_10_CALLS, + ) + async def test_request_async( + self, + name: str, + args: tuple[Any, ...], + kwargs: dict[str, Any], + verb: str, + path: str, + query: list[tuple[str, str]], + body: Any, + ) -> None: + seen: dict[str, Any] = {} + client = _async_client(_recording_handler(seen, {"data": []})) + await getattr(client, name)(*args, **kwargs) + assert seen == {"method": verb, "path": path, "query": query, "body": body} + + @pytest.mark.parametrize(("name", "args"), _LIST_2026_10_METHODS) + @pytest.mark.parametrize( + "payload", + [[{"id": "x1"}], {"data": [{"id": "x1"}], "pagination": _ENVELOPE_PAGINATION}], + ids=["legacy-array", "envelope"], + ) + def test_list_reads_both_shapes( + self, name: str, args: tuple[Any, ...], payload: Any + ) -> None: + client = _sync_client(lambda req: _json_response(payload)) + assert getattr(client, name)(*args) == [{"id": "x1"}] + + @pytest.mark.asyncio + @pytest.mark.parametrize(("name", "args"), _LIST_2026_10_METHODS) + @pytest.mark.parametrize( + "payload", + [[{"id": "x1"}], {"data": [{"id": "x1"}], "pagination": _ENVELOPE_PAGINATION}], + ids=["legacy-array", "envelope"], + ) + async def test_list_reads_both_shapes_async( + self, name: str, args: tuple[Any, ...], payload: Any + ) -> None: + client = _async_client(lambda req: _json_response(payload)) + assert await getattr(client, name)(*args) == [{"id": "x1"}] + + @pytest.mark.parametrize("name", ["list_embedding_models", "list_reranker_models"]) + @pytest.mark.parametrize( + "payload", + [ + {"models": [{"model_type": "m1"}], "default_model_type": "m1"}, + { + "data": [{"model_type": "m1"}], + "pagination": _ENVELOPE_PAGINATION, + "default_model_type": "m1", + }, + ], + ids=["legacy-key", "envelope"], + ) + def test_model_listing_keeps_pricing_beside_the_items( + self, name: str, payload: Any + ) -> None: + client = _sync_client(lambda req: _json_response(payload)) + result = getattr(client, name)() + assert seclai.unwrap_items(result, "models") == [{"model_type": "m1"}] + assert result["default_model_type"] == "m1" + + def test_an_empty_content_version_filter_matches_nothing(self) -> None: + # An empty list encodes as no parameter at all, which the API reads as + # "no filter" and answers with every item in the source. + requests: list[httpx.Request] = [] + + def handler(req: httpx.Request) -> httpx.Response: + requests.append(req) + return _json_response({"data": [{"id": "x1"}]}) + + client = _sync_client(handler) + result = client.list_source_contents( + "s1", page=3, limit=50, content_version_ids=[] + ) + assert requests == [] + assert result == { + "data": [], + "pagination": {**_ENVELOPE_PAGINATION, "page": 3, "limit": 50} + | {"total": 0, "pages": 0}, + } + + @pytest.mark.asyncio + async def test_an_empty_content_version_filter_matches_nothing_async( + self, + ) -> None: + requests: list[httpx.Request] = [] + + def handler(req: httpx.Request) -> httpx.Response: + requests.append(req) + return _json_response({"data": [{"id": "x1"}]}) + + client = _async_client(handler) + result = await client.list_source_contents("s1", content_version_ids=[]) + assert requests == [] + assert result["data"] == [] + assert result["pagination"]["page"] == 1 + assert result["pagination"]["limit"] == 20 + assert result["pagination"]["total"] == 0 + + +def _unread_validation_error(req: httpx.Request) -> httpx.Response: + """A 422 whose body is still a stream, as it is on a real connection.""" + + def body() -> Any: + yield json.dumps( + {"detail": [{"loc": ["body", "input"], "msg": "required", "type": "x"}]} + ).encode() + + return httpx.Response( + 422, headers={"content-type": "application/json"}, content=body() + ) + + +class TestStreamingErrorBodies: + def test_a_422_from_run_and_wait_keeps_its_field_detail(self) -> None: + client = _sync_client(_unread_validation_error) + with pytest.raises(seclai.SeclaiAPIValidationError) as exc: + client.run_streaming_agent_and_wait( + "a1", AgentRunStreamRequest(input="hi", metadata={}) + ) + assert exc.value.response_text + assert exc.value.validation_error is not None + + def test_a_422_from_the_event_stream_keeps_its_field_detail(self) -> None: + client = _sync_client(_unread_validation_error) + events = client.run_streaming_agent( + "a1", AgentRunStreamRequest(input="hi", metadata={}) + ) + with pytest.raises(seclai.SeclaiAPIValidationError) as exc: + next(events) + assert exc.value.response_text + assert exc.value.validation_error is not None + + class TestAsyncParityForNewBehaviour: """AsyncSeclai hand-duplicates every method, so nothing in the sync tests proves the async copy behaves the same. Each case here mirrors a sync test @@ -3617,11 +3914,50 @@ def handler(req: httpx.Request) -> httpx.Response: assert seen["values"] == ["2099-01-01"] def test_a_known_version_in_default_headers_needs_no_escape_hatch(self) -> None: + # Asserting only that construction succeeded would pass even if the + # header were dropped on the way to the wire, so check the wire. + seen: dict[str, Any] = {} + + def handler(req: httpx.Request) -> httpx.Response: + seen["values"] = req.headers.get_list("seclai-version") + return _json_response({"data": []}) + client = _sync_client( - lambda req: _json_response({"data": []}), + handler, default_headers={"Seclai-Version": seclai_versions.LATEST_API_VERSION}, ) - assert client is not None + client.list_agents() + assert seen["values"] == [seclai_versions.LATEST_API_VERSION] + + def test_an_empty_version_header_is_rejected(self) -> None: + # An empty `Seclai-Version` still reaches the wire and still suppresses + # the `api_version` opt-in, so reading it as "no header supplied" let a + # client silently send a version it never validated. + with pytest.raises(seclai.SeclaiConfigurationError) as exc: + Seclai( + api_key="k", + api_version=seclai_versions.LATEST_API_VERSION, + default_headers={"Seclai-Version": ""}, + ) + assert "default_headers" in str(exc.value) + + def test_default_headers_are_snapshotted(self) -> None: + # `_build_default_headers` re-reads this mapping on every request, so + # holding the caller's dict let a later mutation put an unvalidated + # version on the wire. + seen: dict[str, Any] = {} + + def handler(req: httpx.Request) -> httpx.Response: + seen["values"] = req.headers.get_list("seclai-version") + return _json_response({"data": []}) + + headers: dict[str, str] = { + "Seclai-Version": seclai_versions.DEFAULT_API_VERSION + } + client = _sync_client(handler, default_headers=headers) + headers["Seclai-Version"] = "2099-01-01" + client.list_agents() + assert seen["values"] == [seclai_versions.DEFAULT_API_VERSION] class TestDuplicateVersionHeaderSpellings: @@ -3655,3 +3991,201 @@ def handler(req: httpx.Request) -> httpx.Response: ) client.list_agents() assert seen["values"] == [seclai_versions.LATEST_API_VERSION] + + +class TestValidationErrorsFromTheRequestPath: + """A 422 through `request()` must always surface as a SeclaiError. + + `HTTPValidationError.from_dict` assumes `detail` is a list of + `{loc, msg, type}` objects. A hand-raised `HTTPException(422, detail="...")` + is not, and parsing it unguarded turned an API failure into a ValueError / + TypeError / KeyError that no `except SeclaiError` handler catches. + """ + + def test_a_well_formed_detail_becomes_a_validation_error(self) -> None: + body = { + "detail": [{"loc": ["query", "q"], "msg": "field required", "type": "x"}] + } + client = _sync_client(lambda req: _json_response(body, status=422)) + with pytest.raises(seclai.SeclaiAPIValidationError) as exc: + client.get_me() + assert exc.value.status_code == 422 + assert exc.value.validation_error is not None + + @pytest.mark.parametrize( + "body", + [ + {"detail": "insufficient credits"}, + {"detail": None}, + {"detail": [{"msg": "bad", "type": "x"}]}, + {"detail": {"msg": "bad"}}, + {"errors": []}, + ], + ) + def test_an_unparseable_detail_still_raises_a_status_error(self, body: Any) -> None: + client = _sync_client(lambda req: _json_response(body, status=422)) + with pytest.raises(seclai.SeclaiAPIStatusError) as exc: + client.get_me() + assert exc.value.status_code == 422 + + def test_a_non_json_422_still_raises_a_status_error(self) -> None: + client = _sync_client( + lambda req: httpx.Response(status_code=422, text="gateway") + ) + with pytest.raises(seclai.SeclaiAPIStatusError): + client.get_me() + + @pytest.mark.asyncio + async def test_async_parity(self) -> None: + client = _async_client( + lambda req: _json_response({"detail": "nope"}, status=422) + ) + with pytest.raises(seclai.SeclaiAPIStatusError): + await client.get_me() + + +class TestPerRequestHeaderMerge: + """Per-request `headers=` must replace a default case-insensitively. + + Header names are case-insensitive on the wire but dict keys are not, so a + plain `dict.update` left two spellings in the mapping and httpx put both on + the wire for the server to choose between. + """ + + def test_a_per_request_version_replaces_the_client_default(self) -> None: + seen: dict[str, Any] = {} + + def handler(req: httpx.Request) -> httpx.Response: + seen["values"] = req.headers.get_list("seclai-version") + return _json_response({"data": []}) + + client = _sync_client(handler, api_version="2026-07-01") + client.request("GET", "/agents", headers={"Seclai-Version": "2026-07-27"}) + assert seen["values"] == ["2026-07-27"] + + def test_a_per_request_api_key_replaces_the_client_default(self) -> None: + seen: dict[str, Any] = {} + + def handler(req: httpx.Request) -> httpx.Response: + seen["values"] = req.headers.get_list("x-api-key") + return _json_response({"data": []}) + + client = _sync_client(handler) + client.request("GET", "/agents", headers={"X-Api-Key": "override"}) + assert seen["values"] == ["override"] + + @pytest.mark.asyncio + async def test_async_parity(self) -> None: + seen: dict[str, Any] = {} + + def handler(req: httpx.Request) -> httpx.Response: + seen["values"] = req.headers.get_list("seclai-version") + return _json_response({"data": []}) + + client = _async_client(handler, api_version="2026-07-01") + await client.request("GET", "/agents", headers={"Seclai-Version": "2026-07-27"}) + assert seen["values"] == ["2026-07-27"] + + def test_a_caller_supplied_accept_replaces_the_streaming_default(self) -> None: + seen: dict[str, Any] = {} + + done = json.dumps( + { + "attempts": [], + "credits": None, + "error_count": 0, + "input": None, + "output": "ok", + "priority": False, + "run_id": "r1", + "status": "completed", + } + ) + + def handler(req: httpx.Request) -> httpx.Response: + seen["values"] = req.headers.get_list("accept") + return httpx.Response( + status_code=200, + headers={"content-type": "text/event-stream"}, + content=f"event: done\ndata: {done}\n\n".encode(), + ) + + client = _sync_client(handler) + client.run_streaming_agent_and_wait( + "a1", + AgentRunStreamRequest(input="x", metadata={}), + headers={"Accept": "text/event-stream"}, + ) + assert seen["values"] == ["text/event-stream"] + + +class TestUnwrapItems: + """`unwrap_items` is the documented entry point for the version-gated + endpoints that keep a per-resource key, but nothing exercised that path.""" + + def test_reads_a_bare_array(self) -> None: + assert seclai.unwrap_items([{"id": "a"}], "configs") == [{"id": "a"}] + + def test_prefers_data_over_the_legacy_key(self) -> None: + payload = {"data": [{"id": "new"}], "configs": [{"id": "old"}]} + assert seclai.unwrap_items(payload, "configs") == [{"id": "new"}] + + def test_reads_the_legacy_key(self) -> None: + payload = {"configs": [{"id": "a"}], "total": 1} + assert seclai.unwrap_items(payload, "configs") == [{"id": "a"}] + + def test_an_explicit_null_is_an_empty_page(self) -> None: + assert seclai.unwrap_items({"data": None}, "configs") == [] + + def test_an_unrecognised_envelope_raises(self) -> None: + with pytest.raises(seclai.SeclaiError): + seclai.unwrap_items({"widgets": []}, "configs") + + def test_a_non_list_under_a_known_key_raises(self) -> None: + with pytest.raises(seclai.SeclaiError): + seclai.unwrap_items({"data": {"id": "a"}}, "configs") + + +class TestPaginateShapes: + """`paginate()` predates the version-gated shapes and the offset-only + endpoints, so it sent `page` everywhere and could not read a bare array.""" + + def test_a_bare_array_yields_its_items_and_stops(self) -> None: + calls: list[int] = [] + + def handler(req: httpx.Request) -> httpx.Response: + calls.append(1) + return _json_response([{"id": "ec1"}, {"id": "ec2"}]) + + client = _sync_client(handler) + items = list(client.paginate("GET", "/agents/a1/evaluation-criteria")) + assert items == [{"id": "ec1"}, {"id": "ec2"}] + assert len(calls) == 1 + + def test_offset_style_sends_offset_not_page(self) -> None: + seen: list[dict[str, str]] = [] + + def handler(req: httpx.Request) -> httpx.Response: + seen.append(dict(req.url.params)) + return _json_response({"alerts": []}) + + client = _sync_client(handler) + list( + client.paginate( + "GET", + "/models/alerts", + items_key="alerts", + limit=25, + param_style="offset", + ) + ) + assert seen == [{"offset": "0", "limit": "25"}] + + @pytest.mark.asyncio + async def test_async_parity(self) -> None: + client = _async_client(lambda req: _json_response([{"id": "ec1"}])) + items = [ + item + async for item in client.paginate("GET", "/agents/a1/evaluation-criteria") + ] + assert items == [{"id": "ec1"}]