From 74ef1a263018bd1dfd4b52067d32bde2b626d91a Mon Sep 17 00:00:00 2001 From: nathan-roe-24 <241831745+nathan-roe-24@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:50:35 +0000 Subject: [PATCH 1/5] Release v1.1.2 --- .roe-main-release-version | 2 +- SDK_EXAMPLES.md | 189 ++- openapi/openapi.yml | 1273 ++++++++++++++--- openapi/wrappers.yml | 90 ++ pyproject.toml | 2 +- .../agents_jobs_artifacts_result_retrieve.py | 244 ++++ .../agents/agents_jobs_cancel_all_create.py | 55 +- .../agents/agents_jobs_references_retrieve.py | 18 - .../api/agents/agents_jobs_result_retrieve.py | 16 +- .../_generated/api/knowledge_base/__init__.py | 1 + .../knowledge_base_catalog_retrieve.py | 128 ++ .../knowledge_base/knowledge_base_create.py | 204 +++ .../knowledge_base/knowledge_base_destroy.py | 135 ++ .../knowledge_base_draft_retrieve.py | 201 +++ .../knowledge_base_finalize_create.py | 223 +++ .../knowledge_base_import_lens_create.py | 241 ++++ .../knowledge_base_lens_retrieve.py | 149 ++ .../api/knowledge_base/knowledge_base_list.py | 214 +++ .../knowledge_base_regenerate_create.py | 223 +++ .../knowledge_base_resolve_create.py | 267 ++++ .../knowledge_base/knowledge_base_retrieve.py | 197 +++ ...knowledge_base_selection_partial_update.py | 231 +++ .../knowledge_base_sync_create.py | 205 +++ .../knowledge_base_unlink_destroy.py | 151 ++ src/roe/_generated/models/__init__.py | 38 + .../models/agent_job_artifact_result.py | 84 ++ .../models/agent_job_cancel_all_response.py | 100 ++ src/roe/_generated/models/base_agent.py | 4 +- .../_generated/models/connector_type_enum.py | 2 + .../models/create_connection_request.py | 2 + .../models/create_knowledge_base.py | 113 ++ .../models/create_knowledge_base_request.py | 113 ++ src/roe/_generated/models/draft.py | 270 ++++ src/roe/_generated/models/draft_ref.py | 186 +++ .../_generated/models/draft_status_enum.py | 9 + src/roe/_generated/models/finalize_request.py | 97 ++ src/roe/_generated/models/knowledge_base.py | 242 ++++ .../knowledge_base_import_lens_create_body.py | 65 + .../models/knowledge_base_status_enum.py | 9 + .../models/paginated_knowledge_base_list.py | 145 ++ .../models/patched_patch_selection_request.py | 110 ++ ...tched_patch_selection_request_refs_item.py | 65 + src/roe/_generated/models/pending_proposal.py | 177 +++ .../_generated/models/regenerate_request.py | 79 + src/roe/_generated/models/relevance_enum.py | 9 + src/roe/_generated/models/resolve_request.py | 132 ++ .../models/resolve_request_refs_item.py | 65 + .../test_connection_credentials_request.py | 2 + uv.lock | 4 +- 49 files changed, 6522 insertions(+), 259 deletions(-) create mode 100644 src/roe/_generated/api/agents/agents_jobs_artifacts_result_retrieve.py create mode 100644 src/roe/_generated/api/knowledge_base/__init__.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_catalog_retrieve.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_create.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_destroy.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_draft_retrieve.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_finalize_create.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_import_lens_create.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_lens_retrieve.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_list.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_regenerate_create.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_resolve_create.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_retrieve.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_selection_partial_update.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_sync_create.py create mode 100644 src/roe/_generated/api/knowledge_base/knowledge_base_unlink_destroy.py create mode 100644 src/roe/_generated/models/agent_job_artifact_result.py create mode 100644 src/roe/_generated/models/agent_job_cancel_all_response.py create mode 100644 src/roe/_generated/models/create_knowledge_base.py create mode 100644 src/roe/_generated/models/create_knowledge_base_request.py create mode 100644 src/roe/_generated/models/draft.py create mode 100644 src/roe/_generated/models/draft_ref.py create mode 100644 src/roe/_generated/models/draft_status_enum.py create mode 100644 src/roe/_generated/models/finalize_request.py create mode 100644 src/roe/_generated/models/knowledge_base.py create mode 100644 src/roe/_generated/models/knowledge_base_import_lens_create_body.py create mode 100644 src/roe/_generated/models/knowledge_base_status_enum.py create mode 100644 src/roe/_generated/models/paginated_knowledge_base_list.py create mode 100644 src/roe/_generated/models/patched_patch_selection_request.py create mode 100644 src/roe/_generated/models/patched_patch_selection_request_refs_item.py create mode 100644 src/roe/_generated/models/pending_proposal.py create mode 100644 src/roe/_generated/models/regenerate_request.py create mode 100644 src/roe/_generated/models/relevance_enum.py create mode 100644 src/roe/_generated/models/resolve_request.py create mode 100644 src/roe/_generated/models/resolve_request_refs_item.py diff --git a/.roe-main-release-version b/.roe-main-release-version index f749893..1f56bba 100644 --- a/.roe-main-release-version +++ b/.roe-main-release-version @@ -1 +1 @@ -1-1-1 +1-0-86 diff --git a/SDK_EXAMPLES.md b/SDK_EXAMPLES.md index 481c96c..83961bf 100644 --- a/SDK_EXAMPLES.md +++ b/SDK_EXAMPLES.md @@ -70,6 +70,21 @@ result = client.agents.jobs.retrieve_status_many( ) ``` +#### `agents_jobs_artifacts_result_retrieve` + +Get tool result artifact (result only) + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.agents.jobs.retrieve_artifact( + job_id="job_id", # required + artifact_key="artifact_key", # required +) +``` + #### `agents_jobs_references_retrieve` Serve a reference file associated with an agent job. @@ -305,7 +320,7 @@ result = client.agents.duplicate( #### `agents_jobs_cancel_all_create` -Cancel all agent jobs +Cancel all running agent jobs (:cancelAll) ```python from roe import RoeClient @@ -615,6 +630,178 @@ client = RoeClient() result = client.discovery.list_agent_engine_types() ``` +### Knowledge Base + +#### `knowledge_base_list` + +List all KBs for the org, or start a new draft. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.list() +``` + +#### `knowledge_base_create` + +List all KBs for the org, or start a new draft. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.create() +``` + +#### `knowledge_base_catalog_retrieve` + +Names-only typology+tactic catalog. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.catalog() +``` + +#### `knowledge_base_import_lens_create` + +Import a finalized Atlas lens into roe-main by its atlas_lens_id. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.import_lens() +``` + +#### `knowledge_base_lens_retrieve` + +Fetch a lens directly from Atlas by its atlas_lens_id and return the +names-only projection. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.lens_by_atlas_id() +``` + +#### `knowledge_base_destroy` + +Get or delete a single KB. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.delete() +``` + +#### `knowledge_base_retrieve` + +Get or delete a single KB. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.retrieve() +``` + +#### `knowledge_base_draft_retrieve` + +Poll the atlas draft. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.poll_draft() +``` + +#### `knowledge_base_finalize_create` + +Commit the agreed selection into a lens and mark the KB active. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.finalize() +``` + +#### `knowledge_base_regenerate_create` + +Kick off another async generation round with feedback. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.regenerate() +``` + +#### `knowledge_base_resolve_create` + +Approve or decline a pending regeneration proposal. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.resolve() +``` + +#### `knowledge_base_selection_partial_update` + +Persist hand-edits to the working selection (typology + tactic opt-in/out). + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.patch_selection() +``` + +#### `knowledge_base_sync_create` + +Standalone best-effort lens sync (display mode). + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.sync() +``` + +#### `knowledge_base_unlink_destroy` + +Unlink a knowledge base: remove the local KnowledgeBase row only, leaving +the Atlas lens (and any in-progress draft) untouched. + +```python +from roe import RoeClient + +client = RoeClient() + +result = client.knowledge_base.unlink() +``` + ### Policies #### `policies_list` diff --git a/openapi/openapi.yml b/openapi/openapi.yml index e5c4f66..8c1431d 100644 --- a/openapi/openapi.yml +++ b/openapi/openapi.yml @@ -449,8 +449,8 @@ paths: /v1/agents/{agent_id}/jobs/cancel-all/: post: operationId: agents_jobs_cancel_all_create - description: Cancel all running jobs for a given agent. - summary: Cancel all agent jobs + description: Cancel all running jobs for an agent. + summary: Cancel all running agent jobs (:cancelAll) parameters: - in: path name: agent_id @@ -471,22 +471,13 @@ paths: - sdk security: - apiKeyAuth: [] - deprecated: true responses: - '204': - description: All running agent jobs cancelled successfully - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDetailResponse' - description: Access forbidden - '404': + '200': content: application/json: schema: - $ref: '#/components/schemas/ErrorDetailResponse' - description: Agent not found + $ref: '#/components/schemas/AgentJobCancelAllResponse' + description: '' /v1/agents/{agent_id}/versions/: get: operationId: agents_versions_list @@ -955,6 +946,55 @@ paths: schema: $ref: '#/components/schemas/ErrorDetailResponse' description: Agent not found. + /v1/agents/jobs/{agent_job_id}/artifacts/result/: + get: + operationId: agents_jobs_artifacts_result_retrieve + description: Fetches a tool result artifact for an agent job, returning only + the `result` field. Internal fields (`metadata`, `input`, and cost/token `usage` + data) are stripped. The artifact_key is available in the agent job result + output (e.g. `evidence_data` values). + summary: Get tool result artifact (result only) + parameters: + - in: path + name: agent_job_id + schema: + type: string + description: The agent job ID + required: true + - in: query + name: artifact_key + schema: + type: string + description: The artifact key (e.g., 'agent-job-xxx/extraction_123.json') + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - agents + - sdk + security: + - apiKeyAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/AgentJobArtifactResult' + description: The artifact's result field + '400': + description: Missing artifact_key query parameter + '401': + description: Missing or invalid API key + '403': + description: Access denied to this agent job + '404': + description: Artifact not found in storage /v1/agents/jobs/{agent_job_id}/references/{resource_id}/: get: operationId: agents_jobs_references_retrieve @@ -976,14 +1016,6 @@ paths: schema: type: string required: true - - name: organization_id - in: query - required: false - schema: - type: string - format: uuid - description: Organization ID. This is required for access control. It can - be provided via query or request body depending on the endpoint. tags: - agents - sdk @@ -1063,7 +1095,8 @@ paths: /v1/agents/jobs/{agent_job_id}/result/: get: operationId: agents_jobs_result_retrieve - description: Get agent job result data. + description: Get agent job result data. If the output references artifact keys + (e.g. `evidence_data` values), fetch their full content via GET /v1/agents/jobs/{agent_job_id}/artifacts/result/?artifact_key=. parameters: - in: path name: agent_job_id @@ -2562,17 +2595,11 @@ paths: detail: 'Unknown connector: foo. Available: slack, gmail' summary: Not found description: Connector type not found - /v1/policies/: + /v1/knowledge-base/: get: - operationId: policies_list - description: List all policies and create a new policy + operationId: knowledge_base_list + description: List all KBs for the org, or start a new draft. parameters: - - name: ordering - required: false - in: query - description: Which field to use when ordering the results. - schema: - type: string - name: page required: false in: query @@ -2585,12 +2612,6 @@ paths: description: Number of results to return per page. schema: type: integer - - name: search - required: false - in: query - description: A search term. - schema: - type: string - name: organization_id in: query required: false @@ -2600,7 +2621,7 @@ paths: description: Organization ID. This is required for access control. It can be provided via query or request body depending on the endpoint. tags: - - policies + - knowledge-base - sdk security: - apiKeyAuth: [] @@ -2609,19 +2630,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/PaginatedPolicyList' + $ref: '#/components/schemas/PaginatedKnowledgeBaseList' description: '' post: - operationId: policies_create - description: List all policies and create a new policy + operationId: knowledge_base_create + description: List all KBs for the org, or start a new draft. tags: - - policies + - knowledge-base - sdk requestBody: content: application/json: schema: - $ref: '#/components/schemas/CreatePolicyRequest' + $ref: '#/components/schemas/CreateKnowledgeBaseRequest' required: true security: - apiKeyAuth: [] @@ -2630,23 +2651,8 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/CreatePolicy' - description: Policy created successfully. - '400': - content: - application/json: - schema: - type: object - additionalProperties: - oneOf: - - type: array - items: - type: string - - type: string - description: 'Validation failure: a map of field name to a list of - error messages (DRF serializers) or a single message (e.g. organization_id - validation).' - description: Invalid request data. + $ref: '#/components/schemas/CreateKnowledgeBase' + description: '' parameters: - name: organization_id in: query @@ -2656,10 +2662,10 @@ paths: format: uuid description: Organization ID. This is required for access control. It can be provided via query or request body depending on the endpoint. - /v1/policies/{id}/: + /v1/knowledge-base/{id}/: get: - operationId: policies_retrieve - description: Retrieve, update, or delete a single policy by ID + operationId: knowledge_base_retrieve + description: Get or delete a single KB. GET triggers a best-effort display sync. parameters: - in: path name: id @@ -2676,7 +2682,7 @@ paths: description: Organization ID. This is required for access control. It can be provided via query or request body depending on the endpoint. tags: - - policies + - knowledge-base - sdk security: - apiKeyAuth: [] @@ -2685,17 +2691,11 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Policy' - description: Successfully retrieved policy. - '404': - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDetailResponse' - description: Policy not found. - put: - operationId: policies_update - description: Retrieve, update, or delete a single policy by ID + $ref: '#/components/schemas/KnowledgeBase' + description: '' + delete: + operationId: knowledge_base_destroy + description: Get or delete a single KB. GET triggers a best-effort display sync. parameters: - in: path name: id @@ -2712,47 +2712,19 @@ paths: description: Organization ID. This is required for access control. It can be provided via query or request body depending on the endpoint. tags: - - policies + - knowledge-base - sdk - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UpdatePolicyRequest' - required: true security: - apiKeyAuth: [] responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/UpdatePolicy' - description: Policy updated successfully. - '400': - content: - application/json: - schema: - type: object - additionalProperties: - oneOf: - - type: array - items: - type: string - - type: string - description: 'Validation failure: a map of field name to a list of - error messages (DRF serializers) or a single message (e.g. organization_id - validation).' - description: Invalid request data. - '404': - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDetailResponse' - description: Policy not found. - patch: - operationId: policies_partial_update - description: Retrieve, update, or delete a single policy by ID + '204': + description: Deleted. + /v1/knowledge-base/{id}/draft/: + get: + operationId: knowledge_base_draft_retrieve + description: |- + Poll the atlas draft. Returns the projected draft status + refs. + Use until draft_status == 'ready' (or 'error'). parameters: - in: path name: id @@ -2769,13 +2741,8 @@ paths: description: Organization ID. This is required for access control. It can be provided via query or request body depending on the endpoint. tags: - - policies + - knowledge-base - sdk - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/PatchedUpdatePolicyRequest' security: - apiKeyAuth: [] responses: @@ -2783,32 +2750,14 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/UpdatePolicy' - description: Policy updated successfully. - '400': - content: - application/json: - schema: - type: object - additionalProperties: - oneOf: - - type: array - items: - type: string - - type: string - description: 'Validation failure: a map of field name to a list of - error messages (DRF serializers) or a single message (e.g. organization_id - validation).' - description: Invalid request data. - '404': - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDetailResponse' - description: Policy not found. - delete: - operationId: policies_destroy - description: Retrieve, update, or delete a single policy by ID + $ref: '#/components/schemas/Draft' + description: '' + /v1/knowledge-base/{id}/finalize/: + post: + operationId: knowledge_base_finalize_create + description: |- + Commit the agreed selection into a lens and mark the KB active. + Operation sync: strict — propagate atlas errors; reconcile in finally. parameters: - in: path name: id @@ -2825,45 +2774,31 @@ paths: description: Organization ID. This is required for access control. It can be provided via query or request body depending on the endpoint. tags: - - policies + - knowledge-base - sdk + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FinalizeRequest' security: - apiKeyAuth: [] responses: - '204': - description: Policy deleted successfully. - '404': - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDetailResponse' - description: Policy not found. - '409': + '200': content: application/json: schema: - $ref: '#/components/schemas/PolicyDeleteConflict' - description: Policy is in use by agents and cannot be deleted. - /v1/policies/{policy_id}/versions/: - get: - operationId: policies_versions_list - description: Create a new policy version or list all versions of a specific - policy + $ref: '#/components/schemas/KnowledgeBase' + description: '' + /v1/knowledge-base/{id}/regenerate/: + post: + operationId: knowledge_base_regenerate_create + description: |- + Kick off another async generation round with feedback. + Operation sync: propagate atlas errors; finally reconcile. parameters: - - name: page - required: false - in: query - description: A page number within the paginated result set. - schema: - type: integer - - name: page_size - required: false - in: query - description: Number of results to return per page. - schema: - type: integer - in: path - name: policy_id + name: id schema: type: string format: uuid @@ -2877,30 +2812,38 @@ paths: description: Organization ID. This is required for access control. It can be provided via query or request body depending on the endpoint. tags: - - policies + - knowledge-base - sdk + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegenerateRequest' security: - apiKeyAuth: [] responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/PaginatedPolicyVersionList' - description: Successfully retrieved list of policy versions. - '404': + '202': content: application/json: schema: - $ref: '#/components/schemas/ErrorDetailResponse' - description: Policy not found. + $ref: '#/components/schemas/Draft' + description: '' + /v1/knowledge-base/{id}/resolve/: post: - operationId: policies_versions_create - description: Create a new policy version or list all versions of a specific - policy + operationId: knowledge_base_resolve_create + description: |- + Approve or decline a pending regeneration proposal. + + A regeneration round lands as draft.pendingProposal WITHOUT changing the + agreed selection. The reviewer resolves it here: + - apply: { refs, suggested_name?, accept_summary? } — refs is the + resolved selection (per-item accept/reject computed client-side). + - decline: { discard: true } — keep the prior selection untouched. + + finalize is blocked by atlas (409) until this is called. parameters: - in: path - name: policy_id + name: id schema: type: string format: uuid @@ -2914,25 +2857,603 @@ paths: description: Organization ID. This is required for access control. It can be provided via query or request body depending on the endpoint. tags: - - policies + - knowledge-base - sdk requestBody: content: application/json: schema: - $ref: '#/components/schemas/CreatePolicyVersionRequest' - required: true + $ref: '#/components/schemas/ResolveRequest' security: - apiKeyAuth: [] responses: - '201': + '200': content: application/json: schema: - $ref: '#/components/schemas/CreatePolicyVersion' - description: Policy version created successfully. - '400': - content: + $ref: '#/components/schemas/Draft' + description: '' + /v1/knowledge-base/{id}/selection/: + patch: + operationId: knowledge_base_selection_partial_update + description: |- + Persist hand-edits to the working selection (typology + tactic opt-in/out). + Operation sync: if atlas rejects, the error propagates; reconciling sync + runs in finally. + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - knowledge-base + - sdk + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PatchedPatchSelectionRequest' + security: + - apiKeyAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/Draft' + description: '' + /v1/knowledge-base/{id}/sync/: + post: + operationId: knowledge_base_sync_create + description: |- + Standalone best-effort lens sync (display mode). + POST /knowledge-base//sync/ + Always returns 200; sync_error describes any failure. + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - knowledge-base + - sdk + security: + - apiKeyAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/KnowledgeBase' + description: '' + /v1/knowledge-base/{id}/unlink/: + delete: + operationId: knowledge_base_unlink_destroy + description: |- + Unlink a knowledge base: remove the local KnowledgeBase row only, leaving + the Atlas lens (and any in-progress draft) untouched. + + This is the non-destructive counterpart to DELETE //. Use it to stop + tracking a lens in this org without deleting it from Atlas — e.g. the lens + is shared, or you intend to re-import it later via import-lens. Unlike + DELETE //, this never calls atlas.delete_draft / atlas.delete_lens. + + DELETE /knowledge-base//unlink/ + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - knowledge-base + - sdk + security: + - apiKeyAuth: [] + responses: + '204': + description: 'Unlinked: local row removed; Atlas lens preserved.' + /v1/knowledge-base/catalog/: + get: + operationId: knowledge_base_catalog_retrieve + description: Names-only typology+tactic catalog. Powers typology/tactic opt-in + UI. + tags: + - knowledge-base + - sdk + security: + - apiKeyAuth: [] + responses: + '200': + description: List of typologies with tactic names. + parameters: + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + /v1/knowledge-base/import-lens/: + post: + operationId: knowledge_base_import_lens_create + description: |- + Import a finalized Atlas lens into roe-main by its atlas_lens_id. + Creates a KnowledgeBase row in active state with the lens snapshot — + no draft involved. + + POST /knowledge-base/import-lens/ body: { atlas_lens_id } + + Idempotent: if a row for this org already points to the same + atlas_lens_id the existing record is synced and returned (200). + tags: + - knowledge-base + - sdk + requestBody: + content: + application/json: + schema: + type: object + additionalProperties: {} + security: + - apiKeyAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/KnowledgeBase' + description: '' + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/KnowledgeBase' + description: '' + parameters: + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + /v1/knowledge-base/lens/{atlas_lens_id}/: + get: + operationId: knowledge_base_lens_retrieve + description: |- + Fetch a lens directly from Atlas by its atlas_lens_id and return the + names-only projection. Does NOT require a KnowledgeBase row to exist. + + If a KnowledgeBase row for this org already points to the given + atlas_lens_id, it is also synced (best-effort) and returned under + the "knowledge_base" key. + + GET /knowledge-base/lens// + parameters: + - in: path + name: atlas_lens_id + schema: + type: string + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - knowledge-base + - sdk + security: + - apiKeyAuth: [] + responses: + '200': + description: Lens projection and optional local KB record. + /v1/policies/: + get: + operationId: policies_list + description: List all policies and create a new policy + parameters: + - name: ordering + required: false + in: query + description: Which field to use when ordering the results. + schema: + type: string + - name: page + required: false + in: query + description: A page number within the paginated result set. + schema: + type: integer + - name: page_size + required: false + in: query + description: Number of results to return per page. + schema: + type: integer + - name: search + required: false + in: query + description: A search term. + schema: + type: string + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - policies + - sdk + security: + - apiKeyAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/PaginatedPolicyList' + description: '' + post: + operationId: policies_create + description: List all policies and create a new policy + tags: + - policies + - sdk + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePolicyRequest' + required: true + security: + - apiKeyAuth: [] + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePolicy' + description: Policy created successfully. + '400': + content: + application/json: + schema: + type: object + additionalProperties: + oneOf: + - type: array + items: + type: string + - type: string + description: 'Validation failure: a map of field name to a list of + error messages (DRF serializers) or a single message (e.g. organization_id + validation).' + description: Invalid request data. + parameters: + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + /v1/policies/{id}/: + get: + operationId: policies_retrieve + description: Retrieve, update, or delete a single policy by ID + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - policies + - sdk + security: + - apiKeyAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/Policy' + description: Successfully retrieved policy. + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDetailResponse' + description: Policy not found. + put: + operationId: policies_update + description: Retrieve, update, or delete a single policy by ID + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - policies + - sdk + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdatePolicyRequest' + required: true + security: + - apiKeyAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/UpdatePolicy' + description: Policy updated successfully. + '400': + content: + application/json: + schema: + type: object + additionalProperties: + oneOf: + - type: array + items: + type: string + - type: string + description: 'Validation failure: a map of field name to a list of + error messages (DRF serializers) or a single message (e.g. organization_id + validation).' + description: Invalid request data. + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDetailResponse' + description: Policy not found. + patch: + operationId: policies_partial_update + description: Retrieve, update, or delete a single policy by ID + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - policies + - sdk + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PatchedUpdatePolicyRequest' + security: + - apiKeyAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/UpdatePolicy' + description: Policy updated successfully. + '400': + content: + application/json: + schema: + type: object + additionalProperties: + oneOf: + - type: array + items: + type: string + - type: string + description: 'Validation failure: a map of field name to a list of + error messages (DRF serializers) or a single message (e.g. organization_id + validation).' + description: Invalid request data. + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDetailResponse' + description: Policy not found. + delete: + operationId: policies_destroy + description: Retrieve, update, or delete a single policy by ID + parameters: + - in: path + name: id + schema: + type: string + format: uuid + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - policies + - sdk + security: + - apiKeyAuth: [] + responses: + '204': + description: Policy deleted successfully. + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDetailResponse' + description: Policy not found. + '409': + content: + application/json: + schema: + $ref: '#/components/schemas/PolicyDeleteConflict' + description: Policy is in use by agents and cannot be deleted. + /v1/policies/{policy_id}/versions/: + get: + operationId: policies_versions_list + description: Create a new policy version or list all versions of a specific + policy + parameters: + - name: page + required: false + in: query + description: A page number within the paginated result set. + schema: + type: integer + - name: page_size + required: false + in: query + description: Number of results to return per page. + schema: + type: integer + - in: path + name: policy_id + schema: + type: string + format: uuid + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - policies + - sdk + security: + - apiKeyAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/PaginatedPolicyVersionList' + description: Successfully retrieved list of policy versions. + '404': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDetailResponse' + description: Policy not found. + post: + operationId: policies_versions_create + description: Create a new policy version or list all versions of a specific + policy + parameters: + - in: path + name: policy_id + schema: + type: string + format: uuid + required: true + - name: organization_id + in: query + required: false + schema: + type: string + format: uuid + description: Organization ID. This is required for access control. It can + be provided via query or request body depending on the endpoint. + tags: + - policies + - sdk + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePolicyVersionRequest' + required: true + security: + - apiKeyAuth: [] + responses: + '201': + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePolicyVersion' + description: Policy version created successfully. + '400': + content: application/json: schema: type: object @@ -3399,6 +3920,31 @@ components: - data_type - description - key + AgentJobArtifactResult: + type: object + properties: + result: + oneOf: + - {} + - type: 'null' + description: The artifact's result content (any JSON value). + required: + - result + AgentJobCancelAllResponse: + type: object + properties: + task_id: + type: + - string + - 'null' + targeted_count: + type: integer + note: + type: string + required: + - note + - targeted_count + - task_id AgentJobDeleteDataResponse: type: object description: Response payload of purge_agent_job_data (delete-data and :purgeData). @@ -3820,7 +4366,10 @@ components: type: - integer - 'null' - description: Job count from annotation, or None when not fetched (use /agents/job-stats/). + description: |- + Served job count: cached baseline + live delta, annotated by the views + as ``job_count``. ``None`` when stats weren't fetched (the list can be + requested with ``include_job_stats=false``; use /agents/job-stats/). readOnly: true most_recent_job: type: @@ -4078,6 +4627,8 @@ components: - sharepoint - zendesk - google_drive + - google_docs + - google_sheets - salesforce - web_application - custom_api @@ -4096,6 +4647,8 @@ components: * `sharepoint` - SHAREPOINT * `zendesk` - ZENDESK * `google_drive` - GOOGLE_DRIVE + * `google_docs` - GOOGLE_DOCS + * `google_sheets` - GOOGLE_SHEETS * `salesforce` - SALESFORCE * `web_application` - WEB_APPLICATION * `custom_api` - CUSTOM_API @@ -4136,6 +4689,51 @@ components: - config - connector_type - name + CreateKnowledgeBase: + type: object + description: Body for POST /knowledge-base/ — starts a new draft. + properties: + company: + type: string + maxLength: 255 + name: + type: string + maxLength: 255 + product_name: + type: string + maxLength: 255 + website_url: + type: string + format: uri + brief: + type: string + minLength: 10 + required: + - brief + - company + CreateKnowledgeBaseRequest: + type: object + description: Body for POST /knowledge-base/ — starts a new draft. + properties: + company: + type: string + minLength: 1 + maxLength: 255 + name: + type: string + maxLength: 255 + product_name: + type: string + maxLength: 255 + website_url: + type: string + format: uri + brief: + type: string + minLength: 10 + required: + - brief + - company CreatePolicy: type: object description: Serializer for creating a new policy with initial version @@ -4249,6 +4847,92 @@ components: - base_agent_id - version_id - version_name + Draft: + type: object + description: Projected atlas draft returned from poll/regenerate/resolve endpoints. + properties: + id: + type: string + status: + $ref: '#/components/schemas/DraftStatusEnum' + error: + type: + - string + - 'null' + company: + type: string + productName: + type: + - string + - 'null' + suggestedName: + type: string + productSummary: + type: string + iterationCount: + type: integer + refs: + type: array + items: + $ref: '#/components/schemas/DraftRef' + pendingProposal: + oneOf: + - $ref: '#/components/schemas/PendingProposal' + - type: 'null' + createdAt: + type: + - string + - 'null' + updatedAt: + type: + - string + - 'null' + required: + - company + - id + - iterationCount + - productSummary + - refs + - status + - suggestedName + DraftRef: + type: object + description: A single ref in a selection (names-only projection from atlas). + properties: + typologyId: + type: string + typologyName: + type: string + relevance: + allOf: + - $ref: '#/components/schemas/RelevanceEnum' + default: watch + rationale: + type: string + tacticIds: + type: + - array + - 'null' + items: + type: string + tacticNames: + type: + - array + - 'null' + items: + type: string + required: + - typologyId + DraftStatusEnum: + enum: + - generating + - ready + - error + type: string + description: |- + * `generating` - generating + * `ready` - ready + * `error` - error DuplicateConnectionExisting: type: object description: Identifying summary of the existing connection that triggered a @@ -4283,6 +4967,100 @@ components: description: Human-readable error detail required: - detail + FinalizeRequest: + type: object + description: Body for POST /knowledge-base//finalize/. + properties: + name: + type: string + mcp_enabled: + type: boolean + default: true + public: + type: boolean + default: true + KnowledgeBase: + type: object + properties: + id: + type: string + format: uuid + readOnly: true + organization_id: + type: string + format: uuid + readOnly: true + name: + type: string + maxLength: 255 + company: + type: string + maxLength: 255 + status: + allOf: + - $ref: '#/components/schemas/KnowledgeBaseStatusEnum' + readOnly: true + atlas_draft_id: + type: + - string + - 'null' + readOnly: true + atlas_lens_id: + type: + - string + - 'null' + readOnly: true + mcp_url: + type: string + readOnly: true + lens_snapshot: + oneOf: + - {} + - type: 'null' + readOnly: true + last_synced_at: + type: + - string + - 'null' + format: date-time + readOnly: true + sync_error: + type: + - string + - 'null' + readOnly: true + created_at: + type: string + format: date-time + readOnly: true + updated_at: + type: string + format: date-time + readOnly: true + required: + - atlas_draft_id + - atlas_lens_id + - company + - created_at + - id + - last_synced_at + - lens_snapshot + - mcp_url + - name + - organization_id + - status + - sync_error + - updated_at + KnowledgeBaseStatusEnum: + enum: + - drafting + - active + - orphaned + type: string + description: |- + * `drafting` - Drafting + * `active` - Active + * `orphaned` - Orphaned MessageResponse: type: object description: 'Simple success acknowledgement body: `{"message": ...}`.' @@ -4337,6 +5115,29 @@ components: type: array items: $ref: '#/components/schemas/ConnectionList' + PaginatedKnowledgeBaseList: + type: object + required: + - count + - results + properties: + count: + type: integer + example: 123 + next: + type: string + nullable: true + format: uri + example: http://api.example.org/accounts/?page=4 + previous: + type: string + nullable: true + format: uri + example: http://api.example.org/accounts/?page=2 + results: + type: array + items: + $ref: '#/components/schemas/KnowledgeBase' PaginatedPolicyList: type: object required: @@ -4408,6 +5209,17 @@ components: cache_failed_jobs: type: boolean description: Whether to cache failed jobs for this agent. + PatchedPatchSelectionRequest: + type: object + description: Body for PATCH /knowledge-base//selection/. + properties: + refs: + type: array + items: + type: object + additionalProperties: {} + suggested_name: + type: string PatchedUpdateConnectionRequest: type: object description: |- @@ -4447,6 +5259,33 @@ components: maxLength: 255 description: type: string + PendingProposal: + type: object + description: A staged regeneration awaiting reviewer approval (names-only). + properties: + refs: + type: array + items: + $ref: '#/components/schemas/DraftRef' + baseSelection: + type: array + items: + $ref: '#/components/schemas/DraftRef' + feedback: + type: + - string + - 'null' + suggestedName: + type: string + productSummary: + type: string + createdAt: + type: + - string + - 'null' + required: + - baseSelection + - refs Policy: type: object description: Policy serializer @@ -4580,6 +5419,44 @@ components: required: - detail - failed_collections + RegenerateRequest: + type: object + description: Body for POST /knowledge-base//regenerate/. + properties: + feedback: + type: string + RelevanceEnum: + enum: + - core + - watch + - edge + type: string + description: |- + * `core` - core + * `watch` - watch + * `edge` - edge + ResolveRequest: + type: object + description: |- + Body for POST /knowledge-base//resolve/. + + discard=True declines the pending proposal. Otherwise refs is the reviewer's + resolved selection (opaque-handle dicts) and suggested_name / accept_summary + optionally adopt the proposal's name / summary. + properties: + refs: + type: array + items: + type: object + additionalProperties: {} + suggested_name: + type: string + accept_summary: + type: boolean + default: false + discard: + type: boolean + default: false StatusEnum: enum: - active diff --git a/openapi/wrappers.yml b/openapi/wrappers.yml index e62659b..76b443c 100644 --- a/openapi/wrappers.yml +++ b/openapi/wrappers.yml @@ -509,6 +509,22 @@ apis: location: path annotation: str coerce: uuid + - kind: body + method_name: retrieve_artifact + docstring: '' + method: GET + path: /v1/agents/jobs/{agent_job_id}/artifacts/result/ + endpoint_module: roe._generated.api.agents.agents_jobs_artifacts_result_retrieve + return_type: AgentJobArtifactResult + return_import: roe._generated.models.agent_job_artifact_result.AgentJobArtifactResult + parameters: + - name: job_id + location: path + annotation: str + coerce: uuid + - name: artifact_key + location: query + annotation: str - kind: body method_name: cancel docstring: '' @@ -559,6 +575,80 @@ apis: docstring: Download a binary reference produced by an agent job. method: GET path: /v1/agents/jobs/{agent_job_id}/references/{resource_id}/ + knowledge_base: + class_name: KnowledgeBaseAPI + docstring: API for managing Knowledge Base lenses and drafts. + operations: + - kind: manual + method_name: list + docstring: List all knowledge bases for the organisation. + method: GET + path: /v1/knowledge-base/ + - kind: manual + method_name: create + docstring: Create a new knowledge base draft (async generation). + method: POST + path: /v1/knowledge-base/ + - kind: manual + method_name: retrieve + docstring: Retrieve a single knowledge base record. + method: GET + path: /v1/knowledge-base/{id}/ + - kind: manual + method_name: delete + docstring: Delete a knowledge base and its associated Atlas draft or lens. + method: DELETE + path: /v1/knowledge-base/{id}/ + - kind: manual + method_name: poll_draft + docstring: Poll the Atlas draft status until ready or error. + method: GET + path: /v1/knowledge-base/{id}/draft/ + - kind: manual + method_name: patch_selection + docstring: Patch the draft's typology/tactic selection. + method: PATCH + path: /v1/knowledge-base/{id}/selection/ + - kind: manual + method_name: regenerate + docstring: Kick off an async regeneration round with optional feedback. + method: POST + path: /v1/knowledge-base/{id}/regenerate/ + - kind: manual + method_name: resolve + docstring: Approve or decline a pending regeneration proposal. + method: POST + path: /v1/knowledge-base/{id}/resolve/ + - kind: manual + method_name: finalize + docstring: Commit the draft into a permanent Atlas lens. + method: POST + path: /v1/knowledge-base/{id}/finalize/ + - kind: manual + method_name: sync + docstring: Sync the lens snapshot from Atlas (best-effort). + method: POST + path: /v1/knowledge-base/{id}/sync/ + - kind: manual + method_name: unlink + docstring: Unlink a knowledge base locally, preserving the Atlas lens. + method: DELETE + path: /v1/knowledge-base/{id}/unlink/ + - kind: manual + method_name: catalog + docstring: Fetch the names-only typology and tactic catalog. + method: GET + path: /v1/knowledge-base/catalog/ + - kind: manual + method_name: lens_by_atlas_id + docstring: Fetch and optionally sync a lens by its Atlas ID. + method: GET + path: /v1/knowledge-base/lens/{atlas_lens_id}/ + - kind: manual + method_name: import_lens + docstring: Import a finalized Atlas lens into roe-main by its atlas_lens_id. + method: POST + path: /v1/knowledge-base/import-lens/ connections: class_name: ConnectionsAPI docstring: API for managing external data connections. diff --git a/pyproject.toml b/pyproject.toml index bb92b20..197dc1b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "roe-ai" -version = "1.1.1" +version = "1.1.2" authors = [ { name = "Roe", email = "founders@roe-ai.com" }, ] diff --git a/src/roe/_generated/api/agents/agents_jobs_artifacts_result_retrieve.py b/src/roe/_generated/api/agents/agents_jobs_artifacts_result_retrieve.py new file mode 100644 index 0000000..6077878 --- /dev/null +++ b/src/roe/_generated/api/agents/agents_jobs_artifacts_result_retrieve.py @@ -0,0 +1,244 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.agent_job_artifact_result import AgentJobArtifactResult +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + agent_job_id: str, + *, + artifact_key: str, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + + + + + params: dict[str, Any] = {} + + params["artifact_key"] = artifact_key + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "/v1/agents/jobs/{agent_job_id}/artifacts/result/".format(agent_job_id=quote(str(agent_job_id), safe=""),), + "params": params, + } + + + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> AgentJobArtifactResult | Any | None: + if response.status_code == 200: + response_200 = AgentJobArtifactResult.from_dict(response.json()) + + + + return response_200 + + if response.status_code == 400: + response_400 = cast(Any, None) + return response_400 + + if response.status_code == 401: + response_401 = cast(Any, None) + return response_401 + + if response.status_code == 403: + response_403 = cast(Any, None) + return response_403 + + if response.status_code == 404: + response_404 = cast(Any, None) + return response_404 + + 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[AgentJobArtifactResult | Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + agent_job_id: str, + *, + client: AuthenticatedClient, + artifact_key: str, + organization_id: UUID | Unset = UNSET, + +) -> Response[AgentJobArtifactResult | Any]: + """ Get tool result artifact (result only) + + Fetches a tool result artifact for an agent job, returning only the `result` field. Internal fields + (`metadata`, `input`, and cost/token `usage` data) are stripped. The artifact_key is available in + the agent job result output (e.g. `evidence_data` values). + + Args: + agent_job_id (str): + artifact_key (str): + organization_id (UUID | 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[AgentJobArtifactResult | Any] + """ + + + kwargs = _get_kwargs( + agent_job_id=agent_job_id, +artifact_key=artifact_key, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + agent_job_id: str, + *, + client: AuthenticatedClient, + artifact_key: str, + organization_id: UUID | Unset = UNSET, + +) -> AgentJobArtifactResult | Any | None: + """ Get tool result artifact (result only) + + Fetches a tool result artifact for an agent job, returning only the `result` field. Internal fields + (`metadata`, `input`, and cost/token `usage` data) are stripped. The artifact_key is available in + the agent job result output (e.g. `evidence_data` values). + + Args: + agent_job_id (str): + artifact_key (str): + organization_id (UUID | 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: + AgentJobArtifactResult | Any + """ + + + return sync_detailed( + agent_job_id=agent_job_id, +client=client, +artifact_key=artifact_key, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + agent_job_id: str, + *, + client: AuthenticatedClient, + artifact_key: str, + organization_id: UUID | Unset = UNSET, + +) -> Response[AgentJobArtifactResult | Any]: + """ Get tool result artifact (result only) + + Fetches a tool result artifact for an agent job, returning only the `result` field. Internal fields + (`metadata`, `input`, and cost/token `usage` data) are stripped. The artifact_key is available in + the agent job result output (e.g. `evidence_data` values). + + Args: + agent_job_id (str): + artifact_key (str): + organization_id (UUID | 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[AgentJobArtifactResult | Any] + """ + + + kwargs = _get_kwargs( + agent_job_id=agent_job_id, +artifact_key=artifact_key, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + agent_job_id: str, + *, + client: AuthenticatedClient, + artifact_key: str, + organization_id: UUID | Unset = UNSET, + +) -> AgentJobArtifactResult | Any | None: + """ Get tool result artifact (result only) + + Fetches a tool result artifact for an agent job, returning only the `result` field. Internal fields + (`metadata`, `input`, and cost/token `usage` data) are stripped. The artifact_key is available in + the agent job result output (e.g. `evidence_data` values). + + Args: + agent_job_id (str): + artifact_key (str): + organization_id (UUID | 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: + AgentJobArtifactResult | Any + """ + + + return (await asyncio_detailed( + agent_job_id=agent_job_id, +client=client, +artifact_key=artifact_key, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/agents/agents_jobs_cancel_all_create.py b/src/roe/_generated/api/agents/agents_jobs_cancel_all_create.py index 8ab885d..e562a6a 100644 --- a/src/roe/_generated/api/agents/agents_jobs_cancel_all_create.py +++ b/src/roe/_generated/api/agents/agents_jobs_cancel_all_create.py @@ -8,7 +8,7 @@ from ...types import Response, UNSET from ... import errors -from ...models.error_detail_response import ErrorDetailResponse +from ...models.agent_job_cancel_all_response import AgentJobCancelAllResponse from ...types import UNSET, Unset from typing import cast from uuid import UUID @@ -47,24 +47,13 @@ def _get_kwargs( -def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Any | ErrorDetailResponse | None: - if response.status_code == 204: - response_204 = cast(Any, None) - return response_204 +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> AgentJobCancelAllResponse | None: + if response.status_code == 200: + response_200 = AgentJobCancelAllResponse.from_dict(response.json()) - if response.status_code == 403: - response_403 = ErrorDetailResponse.from_dict(response.json()) - - return response_403 - - if response.status_code == 404: - response_404 = ErrorDetailResponse.from_dict(response.json()) - - - - return response_404 + return response_200 if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) @@ -72,7 +61,7 @@ def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Res return None -def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[Any | ErrorDetailResponse]: +def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[AgentJobCancelAllResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -87,10 +76,10 @@ def sync_detailed( client: AuthenticatedClient, organization_id: UUID | Unset = UNSET, -) -> Response[Any | ErrorDetailResponse]: - """ Cancel all agent jobs +) -> Response[AgentJobCancelAllResponse]: + """ Cancel all running agent jobs (:cancelAll) - Cancel all running jobs for a given agent. + Cancel all running jobs for an agent. Args: agent_id (UUID): @@ -101,7 +90,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | ErrorDetailResponse] + Response[AgentJobCancelAllResponse] """ @@ -123,10 +112,10 @@ def sync( client: AuthenticatedClient, organization_id: UUID | Unset = UNSET, -) -> Any | ErrorDetailResponse | None: - """ Cancel all agent jobs +) -> AgentJobCancelAllResponse | None: + """ Cancel all running agent jobs (:cancelAll) - Cancel all running jobs for a given agent. + Cancel all running jobs for an agent. Args: agent_id (UUID): @@ -137,7 +126,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | ErrorDetailResponse + AgentJobCancelAllResponse """ @@ -154,10 +143,10 @@ async def asyncio_detailed( client: AuthenticatedClient, organization_id: UUID | Unset = UNSET, -) -> Response[Any | ErrorDetailResponse]: - """ Cancel all agent jobs +) -> Response[AgentJobCancelAllResponse]: + """ Cancel all running agent jobs (:cancelAll) - Cancel all running jobs for a given agent. + Cancel all running jobs for an agent. Args: agent_id (UUID): @@ -168,7 +157,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any | ErrorDetailResponse] + Response[AgentJobCancelAllResponse] """ @@ -190,10 +179,10 @@ async def asyncio( client: AuthenticatedClient, organization_id: UUID | Unset = UNSET, -) -> Any | ErrorDetailResponse | None: - """ Cancel all agent jobs +) -> AgentJobCancelAllResponse | None: + """ Cancel all running agent jobs (:cancelAll) - Cancel all running jobs for a given agent. + Cancel all running jobs for an agent. Args: agent_id (UUID): @@ -204,7 +193,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Any | ErrorDetailResponse + AgentJobCancelAllResponse """ diff --git a/src/roe/_generated/api/agents/agents_jobs_references_retrieve.py b/src/roe/_generated/api/agents/agents_jobs_references_retrieve.py index 4a8aaf5..47399aa 100644 --- a/src/roe/_generated/api/agents/agents_jobs_references_retrieve.py +++ b/src/roe/_generated/api/agents/agents_jobs_references_retrieve.py @@ -25,7 +25,6 @@ def _get_kwargs( resource_id: str, *, download: bool | Unset = UNSET, - organization_id: UUID | Unset = UNSET, ) -> dict[str, Any]: @@ -36,11 +35,6 @@ def _get_kwargs( params["download"] = download - json_organization_id: str | Unset = UNSET - if not isinstance(organization_id, Unset): - json_organization_id = str(organization_id) - params["organization_id"] = json_organization_id - params = {k: v for k, v in params.items() if v is not UNSET and v is not None} @@ -156,7 +150,6 @@ def sync_detailed( *, client: AuthenticatedClient, download: bool | Unset = UNSET, - organization_id: UUID | Unset = UNSET, ) -> Response[AgentsJobsReferencesRetrieveResponse400Type1 | AgentsJobsReferencesRetrieveResponse400Type2 | list[str] | ApiErrorResponse | ErrorDetailResponse | File]: """ Serve a reference file associated with an agent job. @@ -165,7 +158,6 @@ def sync_detailed( agent_job_id (UUID): resource_id (str): download (bool | Unset): - organization_id (UUID | Unset): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -180,7 +172,6 @@ def sync_detailed( agent_job_id=agent_job_id, resource_id=resource_id, download=download, -organization_id=organization_id, ) @@ -196,7 +187,6 @@ def sync( *, client: AuthenticatedClient, download: bool | Unset = UNSET, - organization_id: UUID | Unset = UNSET, ) -> AgentsJobsReferencesRetrieveResponse400Type1 | AgentsJobsReferencesRetrieveResponse400Type2 | list[str] | ApiErrorResponse | ErrorDetailResponse | File | None: """ Serve a reference file associated with an agent job. @@ -205,7 +195,6 @@ def sync( agent_job_id (UUID): resource_id (str): download (bool | Unset): - organization_id (UUID | Unset): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -221,7 +210,6 @@ def sync( resource_id=resource_id, client=client, download=download, -organization_id=organization_id, ).parsed @@ -231,7 +219,6 @@ async def asyncio_detailed( *, client: AuthenticatedClient, download: bool | Unset = UNSET, - organization_id: UUID | Unset = UNSET, ) -> Response[AgentsJobsReferencesRetrieveResponse400Type1 | AgentsJobsReferencesRetrieveResponse400Type2 | list[str] | ApiErrorResponse | ErrorDetailResponse | File]: """ Serve a reference file associated with an agent job. @@ -240,7 +227,6 @@ async def asyncio_detailed( agent_job_id (UUID): resource_id (str): download (bool | Unset): - organization_id (UUID | Unset): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -255,7 +241,6 @@ async def asyncio_detailed( agent_job_id=agent_job_id, resource_id=resource_id, download=download, -organization_id=organization_id, ) @@ -271,7 +256,6 @@ async def asyncio( *, client: AuthenticatedClient, download: bool | Unset = UNSET, - organization_id: UUID | Unset = UNSET, ) -> AgentsJobsReferencesRetrieveResponse400Type1 | AgentsJobsReferencesRetrieveResponse400Type2 | list[str] | ApiErrorResponse | ErrorDetailResponse | File | None: """ Serve a reference file associated with an agent job. @@ -280,7 +264,6 @@ async def asyncio( agent_job_id (UUID): resource_id (str): download (bool | Unset): - organization_id (UUID | Unset): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. @@ -296,6 +279,5 @@ async def asyncio( resource_id=resource_id, client=client, download=download, -organization_id=organization_id, )).parsed diff --git a/src/roe/_generated/api/agents/agents_jobs_result_retrieve.py b/src/roe/_generated/api/agents/agents_jobs_result_retrieve.py index 9c8b831..6c4901b 100644 --- a/src/roe/_generated/api/agents/agents_jobs_result_retrieve.py +++ b/src/roe/_generated/api/agents/agents_jobs_result_retrieve.py @@ -96,7 +96,9 @@ def sync_detailed( organization_id: UUID | Unset = UNSET, ) -> Response[AgentJobResultResponse | Any | ErrorDetailResponse]: - """ Get agent job result data. + """ Get agent job result data. If the output references artifact keys (e.g. `evidence_data` values), + fetch their full content via GET + /v1/agents/jobs/{agent_job_id}/artifacts/result/?artifact_key=. Args: agent_job_id (UUID): @@ -130,7 +132,9 @@ def sync( organization_id: UUID | Unset = UNSET, ) -> AgentJobResultResponse | Any | ErrorDetailResponse | None: - """ Get agent job result data. + """ Get agent job result data. If the output references artifact keys (e.g. `evidence_data` values), + fetch their full content via GET + /v1/agents/jobs/{agent_job_id}/artifacts/result/?artifact_key=. Args: agent_job_id (UUID): @@ -159,7 +163,9 @@ async def asyncio_detailed( organization_id: UUID | Unset = UNSET, ) -> Response[AgentJobResultResponse | Any | ErrorDetailResponse]: - """ Get agent job result data. + """ Get agent job result data. If the output references artifact keys (e.g. `evidence_data` values), + fetch their full content via GET + /v1/agents/jobs/{agent_job_id}/artifacts/result/?artifact_key=. Args: agent_job_id (UUID): @@ -193,7 +199,9 @@ async def asyncio( organization_id: UUID | Unset = UNSET, ) -> AgentJobResultResponse | Any | ErrorDetailResponse | None: - """ Get agent job result data. + """ Get agent job result data. If the output references artifact keys (e.g. `evidence_data` values), + fetch their full content via GET + /v1/agents/jobs/{agent_job_id}/artifacts/result/?artifact_key=. Args: agent_job_id (UUID): diff --git a/src/roe/_generated/api/knowledge_base/__init__.py b/src/roe/_generated/api/knowledge_base/__init__.py new file mode 100644 index 0000000..c9921b5 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/__init__.py @@ -0,0 +1 @@ +""" Contains endpoint functions for accessing the API """ diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_catalog_retrieve.py b/src/roe/_generated/api/knowledge_base/knowledge_base_catalog_retrieve.py new file mode 100644 index 0000000..2289010 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_catalog_retrieve.py @@ -0,0 +1,128 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...types import UNSET, Unset +from uuid import UUID + + + +def _get_kwargs( + *, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "/v1/knowledge-base/catalog/", + "params": params, + } + + + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Any | None: + if response.status_code == 200: + return None + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[Any]: + 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, + organization_id: UUID | Unset = UNSET, + +) -> Response[Any]: + """ Names-only typology+tactic catalog. Powers typology/tactic opt-in UI. + + Args: + organization_id (UUID | 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[Any] + """ + + + kwargs = _get_kwargs( + organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[Any]: + """ Names-only typology+tactic catalog. Powers typology/tactic opt-in UI. + + Args: + organization_id (UUID | 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[Any] + """ + + + kwargs = _get_kwargs( + organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_create.py b/src/roe/_generated/api/knowledge_base/knowledge_base_create.py new file mode 100644 index 0000000..00f96e3 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_create.py @@ -0,0 +1,204 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.create_knowledge_base import CreateKnowledgeBase +from ...models.create_knowledge_base_request import CreateKnowledgeBaseRequest +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + *, + body: CreateKnowledgeBaseRequest, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "post", + "url": "/v1/knowledge-base/", + "params": params, + } + + _kwargs["json"] = body.to_dict() + + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> CreateKnowledgeBase | None: + if response.status_code == 201: + response_201 = CreateKnowledgeBase.from_dict(response.json()) + + + + return response_201 + + 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[CreateKnowledgeBase]: + 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, + body: CreateKnowledgeBaseRequest, + organization_id: UUID | Unset = UNSET, + +) -> Response[CreateKnowledgeBase]: + """ List all KBs for the org, or start a new draft. + + Args: + organization_id (UUID | Unset): + body (CreateKnowledgeBaseRequest): Body for POST /knowledge-base/ — starts a new draft. + + 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[CreateKnowledgeBase] + """ + + + kwargs = _get_kwargs( + body=body, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + *, + client: AuthenticatedClient, + body: CreateKnowledgeBaseRequest, + organization_id: UUID | Unset = UNSET, + +) -> CreateKnowledgeBase | None: + """ List all KBs for the org, or start a new draft. + + Args: + organization_id (UUID | Unset): + body (CreateKnowledgeBaseRequest): Body for POST /knowledge-base/ — starts a new draft. + + 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: + CreateKnowledgeBase + """ + + + return sync_detailed( + client=client, +body=body, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + *, + client: AuthenticatedClient, + body: CreateKnowledgeBaseRequest, + organization_id: UUID | Unset = UNSET, + +) -> Response[CreateKnowledgeBase]: + """ List all KBs for the org, or start a new draft. + + Args: + organization_id (UUID | Unset): + body (CreateKnowledgeBaseRequest): Body for POST /knowledge-base/ — starts a new draft. + + 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[CreateKnowledgeBase] + """ + + + kwargs = _get_kwargs( + body=body, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + *, + client: AuthenticatedClient, + body: CreateKnowledgeBaseRequest, + organization_id: UUID | Unset = UNSET, + +) -> CreateKnowledgeBase | None: + """ List all KBs for the org, or start a new draft. + + Args: + organization_id (UUID | Unset): + body (CreateKnowledgeBaseRequest): Body for POST /knowledge-base/ — starts a new draft. + + 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: + CreateKnowledgeBase + """ + + + return (await asyncio_detailed( + client=client, +body=body, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_destroy.py b/src/roe/_generated/api/knowledge_base/knowledge_base_destroy.py new file mode 100644 index 0000000..917c889 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_destroy.py @@ -0,0 +1,135 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...types import UNSET, Unset +from uuid import UUID + + + +def _get_kwargs( + id: UUID, + *, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "delete", + "url": "/v1/knowledge-base/{id}/".format(id=quote(str(id), safe=""),), + "params": params, + } + + + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Any | None: + if response.status_code == 204: + return None + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[Any]: + """ Get or delete a single KB. GET triggers a best-effort display sync. + + Args: + id (UUID): + organization_id (UUID | 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[Any] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[Any]: + """ Get or delete a single KB. GET triggers a best-effort display sync. + + Args: + id (UUID): + organization_id (UUID | 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[Any] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_draft_retrieve.py b/src/roe/_generated/api/knowledge_base/knowledge_base_draft_retrieve.py new file mode 100644 index 0000000..e415704 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_draft_retrieve.py @@ -0,0 +1,201 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.draft import Draft +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + id: UUID, + *, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "/v1/knowledge-base/{id}/draft/".format(id=quote(str(id), safe=""),), + "params": params, + } + + + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Draft | None: + if response.status_code == 200: + response_200 = Draft.from_dict(response.json()) + + + + return response_200 + + 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[Draft]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[Draft]: + """ Poll the atlas draft. Returns the projected draft status + refs. + Use until draft_status == 'ready' (or 'error'). + + Args: + id (UUID): + organization_id (UUID | 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[Draft] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Draft | None: + """ Poll the atlas draft. Returns the projected draft status + refs. + Use until draft_status == 'ready' (or 'error'). + + Args: + id (UUID): + organization_id (UUID | 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: + Draft + """ + + + return sync_detailed( + id=id, +client=client, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[Draft]: + """ Poll the atlas draft. Returns the projected draft status + refs. + Use until draft_status == 'ready' (or 'error'). + + Args: + id (UUID): + organization_id (UUID | 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[Draft] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Draft | None: + """ Poll the atlas draft. Returns the projected draft status + refs. + Use until draft_status == 'ready' (or 'error'). + + Args: + id (UUID): + organization_id (UUID | 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: + Draft + """ + + + return (await asyncio_detailed( + id=id, +client=client, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_finalize_create.py b/src/roe/_generated/api/knowledge_base/knowledge_base_finalize_create.py new file mode 100644 index 0000000..3874a84 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_finalize_create.py @@ -0,0 +1,223 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.finalize_request import FinalizeRequest +from ...models.knowledge_base import KnowledgeBase +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + id: UUID, + *, + body: FinalizeRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "post", + "url": "/v1/knowledge-base/{id}/finalize/".format(id=quote(str(id), safe=""),), + "params": params, + } + + + if not isinstance(body, Unset): + _kwargs["json"] = body.to_dict() + + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> KnowledgeBase | None: + if response.status_code == 200: + response_200 = KnowledgeBase.from_dict(response.json()) + + + + return response_200 + + 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[KnowledgeBase]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: UUID, + *, + client: AuthenticatedClient, + body: FinalizeRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[KnowledgeBase]: + """ Commit the agreed selection into a lens and mark the KB active. + Operation sync: strict — propagate atlas errors; reconcile in finally. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (FinalizeRequest | Unset): Body for POST /knowledge-base//finalize/. + + 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[KnowledgeBase] + """ + + + kwargs = _get_kwargs( + id=id, +body=body, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + id: UUID, + *, + client: AuthenticatedClient, + body: FinalizeRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> KnowledgeBase | None: + """ Commit the agreed selection into a lens and mark the KB active. + Operation sync: strict — propagate atlas errors; reconcile in finally. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (FinalizeRequest | Unset): Body for POST /knowledge-base//finalize/. + + 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: + KnowledgeBase + """ + + + return sync_detailed( + id=id, +client=client, +body=body, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + id: UUID, + *, + client: AuthenticatedClient, + body: FinalizeRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[KnowledgeBase]: + """ Commit the agreed selection into a lens and mark the KB active. + Operation sync: strict — propagate atlas errors; reconcile in finally. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (FinalizeRequest | Unset): Body for POST /knowledge-base//finalize/. + + 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[KnowledgeBase] + """ + + + kwargs = _get_kwargs( + id=id, +body=body, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + id: UUID, + *, + client: AuthenticatedClient, + body: FinalizeRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> KnowledgeBase | None: + """ Commit the agreed selection into a lens and mark the KB active. + Operation sync: strict — propagate atlas errors; reconcile in finally. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (FinalizeRequest | Unset): Body for POST /knowledge-base//finalize/. + + 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: + KnowledgeBase + """ + + + return (await asyncio_detailed( + id=id, +client=client, +body=body, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_import_lens_create.py b/src/roe/_generated/api/knowledge_base/knowledge_base_import_lens_create.py new file mode 100644 index 0000000..53e1d17 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_import_lens_create.py @@ -0,0 +1,241 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.knowledge_base import KnowledgeBase +from ...models.knowledge_base_import_lens_create_body import KnowledgeBaseImportLensCreateBody +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + *, + body: KnowledgeBaseImportLensCreateBody | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "post", + "url": "/v1/knowledge-base/import-lens/", + "params": params, + } + + + if not isinstance(body, Unset): + _kwargs["json"] = body.to_dict() + + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> KnowledgeBase | None: + if response.status_code == 200: + response_200 = KnowledgeBase.from_dict(response.json()) + + + + return response_200 + + if response.status_code == 201: + response_201 = KnowledgeBase.from_dict(response.json()) + + + + return response_201 + + 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[KnowledgeBase]: + 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, + body: KnowledgeBaseImportLensCreateBody | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[KnowledgeBase]: + """ Import a finalized Atlas lens into roe-main by its atlas_lens_id. + Creates a KnowledgeBase row in active state with the lens snapshot — + no draft involved. + + POST /knowledge-base/import-lens/ body: { atlas_lens_id } + + Idempotent: if a row for this org already points to the same + atlas_lens_id the existing record is synced and returned (200). + + Args: + organization_id (UUID | Unset): + body (KnowledgeBaseImportLensCreateBody | 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[KnowledgeBase] + """ + + + kwargs = _get_kwargs( + body=body, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + *, + client: AuthenticatedClient, + body: KnowledgeBaseImportLensCreateBody | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> KnowledgeBase | None: + """ Import a finalized Atlas lens into roe-main by its atlas_lens_id. + Creates a KnowledgeBase row in active state with the lens snapshot — + no draft involved. + + POST /knowledge-base/import-lens/ body: { atlas_lens_id } + + Idempotent: if a row for this org already points to the same + atlas_lens_id the existing record is synced and returned (200). + + Args: + organization_id (UUID | Unset): + body (KnowledgeBaseImportLensCreateBody | 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: + KnowledgeBase + """ + + + return sync_detailed( + client=client, +body=body, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + *, + client: AuthenticatedClient, + body: KnowledgeBaseImportLensCreateBody | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[KnowledgeBase]: + """ Import a finalized Atlas lens into roe-main by its atlas_lens_id. + Creates a KnowledgeBase row in active state with the lens snapshot — + no draft involved. + + POST /knowledge-base/import-lens/ body: { atlas_lens_id } + + Idempotent: if a row for this org already points to the same + atlas_lens_id the existing record is synced and returned (200). + + Args: + organization_id (UUID | Unset): + body (KnowledgeBaseImportLensCreateBody | 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[KnowledgeBase] + """ + + + kwargs = _get_kwargs( + body=body, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + *, + client: AuthenticatedClient, + body: KnowledgeBaseImportLensCreateBody | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> KnowledgeBase | None: + """ Import a finalized Atlas lens into roe-main by its atlas_lens_id. + Creates a KnowledgeBase row in active state with the lens snapshot — + no draft involved. + + POST /knowledge-base/import-lens/ body: { atlas_lens_id } + + Idempotent: if a row for this org already points to the same + atlas_lens_id the existing record is synced and returned (200). + + Args: + organization_id (UUID | Unset): + body (KnowledgeBaseImportLensCreateBody | 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: + KnowledgeBase + """ + + + return (await asyncio_detailed( + client=client, +body=body, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_lens_retrieve.py b/src/roe/_generated/api/knowledge_base/knowledge_base_lens_retrieve.py new file mode 100644 index 0000000..dac7407 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_lens_retrieve.py @@ -0,0 +1,149 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...types import UNSET, Unset +from uuid import UUID + + + +def _get_kwargs( + atlas_lens_id: str, + *, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "/v1/knowledge-base/lens/{atlas_lens_id}/".format(atlas_lens_id=quote(str(atlas_lens_id), safe=""),), + "params": params, + } + + + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Any | None: + if response.status_code == 200: + return None + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + atlas_lens_id: str, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[Any]: + r""" Fetch a lens directly from Atlas by its atlas_lens_id and return the + names-only projection. Does NOT require a KnowledgeBase row to exist. + + If a KnowledgeBase row for this org already points to the given + atlas_lens_id, it is also synced (best-effort) and returned under + the \"knowledge_base\" key. + + GET /knowledge-base/lens// + + Args: + atlas_lens_id (str): + organization_id (UUID | 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[Any] + """ + + + kwargs = _get_kwargs( + atlas_lens_id=atlas_lens_id, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + atlas_lens_id: str, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[Any]: + r""" Fetch a lens directly from Atlas by its atlas_lens_id and return the + names-only projection. Does NOT require a KnowledgeBase row to exist. + + If a KnowledgeBase row for this org already points to the given + atlas_lens_id, it is also synced (best-effort) and returned under + the \"knowledge_base\" key. + + GET /knowledge-base/lens// + + Args: + atlas_lens_id (str): + organization_id (UUID | 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[Any] + """ + + + kwargs = _get_kwargs( + atlas_lens_id=atlas_lens_id, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_list.py b/src/roe/_generated/api/knowledge_base/knowledge_base_list.py new file mode 100644 index 0000000..667e065 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_list.py @@ -0,0 +1,214 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.paginated_knowledge_base_list import PaginatedKnowledgeBaseList +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + *, + page: int | Unset = UNSET, + page_size: int | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + + + + + params: dict[str, Any] = {} + + params["page"] = page + + params["page_size"] = page_size + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "/v1/knowledge-base/", + "params": params, + } + + + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> PaginatedKnowledgeBaseList | None: + if response.status_code == 200: + response_200 = PaginatedKnowledgeBaseList.from_dict(response.json()) + + + + return response_200 + + 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[PaginatedKnowledgeBaseList]: + 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, + page: int | Unset = UNSET, + page_size: int | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[PaginatedKnowledgeBaseList]: + """ List all KBs for the org, or start a new draft. + + Args: + page (int | Unset): + page_size (int | Unset): + organization_id (UUID | 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[PaginatedKnowledgeBaseList] + """ + + + kwargs = _get_kwargs( + page=page, +page_size=page_size, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + *, + client: AuthenticatedClient, + page: int | Unset = UNSET, + page_size: int | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> PaginatedKnowledgeBaseList | None: + """ List all KBs for the org, or start a new draft. + + Args: + page (int | Unset): + page_size (int | Unset): + organization_id (UUID | 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: + PaginatedKnowledgeBaseList + """ + + + return sync_detailed( + client=client, +page=page, +page_size=page_size, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + *, + client: AuthenticatedClient, + page: int | Unset = UNSET, + page_size: int | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[PaginatedKnowledgeBaseList]: + """ List all KBs for the org, or start a new draft. + + Args: + page (int | Unset): + page_size (int | Unset): + organization_id (UUID | 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[PaginatedKnowledgeBaseList] + """ + + + kwargs = _get_kwargs( + page=page, +page_size=page_size, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + *, + client: AuthenticatedClient, + page: int | Unset = UNSET, + page_size: int | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> PaginatedKnowledgeBaseList | None: + """ List all KBs for the org, or start a new draft. + + Args: + page (int | Unset): + page_size (int | Unset): + organization_id (UUID | 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: + PaginatedKnowledgeBaseList + """ + + + return (await asyncio_detailed( + client=client, +page=page, +page_size=page_size, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_regenerate_create.py b/src/roe/_generated/api/knowledge_base/knowledge_base_regenerate_create.py new file mode 100644 index 0000000..5551a15 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_regenerate_create.py @@ -0,0 +1,223 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.draft import Draft +from ...models.regenerate_request import RegenerateRequest +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + id: UUID, + *, + body: RegenerateRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "post", + "url": "/v1/knowledge-base/{id}/regenerate/".format(id=quote(str(id), safe=""),), + "params": params, + } + + + if not isinstance(body, Unset): + _kwargs["json"] = body.to_dict() + + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Draft | None: + if response.status_code == 202: + response_202 = Draft.from_dict(response.json()) + + + + return response_202 + + 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[Draft]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: UUID, + *, + client: AuthenticatedClient, + body: RegenerateRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[Draft]: + """ Kick off another async generation round with feedback. + Operation sync: propagate atlas errors; finally reconcile. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (RegenerateRequest | Unset): Body for POST /knowledge-base//regenerate/. + + 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[Draft] + """ + + + kwargs = _get_kwargs( + id=id, +body=body, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + id: UUID, + *, + client: AuthenticatedClient, + body: RegenerateRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Draft | None: + """ Kick off another async generation round with feedback. + Operation sync: propagate atlas errors; finally reconcile. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (RegenerateRequest | Unset): Body for POST /knowledge-base//regenerate/. + + 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: + Draft + """ + + + return sync_detailed( + id=id, +client=client, +body=body, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + id: UUID, + *, + client: AuthenticatedClient, + body: RegenerateRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[Draft]: + """ Kick off another async generation round with feedback. + Operation sync: propagate atlas errors; finally reconcile. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (RegenerateRequest | Unset): Body for POST /knowledge-base//regenerate/. + + 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[Draft] + """ + + + kwargs = _get_kwargs( + id=id, +body=body, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + id: UUID, + *, + client: AuthenticatedClient, + body: RegenerateRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Draft | None: + """ Kick off another async generation round with feedback. + Operation sync: propagate atlas errors; finally reconcile. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (RegenerateRequest | Unset): Body for POST /knowledge-base//regenerate/. + + 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: + Draft + """ + + + return (await asyncio_detailed( + id=id, +client=client, +body=body, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_resolve_create.py b/src/roe/_generated/api/knowledge_base/knowledge_base_resolve_create.py new file mode 100644 index 0000000..ceae0a3 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_resolve_create.py @@ -0,0 +1,267 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.draft import Draft +from ...models.resolve_request import ResolveRequest +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + id: UUID, + *, + body: ResolveRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "post", + "url": "/v1/knowledge-base/{id}/resolve/".format(id=quote(str(id), safe=""),), + "params": params, + } + + + if not isinstance(body, Unset): + _kwargs["json"] = body.to_dict() + + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Draft | None: + if response.status_code == 200: + response_200 = Draft.from_dict(response.json()) + + + + return response_200 + + 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[Draft]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: UUID, + *, + client: AuthenticatedClient, + body: ResolveRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[Draft]: + """ Approve or decline a pending regeneration proposal. + + A regeneration round lands as draft.pendingProposal WITHOUT changing the + agreed selection. The reviewer resolves it here: + - apply: { refs, suggested_name?, accept_summary? } — refs is the + resolved selection (per-item accept/reject computed client-side). + - decline: { discard: true } — keep the prior selection untouched. + + finalize is blocked by atlas (409) until this is called. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (ResolveRequest | Unset): Body for POST /knowledge-base//resolve/. + + discard=True declines the pending proposal. Otherwise refs is the reviewer's + resolved selection (opaque-handle dicts) and suggested_name / accept_summary + optionally adopt the proposal's name / summary. + + 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[Draft] + """ + + + kwargs = _get_kwargs( + id=id, +body=body, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + id: UUID, + *, + client: AuthenticatedClient, + body: ResolveRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Draft | None: + """ Approve or decline a pending regeneration proposal. + + A regeneration round lands as draft.pendingProposal WITHOUT changing the + agreed selection. The reviewer resolves it here: + - apply: { refs, suggested_name?, accept_summary? } — refs is the + resolved selection (per-item accept/reject computed client-side). + - decline: { discard: true } — keep the prior selection untouched. + + finalize is blocked by atlas (409) until this is called. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (ResolveRequest | Unset): Body for POST /knowledge-base//resolve/. + + discard=True declines the pending proposal. Otherwise refs is the reviewer's + resolved selection (opaque-handle dicts) and suggested_name / accept_summary + optionally adopt the proposal's name / summary. + + 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: + Draft + """ + + + return sync_detailed( + id=id, +client=client, +body=body, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + id: UUID, + *, + client: AuthenticatedClient, + body: ResolveRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[Draft]: + """ Approve or decline a pending regeneration proposal. + + A regeneration round lands as draft.pendingProposal WITHOUT changing the + agreed selection. The reviewer resolves it here: + - apply: { refs, suggested_name?, accept_summary? } — refs is the + resolved selection (per-item accept/reject computed client-side). + - decline: { discard: true } — keep the prior selection untouched. + + finalize is blocked by atlas (409) until this is called. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (ResolveRequest | Unset): Body for POST /knowledge-base//resolve/. + + discard=True declines the pending proposal. Otherwise refs is the reviewer's + resolved selection (opaque-handle dicts) and suggested_name / accept_summary + optionally adopt the proposal's name / summary. + + 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[Draft] + """ + + + kwargs = _get_kwargs( + id=id, +body=body, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + id: UUID, + *, + client: AuthenticatedClient, + body: ResolveRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Draft | None: + """ Approve or decline a pending regeneration proposal. + + A regeneration round lands as draft.pendingProposal WITHOUT changing the + agreed selection. The reviewer resolves it here: + - apply: { refs, suggested_name?, accept_summary? } — refs is the + resolved selection (per-item accept/reject computed client-side). + - decline: { discard: true } — keep the prior selection untouched. + + finalize is blocked by atlas (409) until this is called. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (ResolveRequest | Unset): Body for POST /knowledge-base//resolve/. + + discard=True declines the pending proposal. Otherwise refs is the reviewer's + resolved selection (opaque-handle dicts) and suggested_name / accept_summary + optionally adopt the proposal's name / summary. + + 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: + Draft + """ + + + return (await asyncio_detailed( + id=id, +client=client, +body=body, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_retrieve.py b/src/roe/_generated/api/knowledge_base/knowledge_base_retrieve.py new file mode 100644 index 0000000..bd61357 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_retrieve.py @@ -0,0 +1,197 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.knowledge_base import KnowledgeBase +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + id: UUID, + *, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "/v1/knowledge-base/{id}/".format(id=quote(str(id), safe=""),), + "params": params, + } + + + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> KnowledgeBase | None: + if response.status_code == 200: + response_200 = KnowledgeBase.from_dict(response.json()) + + + + return response_200 + + 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[KnowledgeBase]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[KnowledgeBase]: + """ Get or delete a single KB. GET triggers a best-effort display sync. + + Args: + id (UUID): + organization_id (UUID | 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[KnowledgeBase] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> KnowledgeBase | None: + """ Get or delete a single KB. GET triggers a best-effort display sync. + + Args: + id (UUID): + organization_id (UUID | 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: + KnowledgeBase + """ + + + return sync_detailed( + id=id, +client=client, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[KnowledgeBase]: + """ Get or delete a single KB. GET triggers a best-effort display sync. + + Args: + id (UUID): + organization_id (UUID | 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[KnowledgeBase] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> KnowledgeBase | None: + """ Get or delete a single KB. GET triggers a best-effort display sync. + + Args: + id (UUID): + organization_id (UUID | 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: + KnowledgeBase + """ + + + return (await asyncio_detailed( + id=id, +client=client, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_selection_partial_update.py b/src/roe/_generated/api/knowledge_base/knowledge_base_selection_partial_update.py new file mode 100644 index 0000000..9a8e348 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_selection_partial_update.py @@ -0,0 +1,231 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.draft import Draft +from ...models.patched_patch_selection_request import PatchedPatchSelectionRequest +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + id: UUID, + *, + body: PatchedPatchSelectionRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "patch", + "url": "/v1/knowledge-base/{id}/selection/".format(id=quote(str(id), safe=""),), + "params": params, + } + + + if not isinstance(body, Unset): + _kwargs["json"] = body.to_dict() + + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Draft | None: + if response.status_code == 200: + response_200 = Draft.from_dict(response.json()) + + + + return response_200 + + 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[Draft]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: UUID, + *, + client: AuthenticatedClient, + body: PatchedPatchSelectionRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[Draft]: + """ Persist hand-edits to the working selection (typology + tactic opt-in/out). + Operation sync: if atlas rejects, the error propagates; reconciling sync + runs in finally. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (PatchedPatchSelectionRequest | Unset): Body for PATCH /knowledge- + base//selection/. + + 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[Draft] + """ + + + kwargs = _get_kwargs( + id=id, +body=body, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + id: UUID, + *, + client: AuthenticatedClient, + body: PatchedPatchSelectionRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Draft | None: + """ Persist hand-edits to the working selection (typology + tactic opt-in/out). + Operation sync: if atlas rejects, the error propagates; reconciling sync + runs in finally. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (PatchedPatchSelectionRequest | Unset): Body for PATCH /knowledge- + base//selection/. + + 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: + Draft + """ + + + return sync_detailed( + id=id, +client=client, +body=body, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + id: UUID, + *, + client: AuthenticatedClient, + body: PatchedPatchSelectionRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Response[Draft]: + """ Persist hand-edits to the working selection (typology + tactic opt-in/out). + Operation sync: if atlas rejects, the error propagates; reconciling sync + runs in finally. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (PatchedPatchSelectionRequest | Unset): Body for PATCH /knowledge- + base//selection/. + + 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[Draft] + """ + + + kwargs = _get_kwargs( + id=id, +body=body, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + id: UUID, + *, + client: AuthenticatedClient, + body: PatchedPatchSelectionRequest | Unset = UNSET, + organization_id: UUID | Unset = UNSET, + +) -> Draft | None: + """ Persist hand-edits to the working selection (typology + tactic opt-in/out). + Operation sync: if atlas rejects, the error propagates; reconciling sync + runs in finally. + + Args: + id (UUID): + organization_id (UUID | Unset): + body (PatchedPatchSelectionRequest | Unset): Body for PATCH /knowledge- + base//selection/. + + 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: + Draft + """ + + + return (await asyncio_detailed( + id=id, +client=client, +body=body, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_sync_create.py b/src/roe/_generated/api/knowledge_base/knowledge_base_sync_create.py new file mode 100644 index 0000000..0afcba9 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_sync_create.py @@ -0,0 +1,205 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...models.knowledge_base import KnowledgeBase +from ...types import UNSET, Unset +from typing import cast +from uuid import UUID + + + +def _get_kwargs( + id: UUID, + *, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "post", + "url": "/v1/knowledge-base/{id}/sync/".format(id=quote(str(id), safe=""),), + "params": params, + } + + + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> KnowledgeBase | None: + if response.status_code == 200: + response_200 = KnowledgeBase.from_dict(response.json()) + + + + return response_200 + + 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[KnowledgeBase]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[KnowledgeBase]: + """ Standalone best-effort lens sync (display mode). + POST /knowledge-base//sync/ + Always returns 200; sync_error describes any failure. + + Args: + id (UUID): + organization_id (UUID | 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[KnowledgeBase] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> KnowledgeBase | None: + """ Standalone best-effort lens sync (display mode). + POST /knowledge-base//sync/ + Always returns 200; sync_error describes any failure. + + Args: + id (UUID): + organization_id (UUID | 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: + KnowledgeBase + """ + + + return sync_detailed( + id=id, +client=client, +organization_id=organization_id, + + ).parsed + +async def asyncio_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[KnowledgeBase]: + """ Standalone best-effort lens sync (display mode). + POST /knowledge-base//sync/ + Always returns 200; sync_error describes any failure. + + Args: + id (UUID): + organization_id (UUID | 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[KnowledgeBase] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> KnowledgeBase | None: + """ Standalone best-effort lens sync (display mode). + POST /knowledge-base//sync/ + Always returns 200; sync_error describes any failure. + + Args: + id (UUID): + organization_id (UUID | 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: + KnowledgeBase + """ + + + return (await asyncio_detailed( + id=id, +client=client, +organization_id=organization_id, + + )).parsed diff --git a/src/roe/_generated/api/knowledge_base/knowledge_base_unlink_destroy.py b/src/roe/_generated/api/knowledge_base/knowledge_base_unlink_destroy.py new file mode 100644 index 0000000..db1c796 --- /dev/null +++ b/src/roe/_generated/api/knowledge_base/knowledge_base_unlink_destroy.py @@ -0,0 +1,151 @@ +from http import HTTPStatus +from typing import Any, cast +from urllib.parse import quote + +import httpx + +from ...client import AuthenticatedClient, Client +from ...types import Response, UNSET +from ... import errors + +from ...types import UNSET, Unset +from uuid import UUID + + + +def _get_kwargs( + id: UUID, + *, + organization_id: UUID | Unset = UNSET, + +) -> dict[str, Any]: + + + + + params: dict[str, Any] = {} + + json_organization_id: str | Unset = UNSET + if not isinstance(organization_id, Unset): + json_organization_id = str(organization_id) + params["organization_id"] = json_organization_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": "delete", + "url": "/v1/knowledge-base/{id}/unlink/".format(id=quote(str(id), safe=""),), + "params": params, + } + + + return _kwargs + + + +def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Any | None: + if response.status_code == 204: + return None + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[Any]: + """ Unlink a knowledge base: remove the local KnowledgeBase row only, leaving + the Atlas lens (and any in-progress draft) untouched. + + This is the non-destructive counterpart to DELETE //. Use it to stop + tracking a lens in this org without deleting it from Atlas — e.g. the lens + is shared, or you intend to re-import it later via import-lens. Unlike + DELETE //, this never calls atlas.delete_draft / atlas.delete_lens. + + DELETE /knowledge-base//unlink/ + + Args: + id (UUID): + organization_id (UUID | 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[Any] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + id: UUID, + *, + client: AuthenticatedClient, + organization_id: UUID | Unset = UNSET, + +) -> Response[Any]: + """ Unlink a knowledge base: remove the local KnowledgeBase row only, leaving + the Atlas lens (and any in-progress draft) untouched. + + This is the non-destructive counterpart to DELETE //. Use it to stop + tracking a lens in this org without deleting it from Atlas — e.g. the lens + is shared, or you intend to re-import it later via import-lens. Unlike + DELETE //, this never calls atlas.delete_draft / atlas.delete_lens. + + DELETE /knowledge-base//unlink/ + + Args: + id (UUID): + organization_id (UUID | 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[Any] + """ + + + kwargs = _get_kwargs( + id=id, +organization_id=organization_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + diff --git a/src/roe/_generated/models/__init__.py b/src/roe/_generated/models/__init__.py index 64f8a46..6c1df3d 100644 --- a/src/roe/_generated/models/__init__.py +++ b/src/roe/_generated/models/__init__.py @@ -6,6 +6,8 @@ from .agent_execution_request import AgentExecutionRequest from .agent_execution_request_metadata_type_0 import AgentExecutionRequestMetadataType0 from .agent_input_definition import AgentInputDefinition +from .agent_job_artifact_result import AgentJobArtifactResult +from .agent_job_cancel_all_response import AgentJobCancelAllResponse from .agent_job_delete_data_response import AgentJobDeleteDataResponse from .agent_job_result_item import AgentJobResultItem from .agent_job_result_many_request import AgentJobResultManyRequest @@ -61,26 +63,39 @@ from .create_connection_request import CreateConnectionRequest from .create_connection_request_auth_config import CreateConnectionRequestAuthConfig from .create_connection_request_config import CreateConnectionRequestConfig +from .create_knowledge_base import CreateKnowledgeBase +from .create_knowledge_base_request import CreateKnowledgeBaseRequest from .create_policy import CreatePolicy from .create_policy_request import CreatePolicyRequest from .create_policy_version import CreatePolicyVersion from .create_policy_version_request import CreatePolicyVersionRequest from .dependent_agent_info import DependentAgentInfo from .discovery_supported_models_list_response_400 import DiscoverySupportedModelsListResponse400 +from .draft import Draft +from .draft_ref import DraftRef +from .draft_status_enum import DraftStatusEnum from .duplicate_connection_existing import DuplicateConnectionExisting from .duplicate_connection_response import DuplicateConnectionResponse from .error_detail_response import ErrorDetailResponse +from .finalize_request import FinalizeRequest +from .knowledge_base import KnowledgeBase +from .knowledge_base_import_lens_create_body import KnowledgeBaseImportLensCreateBody +from .knowledge_base_status_enum import KnowledgeBaseStatusEnum from .message_response import MessageResponse from .paginated_base_agent_list import PaginatedBaseAgentList from .paginated_connection_list_list import PaginatedConnectionListList +from .paginated_knowledge_base_list import PaginatedKnowledgeBaseList from .paginated_policy_list import PaginatedPolicyList from .paginated_policy_version_list import PaginatedPolicyVersionList from .patched_agent_version_update_request import PatchedAgentVersionUpdateRequest from .patched_base_agent_update_request import PatchedBaseAgentUpdateRequest +from .patched_patch_selection_request import PatchedPatchSelectionRequest +from .patched_patch_selection_request_refs_item import PatchedPatchSelectionRequestRefsItem from .patched_update_connection_request import PatchedUpdateConnectionRequest from .patched_update_connection_request_auth_config import PatchedUpdateConnectionRequestAuthConfig from .patched_update_connection_request_config import PatchedUpdateConnectionRequestConfig from .patched_update_policy_request import PatchedUpdatePolicyRequest +from .pending_proposal import PendingProposal from .policies_create_response_400 import PoliciesCreateResponse400 from .policies_partial_update_response_400 import PoliciesPartialUpdateResponse400 from .policies_update_response_400 import PoliciesUpdateResponse400 @@ -90,6 +105,10 @@ from .policy_version import PolicyVersion from .policy_version_created_by import PolicyVersionCreatedBy from .qdrant_cleanup_error_response import QdrantCleanupErrorResponse +from .regenerate_request import RegenerateRequest +from .relevance_enum import RelevanceEnum +from .resolve_request import ResolveRequest +from .resolve_request_refs_item import ResolveRequestRefsItem from .status_enum import StatusEnum from .supported_llm_model import SupportedLLMModel from .supported_llm_model_list import SupportedLLMModelList @@ -131,6 +150,8 @@ "AgentExecutionRequest", "AgentExecutionRequestMetadataType0", "AgentInputDefinition", + "AgentJobArtifactResult", + "AgentJobCancelAllResponse", "AgentJobDeleteDataResponse", "AgentJobResultItem", "AgentJobResultManyRequest", @@ -186,26 +207,39 @@ "CreateConnectionRequest", "CreateConnectionRequestAuthConfig", "CreateConnectionRequestConfig", + "CreateKnowledgeBase", + "CreateKnowledgeBaseRequest", "CreatePolicy", "CreatePolicyRequest", "CreatePolicyVersion", "CreatePolicyVersionRequest", "DependentAgentInfo", "DiscoverySupportedModelsListResponse400", + "Draft", + "DraftRef", + "DraftStatusEnum", "DuplicateConnectionExisting", "DuplicateConnectionResponse", "ErrorDetailResponse", + "FinalizeRequest", + "KnowledgeBase", + "KnowledgeBaseImportLensCreateBody", + "KnowledgeBaseStatusEnum", "MessageResponse", "PaginatedBaseAgentList", "PaginatedConnectionListList", + "PaginatedKnowledgeBaseList", "PaginatedPolicyList", "PaginatedPolicyVersionList", "PatchedAgentVersionUpdateRequest", "PatchedBaseAgentUpdateRequest", + "PatchedPatchSelectionRequest", + "PatchedPatchSelectionRequestRefsItem", "PatchedUpdateConnectionRequest", "PatchedUpdateConnectionRequestAuthConfig", "PatchedUpdateConnectionRequestConfig", "PatchedUpdatePolicyRequest", + "PendingProposal", "PoliciesCreateResponse400", "PoliciesPartialUpdateResponse400", "PoliciesUpdateResponse400", @@ -215,6 +249,10 @@ "PolicyVersion", "PolicyVersionCreatedBy", "QdrantCleanupErrorResponse", + "RegenerateRequest", + "RelevanceEnum", + "ResolveRequest", + "ResolveRequestRefsItem", "StatusEnum", "SupportedLLMModel", "SupportedLLMModelList", diff --git a/src/roe/_generated/models/agent_job_artifact_result.py b/src/roe/_generated/models/agent_job_artifact_result.py new file mode 100644 index 0000000..cfaf08c --- /dev/null +++ b/src/roe/_generated/models/agent_job_artifact_result.py @@ -0,0 +1,84 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from typing import cast + + + + + + +T = TypeVar("T", bound="AgentJobArtifactResult") + + + +@_attrs_define +class AgentJobArtifactResult: + """ + Attributes: + result (Any | None): The artifact's result content (any JSON value). + """ + + result: Any | None + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + result: Any | None + result = self.result + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "result": result, + }) + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + def _parse_result(data: object) -> Any | None: + if data is None: + return data + return cast(Any | None, data) + + result = _parse_result(d.pop("result")) + + + agent_job_artifact_result = cls( + result=result, + ) + + + agent_job_artifact_result.additional_properties = d + return agent_job_artifact_result + + @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/src/roe/_generated/models/agent_job_cancel_all_response.py b/src/roe/_generated/models/agent_job_cancel_all_response.py new file mode 100644 index 0000000..6922682 --- /dev/null +++ b/src/roe/_generated/models/agent_job_cancel_all_response.py @@ -0,0 +1,100 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from typing import cast + + + + + + +T = TypeVar("T", bound="AgentJobCancelAllResponse") + + + +@_attrs_define +class AgentJobCancelAllResponse: + """ + Attributes: + task_id (None | str): + targeted_count (int): + note (str): + """ + + task_id: None | str + targeted_count: int + note: str + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + task_id: None | str + task_id = self.task_id + + targeted_count = self.targeted_count + + note = self.note + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "task_id": task_id, + "targeted_count": targeted_count, + "note": note, + }) + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + def _parse_task_id(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + task_id = _parse_task_id(d.pop("task_id")) + + + targeted_count = d.pop("targeted_count") + + note = d.pop("note") + + agent_job_cancel_all_response = cls( + task_id=task_id, + targeted_count=targeted_count, + note=note, + ) + + + agent_job_cancel_all_response.additional_properties = d + return agent_job_cancel_all_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/src/roe/_generated/models/base_agent.py b/src/roe/_generated/models/base_agent.py index b563b3e..c0a6787 100644 --- a/src/roe/_generated/models/base_agent.py +++ b/src/roe/_generated/models/base_agent.py @@ -39,7 +39,9 @@ class BaseAgent: organization_id (UUID): Organization ID that owns this agent. engine_class_id (str): current_version_id (UUID): UUID of the current agent version. - job_count (int | None): Job count from annotation, or None when not fetched (use /agents/job-stats/). + job_count (int | None): Served job count: cached baseline + live delta, annotated by the views + as ``job_count``. ``None`` when stats weren't fetched (the list can be + requested with ``include_job_stats=false``; use /agents/job-stats/). most_recent_job (datetime.datetime | None): engine_name (str): Engine Display Name tags (list[AgentTag]): diff --git a/src/roe/_generated/models/connector_type_enum.py b/src/roe/_generated/models/connector_type_enum.py index d1e2a52..c5b4bc1 100644 --- a/src/roe/_generated/models/connector_type_enum.py +++ b/src/roe/_generated/models/connector_type_enum.py @@ -4,7 +4,9 @@ class ConnectorTypeEnum(str, Enum): CHECKOUT_COM = "checkout_com" CUSTOM_API = "custom_api" CUSTOM_MCP = "custom_mcp" + GOOGLE_DOCS = "google_docs" GOOGLE_DRIVE = "google_drive" + GOOGLE_SHEETS = "google_sheets" INTERCOM = "intercom" LEXIS_NEXIS = "lexis_nexis" PLAID = "plaid" diff --git a/src/roe/_generated/models/create_connection_request.py b/src/roe/_generated/models/create_connection_request.py index bfc68c5..754631e 100644 --- a/src/roe/_generated/models/create_connection_request.py +++ b/src/roe/_generated/models/create_connection_request.py @@ -36,6 +36,8 @@ class CreateConnectionRequest: * `sharepoint` - SHAREPOINT * `zendesk` - ZENDESK * `google_drive` - GOOGLE_DRIVE + * `google_docs` - GOOGLE_DOCS + * `google_sheets` - GOOGLE_SHEETS * `salesforce` - SALESFORCE * `web_application` - WEB_APPLICATION * `custom_api` - CUSTOM_API diff --git a/src/roe/_generated/models/create_knowledge_base.py b/src/roe/_generated/models/create_knowledge_base.py new file mode 100644 index 0000000..5edeb97 --- /dev/null +++ b/src/roe/_generated/models/create_knowledge_base.py @@ -0,0 +1,113 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset + + + + + + +T = TypeVar("T", bound="CreateKnowledgeBase") + + + +@_attrs_define +class CreateKnowledgeBase: + """ Body for POST /knowledge-base/ — starts a new draft. + + Attributes: + company (str): + brief (str): + name (str | Unset): + product_name (str | Unset): + website_url (str | Unset): + """ + + company: str + brief: str + name: str | Unset = UNSET + product_name: str | Unset = UNSET + website_url: str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + company = self.company + + brief = self.brief + + name = self.name + + product_name = self.product_name + + website_url = self.website_url + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "company": company, + "brief": brief, + }) + if name is not UNSET: + field_dict["name"] = name + if product_name is not UNSET: + field_dict["product_name"] = product_name + if website_url is not UNSET: + field_dict["website_url"] = website_url + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + company = d.pop("company") + + brief = d.pop("brief") + + name = d.pop("name", UNSET) + + product_name = d.pop("product_name", UNSET) + + website_url = d.pop("website_url", UNSET) + + create_knowledge_base = cls( + company=company, + brief=brief, + name=name, + product_name=product_name, + website_url=website_url, + ) + + + create_knowledge_base.additional_properties = d + return create_knowledge_base + + @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/src/roe/_generated/models/create_knowledge_base_request.py b/src/roe/_generated/models/create_knowledge_base_request.py new file mode 100644 index 0000000..c76acb3 --- /dev/null +++ b/src/roe/_generated/models/create_knowledge_base_request.py @@ -0,0 +1,113 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset + + + + + + +T = TypeVar("T", bound="CreateKnowledgeBaseRequest") + + + +@_attrs_define +class CreateKnowledgeBaseRequest: + """ Body for POST /knowledge-base/ — starts a new draft. + + Attributes: + company (str): + brief (str): + name (str | Unset): + product_name (str | Unset): + website_url (str | Unset): + """ + + company: str + brief: str + name: str | Unset = UNSET + product_name: str | Unset = UNSET + website_url: str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + company = self.company + + brief = self.brief + + name = self.name + + product_name = self.product_name + + website_url = self.website_url + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "company": company, + "brief": brief, + }) + if name is not UNSET: + field_dict["name"] = name + if product_name is not UNSET: + field_dict["product_name"] = product_name + if website_url is not UNSET: + field_dict["website_url"] = website_url + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + company = d.pop("company") + + brief = d.pop("brief") + + name = d.pop("name", UNSET) + + product_name = d.pop("product_name", UNSET) + + website_url = d.pop("website_url", UNSET) + + create_knowledge_base_request = cls( + company=company, + brief=brief, + name=name, + product_name=product_name, + website_url=website_url, + ) + + + create_knowledge_base_request.additional_properties = d + return create_knowledge_base_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/src/roe/_generated/models/draft.py b/src/roe/_generated/models/draft.py new file mode 100644 index 0000000..8c8e31b --- /dev/null +++ b/src/roe/_generated/models/draft.py @@ -0,0 +1,270 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..models.draft_status_enum import DraftStatusEnum +from ..types import UNSET, Unset +from typing import cast + +if TYPE_CHECKING: + from ..models.draft_ref import DraftRef + from ..models.pending_proposal import PendingProposal + + + + + +T = TypeVar("T", bound="Draft") + + + +@_attrs_define +class Draft: + """ Projected atlas draft returned from poll/regenerate/resolve endpoints. + + Attributes: + id (str): + status (DraftStatusEnum): * `generating` - generating + * `ready` - ready + * `error` - error + company (str): + suggested_name (str): + product_summary (str): + iteration_count (int): + refs (list[DraftRef]): + error (None | str | Unset): + product_name (None | str | Unset): + pending_proposal (None | PendingProposal | Unset): + created_at (None | str | Unset): + updated_at (None | str | Unset): + """ + + id: str + status: DraftStatusEnum + company: str + suggested_name: str + product_summary: str + iteration_count: int + refs: list[DraftRef] + error: None | str | Unset = UNSET + product_name: None | str | Unset = UNSET + pending_proposal: None | PendingProposal | Unset = UNSET + created_at: None | str | Unset = UNSET + updated_at: None | str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + from ..models.draft_ref import DraftRef + from ..models.pending_proposal import PendingProposal + id = self.id + + status = self.status.value + + company = self.company + + suggested_name = self.suggested_name + + product_summary = self.product_summary + + iteration_count = self.iteration_count + + refs = [] + for refs_item_data in self.refs: + refs_item = refs_item_data.to_dict() + refs.append(refs_item) + + + + error: None | str | Unset + if isinstance(self.error, Unset): + error = UNSET + else: + error = self.error + + product_name: None | str | Unset + if isinstance(self.product_name, Unset): + product_name = UNSET + else: + product_name = self.product_name + + pending_proposal: dict[str, Any] | None | Unset + if isinstance(self.pending_proposal, Unset): + pending_proposal = UNSET + elif isinstance(self.pending_proposal, PendingProposal): + pending_proposal = self.pending_proposal.to_dict() + else: + pending_proposal = self.pending_proposal + + created_at: None | str | Unset + if isinstance(self.created_at, Unset): + created_at = UNSET + else: + created_at = self.created_at + + updated_at: None | str | Unset + if isinstance(self.updated_at, Unset): + updated_at = UNSET + else: + updated_at = self.updated_at + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "id": id, + "status": status, + "company": company, + "suggestedName": suggested_name, + "productSummary": product_summary, + "iterationCount": iteration_count, + "refs": refs, + }) + if error is not UNSET: + field_dict["error"] = error + if product_name is not UNSET: + field_dict["productName"] = product_name + if pending_proposal is not UNSET: + field_dict["pendingProposal"] = pending_proposal + if created_at is not UNSET: + field_dict["createdAt"] = created_at + if updated_at is not UNSET: + field_dict["updatedAt"] = updated_at + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.draft_ref import DraftRef + from ..models.pending_proposal import PendingProposal + d = dict(src_dict) + id = d.pop("id") + + status = DraftStatusEnum(d.pop("status")) + + + + + company = d.pop("company") + + suggested_name = d.pop("suggestedName") + + product_summary = d.pop("productSummary") + + iteration_count = d.pop("iterationCount") + + refs = [] + _refs = d.pop("refs") + for refs_item_data in (_refs): + refs_item = DraftRef.from_dict(refs_item_data) + + + + refs.append(refs_item) + + + def _parse_error(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + error = _parse_error(d.pop("error", UNSET)) + + + def _parse_product_name(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + product_name = _parse_product_name(d.pop("productName", UNSET)) + + + def _parse_pending_proposal(data: object) -> None | PendingProposal | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + pending_proposal_type_0 = PendingProposal.from_dict(data) + + + + return pending_proposal_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | PendingProposal | Unset, data) + + pending_proposal = _parse_pending_proposal(d.pop("pendingProposal", UNSET)) + + + def _parse_created_at(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + created_at = _parse_created_at(d.pop("createdAt", UNSET)) + + + def _parse_updated_at(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + updated_at = _parse_updated_at(d.pop("updatedAt", UNSET)) + + + draft = cls( + id=id, + status=status, + company=company, + suggested_name=suggested_name, + product_summary=product_summary, + iteration_count=iteration_count, + refs=refs, + error=error, + product_name=product_name, + pending_proposal=pending_proposal, + created_at=created_at, + updated_at=updated_at, + ) + + + draft.additional_properties = d + return draft + + @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/src/roe/_generated/models/draft_ref.py b/src/roe/_generated/models/draft_ref.py new file mode 100644 index 0000000..6be428d --- /dev/null +++ b/src/roe/_generated/models/draft_ref.py @@ -0,0 +1,186 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..models.relevance_enum import RelevanceEnum +from ..types import UNSET, Unset +from typing import cast + + + + + + +T = TypeVar("T", bound="DraftRef") + + + +@_attrs_define +class DraftRef: + """ A single ref in a selection (names-only projection from atlas). + + Attributes: + typology_id (str): + typology_name (str | Unset): + relevance (RelevanceEnum | Unset): * `core` - core + * `watch` - watch + * `edge` - edge Default: RelevanceEnum.WATCH. + rationale (str | Unset): + tactic_ids (list[str] | None | Unset): + tactic_names (list[str] | None | Unset): + """ + + typology_id: str + typology_name: str | Unset = UNSET + relevance: RelevanceEnum | Unset = RelevanceEnum.WATCH + rationale: str | Unset = UNSET + tactic_ids: list[str] | None | Unset = UNSET + tactic_names: list[str] | None | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + typology_id = self.typology_id + + typology_name = self.typology_name + + relevance: str | Unset = UNSET + if not isinstance(self.relevance, Unset): + relevance = self.relevance.value + + + rationale = self.rationale + + tactic_ids: list[str] | None | Unset + if isinstance(self.tactic_ids, Unset): + tactic_ids = UNSET + elif isinstance(self.tactic_ids, list): + tactic_ids = self.tactic_ids + + + else: + tactic_ids = self.tactic_ids + + tactic_names: list[str] | None | Unset + if isinstance(self.tactic_names, Unset): + tactic_names = UNSET + elif isinstance(self.tactic_names, list): + tactic_names = self.tactic_names + + + else: + tactic_names = self.tactic_names + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "typologyId": typology_id, + }) + if typology_name is not UNSET: + field_dict["typologyName"] = typology_name + if relevance is not UNSET: + field_dict["relevance"] = relevance + if rationale is not UNSET: + field_dict["rationale"] = rationale + if tactic_ids is not UNSET: + field_dict["tacticIds"] = tactic_ids + if tactic_names is not UNSET: + field_dict["tacticNames"] = tactic_names + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + typology_id = d.pop("typologyId") + + typology_name = d.pop("typologyName", UNSET) + + _relevance = d.pop("relevance", UNSET) + relevance: RelevanceEnum | Unset + if isinstance(_relevance, Unset): + relevance = UNSET + else: + relevance = RelevanceEnum(_relevance) + + + + + rationale = d.pop("rationale", UNSET) + + def _parse_tactic_ids(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() + tactic_ids_type_0 = cast(list[str], data) + + return tactic_ids_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + tactic_ids = _parse_tactic_ids(d.pop("tacticIds", UNSET)) + + + def _parse_tactic_names(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() + tactic_names_type_0 = cast(list[str], data) + + return tactic_names_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + tactic_names = _parse_tactic_names(d.pop("tacticNames", UNSET)) + + + draft_ref = cls( + typology_id=typology_id, + typology_name=typology_name, + relevance=relevance, + rationale=rationale, + tactic_ids=tactic_ids, + tactic_names=tactic_names, + ) + + + draft_ref.additional_properties = d + return draft_ref + + @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/src/roe/_generated/models/draft_status_enum.py b/src/roe/_generated/models/draft_status_enum.py new file mode 100644 index 0000000..55741a8 --- /dev/null +++ b/src/roe/_generated/models/draft_status_enum.py @@ -0,0 +1,9 @@ +from enum import Enum + +class DraftStatusEnum(str, Enum): + ERROR = "error" + GENERATING = "generating" + READY = "ready" + + def __str__(self) -> str: + return str(self.value) diff --git a/src/roe/_generated/models/finalize_request.py b/src/roe/_generated/models/finalize_request.py new file mode 100644 index 0000000..e3e039f --- /dev/null +++ b/src/roe/_generated/models/finalize_request.py @@ -0,0 +1,97 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset + + + + + + +T = TypeVar("T", bound="FinalizeRequest") + + + +@_attrs_define +class FinalizeRequest: + """ Body for POST /knowledge-base//finalize/. + + Attributes: + name (str | Unset): + mcp_enabled (bool | Unset): Default: True. + public (bool | Unset): Default: True. + """ + + name: str | Unset = UNSET + mcp_enabled: bool | Unset = True + public: bool | Unset = True + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + name = self.name + + mcp_enabled = self.mcp_enabled + + public = self.public + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + }) + if name is not UNSET: + field_dict["name"] = name + if mcp_enabled is not UNSET: + field_dict["mcp_enabled"] = mcp_enabled + if public is not UNSET: + field_dict["public"] = public + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + name = d.pop("name", UNSET) + + mcp_enabled = d.pop("mcp_enabled", UNSET) + + public = d.pop("public", UNSET) + + finalize_request = cls( + name=name, + mcp_enabled=mcp_enabled, + public=public, + ) + + + finalize_request.additional_properties = d + return finalize_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/src/roe/_generated/models/knowledge_base.py b/src/roe/_generated/models/knowledge_base.py new file mode 100644 index 0000000..f6d7cdc --- /dev/null +++ b/src/roe/_generated/models/knowledge_base.py @@ -0,0 +1,242 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..models.knowledge_base_status_enum import KnowledgeBaseStatusEnum +from dateutil.parser import isoparse +from typing import cast +from uuid import UUID +import datetime + + + + + + +T = TypeVar("T", bound="KnowledgeBase") + + + +@_attrs_define +class KnowledgeBase: + """ + Attributes: + id (UUID): + organization_id (UUID): + name (str): + company (str): + status (KnowledgeBaseStatusEnum): * `drafting` - Drafting + * `active` - Active + * `orphaned` - Orphaned + atlas_draft_id (None | str): + atlas_lens_id (None | str): + mcp_url (str): + lens_snapshot (Any | None): + last_synced_at (datetime.datetime | None): + sync_error (None | str): + created_at (datetime.datetime): + updated_at (datetime.datetime): + """ + + id: UUID + organization_id: UUID + name: str + company: str + status: KnowledgeBaseStatusEnum + atlas_draft_id: None | str + atlas_lens_id: None | str + mcp_url: str + lens_snapshot: Any | None + last_synced_at: datetime.datetime | None + sync_error: None | str + created_at: datetime.datetime + updated_at: datetime.datetime + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + id = str(self.id) + + organization_id = str(self.organization_id) + + name = self.name + + company = self.company + + status = self.status.value + + atlas_draft_id: None | str + atlas_draft_id = self.atlas_draft_id + + atlas_lens_id: None | str + atlas_lens_id = self.atlas_lens_id + + mcp_url = self.mcp_url + + lens_snapshot: Any | None + lens_snapshot = self.lens_snapshot + + last_synced_at: None | str + if isinstance(self.last_synced_at, datetime.datetime): + last_synced_at = self.last_synced_at.isoformat() + else: + last_synced_at = self.last_synced_at + + sync_error: None | str + sync_error = self.sync_error + + created_at = self.created_at.isoformat() + + updated_at = self.updated_at.isoformat() + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "id": id, + "organization_id": organization_id, + "name": name, + "company": company, + "status": status, + "atlas_draft_id": atlas_draft_id, + "atlas_lens_id": atlas_lens_id, + "mcp_url": mcp_url, + "lens_snapshot": lens_snapshot, + "last_synced_at": last_synced_at, + "sync_error": sync_error, + "created_at": created_at, + "updated_at": updated_at, + }) + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + id = UUID(d.pop("id")) + + + + + organization_id = UUID(d.pop("organization_id")) + + + + + name = d.pop("name") + + company = d.pop("company") + + status = KnowledgeBaseStatusEnum(d.pop("status")) + + + + + def _parse_atlas_draft_id(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + atlas_draft_id = _parse_atlas_draft_id(d.pop("atlas_draft_id")) + + + def _parse_atlas_lens_id(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + atlas_lens_id = _parse_atlas_lens_id(d.pop("atlas_lens_id")) + + + mcp_url = d.pop("mcp_url") + + def _parse_lens_snapshot(data: object) -> Any | None: + if data is None: + return data + return cast(Any | None, data) + + lens_snapshot = _parse_lens_snapshot(d.pop("lens_snapshot")) + + + def _parse_last_synced_at(data: object) -> datetime.datetime | None: + if data is None: + return data + try: + if not isinstance(data, str): + raise TypeError() + last_synced_at_type_0 = isoparse(data) + + + + return last_synced_at_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(datetime.datetime | None, data) + + last_synced_at = _parse_last_synced_at(d.pop("last_synced_at")) + + + def _parse_sync_error(data: object) -> None | str: + if data is None: + return data + return cast(None | str, data) + + sync_error = _parse_sync_error(d.pop("sync_error")) + + + created_at = isoparse(d.pop("created_at")) + + + + + updated_at = isoparse(d.pop("updated_at")) + + + + + knowledge_base = cls( + id=id, + organization_id=organization_id, + name=name, + company=company, + status=status, + atlas_draft_id=atlas_draft_id, + atlas_lens_id=atlas_lens_id, + mcp_url=mcp_url, + lens_snapshot=lens_snapshot, + last_synced_at=last_synced_at, + sync_error=sync_error, + created_at=created_at, + updated_at=updated_at, + ) + + + knowledge_base.additional_properties = d + return knowledge_base + + @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/src/roe/_generated/models/knowledge_base_import_lens_create_body.py b/src/roe/_generated/models/knowledge_base_import_lens_create_body.py new file mode 100644 index 0000000..ca86efe --- /dev/null +++ b/src/roe/_generated/models/knowledge_base_import_lens_create_body.py @@ -0,0 +1,65 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + + + + + + + +T = TypeVar("T", bound="KnowledgeBaseImportLensCreateBody") + + + +@_attrs_define +class KnowledgeBaseImportLensCreateBody: + """ + """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + knowledge_base_import_lens_create_body = cls( + ) + + + knowledge_base_import_lens_create_body.additional_properties = d + return knowledge_base_import_lens_create_body + + @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/src/roe/_generated/models/knowledge_base_status_enum.py b/src/roe/_generated/models/knowledge_base_status_enum.py new file mode 100644 index 0000000..2f9aa73 --- /dev/null +++ b/src/roe/_generated/models/knowledge_base_status_enum.py @@ -0,0 +1,9 @@ +from enum import Enum + +class KnowledgeBaseStatusEnum(str, Enum): + ACTIVE = "active" + DRAFTING = "drafting" + ORPHANED = "orphaned" + + def __str__(self) -> str: + return str(self.value) diff --git a/src/roe/_generated/models/paginated_knowledge_base_list.py b/src/roe/_generated/models/paginated_knowledge_base_list.py new file mode 100644 index 0000000..9f5d1dd --- /dev/null +++ b/src/roe/_generated/models/paginated_knowledge_base_list.py @@ -0,0 +1,145 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset +from typing import cast + +if TYPE_CHECKING: + from ..models.knowledge_base import KnowledgeBase + + + + + +T = TypeVar("T", bound="PaginatedKnowledgeBaseList") + + + +@_attrs_define +class PaginatedKnowledgeBaseList: + """ + Attributes: + count (int): Example: 123. + results (list[KnowledgeBase]): + next_ (None | str | Unset): Example: http://api.example.org/accounts/?page=4. + previous (None | str | Unset): Example: http://api.example.org/accounts/?page=2. + """ + + count: int + results: list[KnowledgeBase] + next_: None | str | Unset = UNSET + previous: None | str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + from ..models.knowledge_base import KnowledgeBase + count = self.count + + results = [] + for results_item_data in self.results: + results_item = results_item_data.to_dict() + results.append(results_item) + + + + next_: None | str | Unset + if isinstance(self.next_, Unset): + next_ = UNSET + else: + next_ = self.next_ + + previous: None | str | Unset + if isinstance(self.previous, Unset): + previous = UNSET + else: + previous = self.previous + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "count": count, + "results": results, + }) + if next_ is not UNSET: + field_dict["next"] = next_ + if previous is not UNSET: + field_dict["previous"] = previous + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.knowledge_base import KnowledgeBase + d = dict(src_dict) + count = d.pop("count") + + results = [] + _results = d.pop("results") + for results_item_data in (_results): + results_item = KnowledgeBase.from_dict(results_item_data) + + + + results.append(results_item) + + + def _parse_next_(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + next_ = _parse_next_(d.pop("next", UNSET)) + + + def _parse_previous(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + previous = _parse_previous(d.pop("previous", UNSET)) + + + paginated_knowledge_base_list = cls( + count=count, + results=results, + next_=next_, + previous=previous, + ) + + + paginated_knowledge_base_list.additional_properties = d + return paginated_knowledge_base_list + + @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/src/roe/_generated/models/patched_patch_selection_request.py b/src/roe/_generated/models/patched_patch_selection_request.py new file mode 100644 index 0000000..8d8f269 --- /dev/null +++ b/src/roe/_generated/models/patched_patch_selection_request.py @@ -0,0 +1,110 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset +from typing import cast + +if TYPE_CHECKING: + from ..models.patched_patch_selection_request_refs_item import PatchedPatchSelectionRequestRefsItem + + + + + +T = TypeVar("T", bound="PatchedPatchSelectionRequest") + + + +@_attrs_define +class PatchedPatchSelectionRequest: + """ Body for PATCH /knowledge-base//selection/. + + Attributes: + refs (list[PatchedPatchSelectionRequestRefsItem] | Unset): + suggested_name (str | Unset): + """ + + refs: list[PatchedPatchSelectionRequestRefsItem] | Unset = UNSET + suggested_name: str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + from ..models.patched_patch_selection_request_refs_item import PatchedPatchSelectionRequestRefsItem + refs: list[dict[str, Any]] | Unset = UNSET + if not isinstance(self.refs, Unset): + refs = [] + for refs_item_data in self.refs: + refs_item = refs_item_data.to_dict() + refs.append(refs_item) + + + + suggested_name = self.suggested_name + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + }) + if refs is not UNSET: + field_dict["refs"] = refs + if suggested_name is not UNSET: + field_dict["suggested_name"] = suggested_name + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.patched_patch_selection_request_refs_item import PatchedPatchSelectionRequestRefsItem + d = dict(src_dict) + _refs = d.pop("refs", UNSET) + refs: list[PatchedPatchSelectionRequestRefsItem] | Unset = UNSET + if _refs is not UNSET: + refs = [] + for refs_item_data in _refs: + refs_item = PatchedPatchSelectionRequestRefsItem.from_dict(refs_item_data) + + + + refs.append(refs_item) + + + suggested_name = d.pop("suggested_name", UNSET) + + patched_patch_selection_request = cls( + refs=refs, + suggested_name=suggested_name, + ) + + + patched_patch_selection_request.additional_properties = d + return patched_patch_selection_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/src/roe/_generated/models/patched_patch_selection_request_refs_item.py b/src/roe/_generated/models/patched_patch_selection_request_refs_item.py new file mode 100644 index 0000000..6a66e66 --- /dev/null +++ b/src/roe/_generated/models/patched_patch_selection_request_refs_item.py @@ -0,0 +1,65 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + + + + + + + +T = TypeVar("T", bound="PatchedPatchSelectionRequestRefsItem") + + + +@_attrs_define +class PatchedPatchSelectionRequestRefsItem: + """ + """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + patched_patch_selection_request_refs_item = cls( + ) + + + patched_patch_selection_request_refs_item.additional_properties = d + return patched_patch_selection_request_refs_item + + @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/src/roe/_generated/models/pending_proposal.py b/src/roe/_generated/models/pending_proposal.py new file mode 100644 index 0000000..34c5745 --- /dev/null +++ b/src/roe/_generated/models/pending_proposal.py @@ -0,0 +1,177 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset +from typing import cast + +if TYPE_CHECKING: + from ..models.draft_ref import DraftRef + + + + + +T = TypeVar("T", bound="PendingProposal") + + + +@_attrs_define +class PendingProposal: + """ A staged regeneration awaiting reviewer approval (names-only). + + Attributes: + refs (list[DraftRef]): + base_selection (list[DraftRef]): + feedback (None | str | Unset): + suggested_name (str | Unset): + product_summary (str | Unset): + created_at (None | str | Unset): + """ + + refs: list[DraftRef] + base_selection: list[DraftRef] + feedback: None | str | Unset = UNSET + suggested_name: str | Unset = UNSET + product_summary: str | Unset = UNSET + created_at: None | str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + from ..models.draft_ref import DraftRef + refs = [] + for refs_item_data in self.refs: + refs_item = refs_item_data.to_dict() + refs.append(refs_item) + + + + base_selection = [] + for base_selection_item_data in self.base_selection: + base_selection_item = base_selection_item_data.to_dict() + base_selection.append(base_selection_item) + + + + feedback: None | str | Unset + if isinstance(self.feedback, Unset): + feedback = UNSET + else: + feedback = self.feedback + + suggested_name = self.suggested_name + + product_summary = self.product_summary + + created_at: None | str | Unset + if isinstance(self.created_at, Unset): + created_at = UNSET + else: + created_at = self.created_at + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "refs": refs, + "baseSelection": base_selection, + }) + if feedback is not UNSET: + field_dict["feedback"] = feedback + if suggested_name is not UNSET: + field_dict["suggestedName"] = suggested_name + if product_summary is not UNSET: + field_dict["productSummary"] = product_summary + if created_at is not UNSET: + field_dict["createdAt"] = created_at + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.draft_ref import DraftRef + d = dict(src_dict) + refs = [] + _refs = d.pop("refs") + for refs_item_data in (_refs): + refs_item = DraftRef.from_dict(refs_item_data) + + + + refs.append(refs_item) + + + base_selection = [] + _base_selection = d.pop("baseSelection") + for base_selection_item_data in (_base_selection): + base_selection_item = DraftRef.from_dict(base_selection_item_data) + + + + base_selection.append(base_selection_item) + + + def _parse_feedback(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + feedback = _parse_feedback(d.pop("feedback", UNSET)) + + + suggested_name = d.pop("suggestedName", UNSET) + + product_summary = d.pop("productSummary", UNSET) + + def _parse_created_at(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + created_at = _parse_created_at(d.pop("createdAt", UNSET)) + + + pending_proposal = cls( + refs=refs, + base_selection=base_selection, + feedback=feedback, + suggested_name=suggested_name, + product_summary=product_summary, + created_at=created_at, + ) + + + pending_proposal.additional_properties = d + return pending_proposal + + @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/src/roe/_generated/models/regenerate_request.py b/src/roe/_generated/models/regenerate_request.py new file mode 100644 index 0000000..cd8e448 --- /dev/null +++ b/src/roe/_generated/models/regenerate_request.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset + + + + + + +T = TypeVar("T", bound="RegenerateRequest") + + + +@_attrs_define +class RegenerateRequest: + """ Body for POST /knowledge-base//regenerate/. + + Attributes: + feedback (str | Unset): + """ + + feedback: str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + feedback = self.feedback + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + }) + if feedback is not UNSET: + field_dict["feedback"] = feedback + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + feedback = d.pop("feedback", UNSET) + + regenerate_request = cls( + feedback=feedback, + ) + + + regenerate_request.additional_properties = d + return regenerate_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/src/roe/_generated/models/relevance_enum.py b/src/roe/_generated/models/relevance_enum.py new file mode 100644 index 0000000..c93a2ed --- /dev/null +++ b/src/roe/_generated/models/relevance_enum.py @@ -0,0 +1,9 @@ +from enum import Enum + +class RelevanceEnum(str, Enum): + CORE = "core" + EDGE = "edge" + WATCH = "watch" + + def __str__(self) -> str: + return str(self.value) diff --git a/src/roe/_generated/models/resolve_request.py b/src/roe/_generated/models/resolve_request.py new file mode 100644 index 0000000..f9fa72f --- /dev/null +++ b/src/roe/_generated/models/resolve_request.py @@ -0,0 +1,132 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset +from typing import cast + +if TYPE_CHECKING: + from ..models.resolve_request_refs_item import ResolveRequestRefsItem + + + + + +T = TypeVar("T", bound="ResolveRequest") + + + +@_attrs_define +class ResolveRequest: + """ Body for POST /knowledge-base//resolve/. + + discard=True declines the pending proposal. Otherwise refs is the reviewer's + resolved selection (opaque-handle dicts) and suggested_name / accept_summary + optionally adopt the proposal's name / summary. + + Attributes: + refs (list[ResolveRequestRefsItem] | Unset): + suggested_name (str | Unset): + accept_summary (bool | Unset): Default: False. + discard (bool | Unset): Default: False. + """ + + refs: list[ResolveRequestRefsItem] | Unset = UNSET + suggested_name: str | Unset = UNSET + accept_summary: bool | Unset = False + discard: bool | Unset = False + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + from ..models.resolve_request_refs_item import ResolveRequestRefsItem + refs: list[dict[str, Any]] | Unset = UNSET + if not isinstance(self.refs, Unset): + refs = [] + for refs_item_data in self.refs: + refs_item = refs_item_data.to_dict() + refs.append(refs_item) + + + + suggested_name = self.suggested_name + + accept_summary = self.accept_summary + + discard = self.discard + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + }) + if refs is not UNSET: + field_dict["refs"] = refs + if suggested_name is not UNSET: + field_dict["suggested_name"] = suggested_name + if accept_summary is not UNSET: + field_dict["accept_summary"] = accept_summary + if discard is not UNSET: + field_dict["discard"] = discard + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.resolve_request_refs_item import ResolveRequestRefsItem + d = dict(src_dict) + _refs = d.pop("refs", UNSET) + refs: list[ResolveRequestRefsItem] | Unset = UNSET + if _refs is not UNSET: + refs = [] + for refs_item_data in _refs: + refs_item = ResolveRequestRefsItem.from_dict(refs_item_data) + + + + refs.append(refs_item) + + + suggested_name = d.pop("suggested_name", UNSET) + + accept_summary = d.pop("accept_summary", UNSET) + + discard = d.pop("discard", UNSET) + + resolve_request = cls( + refs=refs, + suggested_name=suggested_name, + accept_summary=accept_summary, + discard=discard, + ) + + + resolve_request.additional_properties = d + return resolve_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/src/roe/_generated/models/resolve_request_refs_item.py b/src/roe/_generated/models/resolve_request_refs_item.py new file mode 100644 index 0000000..324f35b --- /dev/null +++ b/src/roe/_generated/models/resolve_request_refs_item.py @@ -0,0 +1,65 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + + + + + + + +T = TypeVar("T", bound="ResolveRequestRefsItem") + + + +@_attrs_define +class ResolveRequestRefsItem: + """ + """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + resolve_request_refs_item = cls( + ) + + + resolve_request_refs_item.additional_properties = d + return resolve_request_refs_item + + @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/src/roe/_generated/models/test_connection_credentials_request.py b/src/roe/_generated/models/test_connection_credentials_request.py index 116f8d4..ac23292 100644 --- a/src/roe/_generated/models/test_connection_credentials_request.py +++ b/src/roe/_generated/models/test_connection_credentials_request.py @@ -34,6 +34,8 @@ class TestConnectionCredentialsRequest: * `sharepoint` - SHAREPOINT * `zendesk` - ZENDESK * `google_drive` - GOOGLE_DRIVE + * `google_docs` - GOOGLE_DOCS + * `google_sheets` - GOOGLE_SHEETS * `salesforce` - SALESFORCE * `web_application` - WEB_APPLICATION * `custom_api` - CUSTOM_API diff --git a/uv.lock b/uv.lock index 65b3d72..7a329ce 100644 --- a/uv.lock +++ b/uv.lock @@ -79,7 +79,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -454,7 +454,7 @@ wheels = [ [[package]] name = "roe-ai" -version = "1.1.1" +version = "1.1.2" source = { editable = "." } dependencies = [ { name = "attrs" }, From 64ed38a7d23a26c6b836660a0ff3cc4c144fc31e Mon Sep 17 00:00:00 2001 From: Chen-ROE Date: Tue, 23 Jun 2026 11:46:42 -0700 Subject: [PATCH 2/5] fix(knowledge_base): add manual SDK wrapper and wire into client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Release 1-0-85 added a new `knowledge_base` namespace declared `kind: manual` in the SDK contract. The codegen intentionally skips manual namespaces, so the release bot generated the raw `_generated` client + models but left the friendly wrapper missing — `client.knowledge_base` did not exist. - Hand-write `KnowledgeBaseAPI` (src/roe/api/knowledge_base.py) modeled on the existing manual wrappers (policies/agents/users): thin facade over the raw client via `request_raw`, returning generated models, errors translated at the boundary. Covers all 13 contract operations. - Wire it explicitly in client.py (manual namespaces are not in the generated registry), matching agents/policies/users. - Add transport regression tests mirroring the other wrappers. - Sync the README release banner to v1.1.2 (clears check-codegen-drift). Co-Authored-By: Claude Opus 4.8 --- README.md | 2 +- src/roe/api/knowledge_base.py | 266 ++++++++++++++++++ src/roe/client.py | 24 ++ .../test_knowledge_base_wrapper_transport.py | 88 ++++++ 4 files changed, 379 insertions(+), 1 deletion(-) create mode 100644 src/roe/api/knowledge_base.py create mode 100644 tests/unit/test_knowledge_base_wrapper_transport.py diff --git a/README.md b/README.md index be3534a..0b94d96 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A Python SDK for the [Roe](https://www.roe-ai.com/) API. -> **v1.1.1** - SDK operation coverage is synchronized across Python, +> **v1.1.2** - SDK operation coverage is synchronized across Python, > TypeScript, and Go. See `SDK_EXAMPLES.md` for copy-ready examples and > use cases. diff --git a/src/roe/api/knowledge_base.py b/src/roe/api/knowledge_base.py new file mode 100644 index 0000000..a7d666d --- /dev/null +++ b/src/roe/api/knowledge_base.py @@ -0,0 +1,266 @@ +"""Knowledge Base API — thin facade over the generated raw client. + +Methods call the generated endpoint functions in +``roe._generated.api.knowledge_base`` and return the generated response models +directly. Non-2xx responses are translated to the typed ``RoeAPIException`` +family at the wrapper boundary. + +This is a hand-maintained ("manual") wrapper: the knowledge_base operations are +declared ``kind: manual`` in the SDK contract, so codegen does not generate this +module. It is wired explicitly in ``roe.client`` like agents/policies/users. +""" + +from __future__ import annotations + +from typing import Any +from uuid import UUID + +from roe._generated.api.knowledge_base import ( + knowledge_base_catalog_retrieve, + knowledge_base_create, + knowledge_base_destroy, + knowledge_base_draft_retrieve, + knowledge_base_finalize_create, + knowledge_base_import_lens_create, + knowledge_base_lens_retrieve, + knowledge_base_list, + knowledge_base_regenerate_create, + knowledge_base_resolve_create, + knowledge_base_retrieve, + knowledge_base_selection_partial_update, + knowledge_base_sync_create, +) +from roe._generated.client import AuthenticatedClient +from roe._generated.models.create_knowledge_base import CreateKnowledgeBase +from roe._generated.models.create_knowledge_base_request import ( + CreateKnowledgeBaseRequest, +) +from roe._generated.models.draft import Draft +from roe._generated.models.finalize_request import FinalizeRequest +from roe._generated.models.knowledge_base import KnowledgeBase +from roe._generated.models.knowledge_base_import_lens_create_body import ( + KnowledgeBaseImportLensCreateBody, +) +from roe._generated.models.paginated_knowledge_base_list import ( + PaginatedKnowledgeBaseList, +) +from roe._generated.models.patched_patch_selection_request import ( + PatchedPatchSelectionRequest, +) +from roe._generated.models.patched_patch_selection_request_refs_item import ( + PatchedPatchSelectionRequestRefsItem, +) +from roe._generated.models.regenerate_request import RegenerateRequest +from roe._generated.models.resolve_request import ResolveRequest +from roe._generated.models.resolve_request_refs_item import ResolveRequestRefsItem +from roe._generated.types import UNSET +from roe.config import RoeConfig +from roe.utils.generated_request import request_raw + + +class KnowledgeBaseAPI: + """API for managing Knowledge Base lenses and drafts.""" + + def __init__(self, config: RoeConfig, raw_client: AuthenticatedClient): + self.config = config + self._raw = raw_client + + def _org(self) -> Any: + org = self.config.organization_id + return UUID(str(org)) if org else UNSET + + def list( + self, + page: int | None = None, + page_size: int | None = None, + ) -> PaginatedKnowledgeBaseList: + """List all knowledge bases for the organisation.""" + response = request_raw( + self._raw, + knowledge_base_list, + page=page if page is not None else UNSET, + page_size=page_size if page_size is not None else UNSET, + organization_id=self._org(), + ) + return PaginatedKnowledgeBaseList.from_dict(response.json()) + + def create( + self, + company: str, + brief: str, + name: str | None = None, + product_name: str | None = None, + website_url: str | None = None, + ) -> CreateKnowledgeBase: + """Create a new knowledge base draft (async generation).""" + body = CreateKnowledgeBaseRequest( + company=company, + brief=brief, + name=name if name is not None else UNSET, + product_name=product_name if product_name is not None else UNSET, + website_url=website_url if website_url is not None else UNSET, + ) + response = request_raw( + self._raw, + knowledge_base_create, + body=body, + organization_id=self._org(), + ) + return CreateKnowledgeBase.from_dict(response.json()) + + def retrieve(self, knowledge_base_id: str) -> KnowledgeBase: + """Retrieve a single knowledge base record.""" + response = request_raw( + self._raw, + knowledge_base_retrieve, + UUID(str(knowledge_base_id)), + organization_id=self._org(), + ) + return KnowledgeBase.from_dict(response.json()) + + def delete(self, knowledge_base_id: str) -> None: + """Delete a knowledge base and its associated Atlas draft or lens.""" + request_raw( + self._raw, + knowledge_base_destroy, + UUID(str(knowledge_base_id)), + organization_id=self._org(), + ) + + def poll_draft(self, knowledge_base_id: str) -> Draft: + """Poll the Atlas draft status until ready or error.""" + response = request_raw( + self._raw, + knowledge_base_draft_retrieve, + UUID(str(knowledge_base_id)), + organization_id=self._org(), + ) + return Draft.from_dict(response.json()) + + def patch_selection( + self, + knowledge_base_id: str, + refs: list[dict[str, Any]], + suggested_name: str | None = None, + ) -> Draft: + """Patch the draft's typology/tactic selection.""" + body = PatchedPatchSelectionRequest( + refs=[PatchedPatchSelectionRequestRefsItem.from_dict(r) for r in refs], + suggested_name=suggested_name if suggested_name is not None else UNSET, + ) + response = request_raw( + self._raw, + knowledge_base_selection_partial_update, + UUID(str(knowledge_base_id)), + body=body, + organization_id=self._org(), + ) + return Draft.from_dict(response.json()) + + def regenerate( + self, + knowledge_base_id: str, + feedback: str | None = None, + ) -> Draft: + """Kick off an async regeneration round with optional feedback.""" + body = RegenerateRequest( + feedback=feedback if feedback is not None else UNSET, + ) + response = request_raw( + self._raw, + knowledge_base_regenerate_create, + UUID(str(knowledge_base_id)), + body=body, + organization_id=self._org(), + ) + return Draft.from_dict(response.json()) + + def resolve( + self, + knowledge_base_id: str, + refs: list[dict[str, Any]] | None = None, + suggested_name: str | None = None, + accept_summary: bool = False, + discard: bool = False, + ) -> Draft: + """Approve or decline a pending regeneration proposal.""" + body = ResolveRequest( + refs=[ResolveRequestRefsItem.from_dict(r) for r in refs] + if refs is not None + else UNSET, + suggested_name=suggested_name if suggested_name is not None else UNSET, + accept_summary=accept_summary, + discard=discard, + ) + response = request_raw( + self._raw, + knowledge_base_resolve_create, + UUID(str(knowledge_base_id)), + body=body, + organization_id=self._org(), + ) + return Draft.from_dict(response.json()) + + def finalize( + self, + knowledge_base_id: str, + name: str | None = None, + mcp_enabled: bool = True, + public: bool = True, + ) -> KnowledgeBase: + """Commit the draft into a permanent Atlas lens.""" + body = FinalizeRequest( + name=name if name is not None else UNSET, + mcp_enabled=mcp_enabled, + public=public, + ) + response = request_raw( + self._raw, + knowledge_base_finalize_create, + UUID(str(knowledge_base_id)), + body=body, + organization_id=self._org(), + ) + return KnowledgeBase.from_dict(response.json()) + + def sync(self, knowledge_base_id: str) -> KnowledgeBase: + """Sync the lens snapshot from Atlas (best-effort).""" + response = request_raw( + self._raw, + knowledge_base_sync_create, + UUID(str(knowledge_base_id)), + organization_id=self._org(), + ) + return KnowledgeBase.from_dict(response.json()) + + def catalog(self) -> Any: + """Fetch the names-only typology and tactic catalog.""" + response = request_raw( + self._raw, + knowledge_base_catalog_retrieve, + organization_id=self._org(), + ) + return response.json() + + def lens_by_atlas_id(self, atlas_lens_id: str) -> Any: + """Fetch and optionally sync a lens by its Atlas ID.""" + response = request_raw( + self._raw, + knowledge_base_lens_retrieve, + str(atlas_lens_id), + organization_id=self._org(), + ) + return response.json() + + def import_lens(self, atlas_lens_id: str) -> KnowledgeBase: + """Import a finalized Atlas lens into roe-main by its atlas_lens_id.""" + body = KnowledgeBaseImportLensCreateBody.from_dict( + {"atlas_lens_id": atlas_lens_id} + ) + response = request_raw( + self._raw, + knowledge_base_import_lens_create, + body=body, + organization_id=self._org(), + ) + return KnowledgeBase.from_dict(response.json()) diff --git a/src/roe/client.py b/src/roe/client.py index daab0bd..93a6b9e 100644 --- a/src/roe/client.py +++ b/src/roe/client.py @@ -7,6 +7,7 @@ from roe._generated.client import AuthenticatedClient as RawClient from roe.api._generated_registry import GENERATED_API_CLASSES from roe.api.agents import AgentsAPI +from roe.api.knowledge_base import KnowledgeBaseAPI from roe.api.policies import PoliciesAPI from roe.api.users import UsersAPI from roe.auth import RoeAuth @@ -97,6 +98,7 @@ def __init__( self._agents = AgentsAPI(self.config, self._raw) self._policies = PoliciesAPI(self.config, self._raw) self._users = UsersAPI(self.config, self._raw) + self._knowledge_base = KnowledgeBaseAPI(self.config, self._raw) self._generated_apis = { name: api_cls(self.config, self._raw) for name, api_cls in GENERATED_API_CLASSES.items() @@ -166,6 +168,28 @@ def users(self) -> UsersAPI: """ return self._users + @property + def knowledge_base(self) -> KnowledgeBaseAPI: + """Access the knowledge base API for managing lenses and drafts. + + Returns: + KnowledgeBaseAPI instance for managing knowledge bases. + + Examples: + # Create a knowledge base draft + kb = client.knowledge_base.create( + company="Acme Corp", + brief="A long-enough brief describing the company and goals.", + ) + + # List knowledge bases + knowledge_bases = client.knowledge_base.list() + + # Finalize a draft into a permanent lens + client.knowledge_base.finalize(str(kb.id)) + """ + return self._knowledge_base + @property def raw(self) -> RawClient: """Access the generated raw client.""" diff --git a/tests/unit/test_knowledge_base_wrapper_transport.py b/tests/unit/test_knowledge_base_wrapper_transport.py new file mode 100644 index 0000000..04e90b0 --- /dev/null +++ b/tests/unit/test_knowledge_base_wrapper_transport.py @@ -0,0 +1,88 @@ +"""Regression tests for public knowledge base wrapper transport behavior.""" + +from __future__ import annotations + +from types import SimpleNamespace +from unittest.mock import MagicMock +from uuid import UUID + +import httpx + +from roe.api.knowledge_base import KnowledgeBaseAPI + +ORG_ID = "00000000-0000-0000-0000-000000000123" +KB_ID = "00000000-0000-0000-0000-000000000444" + + +def _api(response: httpx.Response) -> tuple[KnowledgeBaseAPI, MagicMock]: + request = MagicMock(return_value=response) + raw_client = MagicMock() + raw_client.get_httpx_client.return_value = SimpleNamespace(request=request) + config = SimpleNamespace(organization_id=ORG_ID) + return KnowledgeBaseAPI(config, raw_client), request + + +def _draft_json() -> dict[str, object]: + return { + "id": "draft-1", + "status": "ready", + "company": "Acme", + "suggestedName": "Acme Lens", + "productSummary": "summary", + "iterationCount": 1, + "refs": [], + } + + +def test_create_posts_body_with_org_query(): + api, request = _api( + httpx.Response(201, json={"company": "Acme", "brief": "a long enough brief"}) + ) + + result = api.create(company="Acme", brief="a long enough brief") + + kwargs = request.call_args.kwargs + assert kwargs["method"] == "post" + assert kwargs["params"] == {"organization_id": ORG_ID} + assert kwargs["json"] == {"company": "Acme", "brief": "a long enough brief"} + assert result.company == "Acme" + + +def test_list_sends_pagination_and_org_query(): + api, request = _api(httpx.Response(200, json={"count": 0, "results": []})) + + result = api.list(page=2, page_size=10) + + kwargs = request.call_args.kwargs + assert kwargs["method"] == "get" + assert kwargs["params"] == { + "page": 2, + "page_size": 10, + "organization_id": ORG_ID, + } + assert result.count == 0 + + +def test_patch_selection_round_trips_refs_in_body(): + api, request = _api(httpx.Response(200, json=_draft_json())) + + refs = [{"typologyId": "t1", "relevance": "core"}] + api.patch_selection(KB_ID, refs=refs, suggested_name="Acme Lens") + + kwargs = request.call_args.kwargs + assert kwargs["method"] == "patch" + assert kwargs["params"] == {"organization_id": ORG_ID} + assert kwargs["json"] == {"refs": refs, "suggested_name": "Acme Lens"} + + +def test_delete_sends_delete_with_org_query_and_no_body(): + api, request = _api(httpx.Response(204)) + + assert api.delete(KB_ID) is None + + kwargs = request.call_args.kwargs + assert kwargs["method"] == "delete" + assert kwargs["params"] == {"organization_id": ORG_ID} + assert "json" not in kwargs + # path-arg is interpolated into the URL, not sent as a query param + assert UUID(KB_ID).hex in kwargs["url"].replace("-", "") From 6ad283db5912672a6c68c6e4104e3aab42bdb655 Mon Sep 17 00:00:00 2001 From: Chen-ROE Date: Tue, 23 Jun 2026 14:34:34 -0700 Subject: [PATCH 3/5] fix(agents): update jobs wrapper for 1-0-85 API changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The agents namespace is hand-maintained, so codegen did not update it for this release's agent-jobs API changes (surfaced by the SDK review): - download_reference: drop the organization_id kwarg. The references endpoint removed that query param (org is derived from the job), so the generated _get_kwargs no longer accepts it — the previous call raised TypeError at runtime. - retrieve_artifact: add wrapper for the new agents_jobs_artifacts_result_retrieve endpoint (GET .../artifacts/result/ ?artifact_key=), returning AgentJobArtifactResult. - cancel_all: return the new AgentJobCancelAllResponse body (the endpoint changed from 204/None to 200 with a structured response) instead of None. Add transport regression tests for all three. Co-Authored-By: Claude Opus 4.8 --- src/roe/api/agents.py | 23 +++++++++-- tests/unit/test_agents_wrapper_transport.py | 42 +++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/roe/api/agents.py b/src/roe/api/agents.py index 922cd14..2e43f23 100644 --- a/src/roe/api/agents.py +++ b/src/roe/api/agents.py @@ -21,6 +21,7 @@ agents_create, agents_destroy, agents_duplicate_create, + agents_jobs_artifacts_result_retrieve, agents_jobs_cancel_all_create, agents_jobs_cancel_create, agents_jobs_delete_data_create, @@ -51,6 +52,10 @@ from roe._generated.models.agent_execution_request import ( AgentExecutionRequest, ) +from roe._generated.models.agent_job_artifact_result import AgentJobArtifactResult +from roe._generated.models.agent_job_cancel_all_response import ( + AgentJobCancelAllResponse, +) from roe._generated.models.agent_job_delete_data_response import ( AgentJobDeleteDataResponse, ) @@ -334,7 +339,6 @@ def download_reference( kwargs = agents_jobs_references_retrieve._get_kwargs( agent_job_id=UUID(str(job_id)), resource_id=resource_id, - organization_id=self._org_id, ) if as_attachment: kwargs.setdefault("params", {})["download"] = "true" @@ -342,6 +346,18 @@ def download_reference( translate_response(response) return response.content + def retrieve_artifact( + self, job_id: str, artifact_key: str + ) -> AgentJobArtifactResult: + response = request_raw( + self._raw, + agents_jobs_artifacts_result_retrieve, + str(job_id), + artifact_key=artifact_key, + organization_id=self._org_id, + ) + return AgentJobArtifactResult.from_dict(response.json()) + def cancel(self, job_id: str) -> None: request_raw( self._raw, @@ -350,13 +366,14 @@ def cancel(self, job_id: str) -> None: organization_id=self._org_id, ) - def cancel_all(self, agent_id: str) -> None: - request_raw( + def cancel_all(self, agent_id: str) -> AgentJobCancelAllResponse: + response = request_raw( self._raw, agents_jobs_cancel_all_create, UUID(str(agent_id)), organization_id=self._org_id, ) + return AgentJobCancelAllResponse.from_dict(response.json()) def delete_data(self, job_id: str) -> AgentJobDeleteDataResponse: response = request_raw( diff --git a/tests/unit/test_agents_wrapper_transport.py b/tests/unit/test_agents_wrapper_transport.py index 63420ae..375bdd5 100644 --- a/tests/unit/test_agents_wrapper_transport.py +++ b/tests/unit/test_agents_wrapper_transport.py @@ -103,6 +103,48 @@ def test_agent_version_replace_uses_put_with_org_query_and_model_body(): assert result.message == "ok" +def test_download_reference_omits_organization_id_query_param(): + # The references endpoint dropped organization_id; the wrapper must not send + # it, or _get_kwargs raises TypeError (org is derived from the job). + api, request = _api(httpx.Response(200, content=b"file-bytes")) + + content = api.jobs.download_reference(JOB_ID, "resource-1") + + kwargs = request.call_args.kwargs + assert "organization_id" not in (kwargs.get("params") or {}) + assert content == b"file-bytes" + + +def test_retrieve_artifact_sends_artifact_key_and_org_query(): + api, request = _api(httpx.Response(200, json={"result": {"value": 1}})) + + result = api.jobs.retrieve_artifact(JOB_ID, artifact_key="evidence_data") + + kwargs = request.call_args.kwargs + assert kwargs["method"] == "get" + assert kwargs["params"]["artifact_key"] == "evidence_data" + assert kwargs["params"]["organization_id"] == ORG_ID + assert JOB_ID in kwargs["url"] + assert result.result == {"value": 1} + + +def test_cancel_all_returns_structured_response_body(): + api, request = _api( + httpx.Response( + 200, + json={"task_id": "task-1", "targeted_count": 3, "note": "cancelling"}, + ) + ) + + result = api.jobs.cancel_all(AGENT_ID) + + kwargs = request.call_args.kwargs + assert kwargs["method"] == "post" + assert kwargs["params"] == {"organization_id": ORG_ID} + assert result.targeted_count == 3 + assert result.note == "cancelling" + + def test_retrieve_status_parses_single_status_shape_without_id(): # GET /v1/agents/jobs/{job_id}/status/ returns AgentJobSingleStatus # ({status, timestamp, error_message?}) with no "id" field — parsing it From fc699e304a4954407cdbb91540c91e0412da90ef Mon Sep 17 00:00:00 2001 From: Chen-ROE Date: Tue, 30 Jun 2026 16:49:00 -0700 Subject: [PATCH 4/5] feat(knowledge_base): add unlink method for 1-0-86 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Release 1-0-86 adds the knowledge_base_unlink_destroy operation (DELETE /v1/knowledge-base/{id}/unlink/, kind: manual) — unlink a knowledge base locally while preserving the Atlas lens. Add the matching KnowledgeBaseAPI.unlink wrapper method and a transport test. Co-Authored-By: Claude Opus 4.8 --- src/roe/api/knowledge_base.py | 10 ++++++++++ tests/unit/test_knowledge_base_wrapper_transport.py | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/roe/api/knowledge_base.py b/src/roe/api/knowledge_base.py index a7d666d..ba0da6b 100644 --- a/src/roe/api/knowledge_base.py +++ b/src/roe/api/knowledge_base.py @@ -29,6 +29,7 @@ knowledge_base_retrieve, knowledge_base_selection_partial_update, knowledge_base_sync_create, + knowledge_base_unlink_destroy, ) from roe._generated.client import AuthenticatedClient from roe._generated.models.create_knowledge_base import CreateKnowledgeBase @@ -127,6 +128,15 @@ def delete(self, knowledge_base_id: str) -> None: organization_id=self._org(), ) + def unlink(self, knowledge_base_id: str) -> None: + """Unlink a knowledge base locally, preserving the Atlas lens.""" + request_raw( + self._raw, + knowledge_base_unlink_destroy, + UUID(str(knowledge_base_id)), + organization_id=self._org(), + ) + def poll_draft(self, knowledge_base_id: str) -> Draft: """Poll the Atlas draft status until ready or error.""" response = request_raw( diff --git a/tests/unit/test_knowledge_base_wrapper_transport.py b/tests/unit/test_knowledge_base_wrapper_transport.py index 04e90b0..44fdf3a 100644 --- a/tests/unit/test_knowledge_base_wrapper_transport.py +++ b/tests/unit/test_knowledge_base_wrapper_transport.py @@ -86,3 +86,14 @@ def test_delete_sends_delete_with_org_query_and_no_body(): assert "json" not in kwargs # path-arg is interpolated into the URL, not sent as a query param assert UUID(KB_ID).hex in kwargs["url"].replace("-", "") + + +def test_unlink_sends_delete_to_unlink_endpoint_with_org_query(): + api, request = _api(httpx.Response(204)) + + assert api.unlink(KB_ID) is None + + kwargs = request.call_args.kwargs + assert kwargs["method"] == "delete" + assert kwargs["params"] == {"organization_id": ORG_ID} + assert kwargs["url"].endswith(f"/v1/knowledge-base/{KB_ID}/unlink/") From 58ab150b27f0fa1d1fa755807f1cf36cbd8de03f Mon Sep 17 00:00:00 2001 From: Chen-ROE Date: Tue, 30 Jun 2026 17:11:42 -0700 Subject: [PATCH 5/5] docs(examples): fill in knowledge_base example arguments The generated SDK_EXAMPLES.md rendered every knowledge_base manual method as a bare call (e.g. `client.knowledge_base.create()`), which fails at runtime because the wrappers require arguments. Regenerated with the roe-sdk examples renderer fix that adds the manual knowledge_base call templates, so the copy-ready snippets now pass the required args. Co-Authored-By: Claude Opus 4.8 --- SDK_EXAMPLES.md | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/SDK_EXAMPLES.md b/SDK_EXAMPLES.md index 83961bf..c8e23ec 100644 --- a/SDK_EXAMPLES.md +++ b/SDK_EXAMPLES.md @@ -653,7 +653,10 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.create() +result = client.knowledge_base.create( + company="company", + brief="brief", +) ``` #### `knowledge_base_catalog_retrieve` @@ -677,7 +680,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.import_lens() +result = client.knowledge_base.import_lens("atlas_lens_id") ``` #### `knowledge_base_lens_retrieve` @@ -690,7 +693,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.lens_by_atlas_id() +result = client.knowledge_base.lens_by_atlas_id("atlas_lens_id") ``` #### `knowledge_base_destroy` @@ -702,7 +705,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.delete() +client.knowledge_base.delete("knowledge_base_id") ``` #### `knowledge_base_retrieve` @@ -714,7 +717,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.retrieve() +result = client.knowledge_base.retrieve("knowledge_base_id") ``` #### `knowledge_base_draft_retrieve` @@ -726,7 +729,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.poll_draft() +result = client.knowledge_base.poll_draft("knowledge_base_id") ``` #### `knowledge_base_finalize_create` @@ -738,7 +741,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.finalize() +result = client.knowledge_base.finalize("knowledge_base_id") ``` #### `knowledge_base_regenerate_create` @@ -750,7 +753,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.regenerate() +result = client.knowledge_base.regenerate("knowledge_base_id") ``` #### `knowledge_base_resolve_create` @@ -762,7 +765,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.resolve() +result = client.knowledge_base.resolve("knowledge_base_id") ``` #### `knowledge_base_selection_partial_update` @@ -774,7 +777,10 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.patch_selection() +result = client.knowledge_base.patch_selection( + "knowledge_base_id", + refs=[], +) ``` #### `knowledge_base_sync_create` @@ -786,7 +792,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.sync() +result = client.knowledge_base.sync("knowledge_base_id") ``` #### `knowledge_base_unlink_destroy` @@ -799,7 +805,7 @@ from roe import RoeClient client = RoeClient() -result = client.knowledge_base.unlink() +client.knowledge_base.unlink("knowledge_base_id") ``` ### Policies