diff --git a/specification/DigitalOcean-public.v2.yaml b/specification/DigitalOcean-public.v2.yaml index b8c29b46..605948bc 100644 --- a/specification/DigitalOcean-public.v2.yaml +++ b/specification/DigitalOcean-public.v2.yaml @@ -60,6 +60,15 @@ tags: The Add-Ons API allows you to manage these resources, including creating, listing, and retrieving details about specific add-on resources. + - name: Agents + description: |- + Hosted Agents sessions API (`/v2/agents/sessions`). Sessions represent a + managed agent + sandbox pair. Product provenance is exposed via + `session.origin` (`direct` | `simulation` | `evaluation`). ListSessions + omits simulation and evaluation sessions server-side so customer surfaces + stay free of product-owned internal runs; GetSession by session_id still + returns those sessions for the owning product workflow. + - name: Apps description: |- App Platform is a Platform-as-a-Service (PaaS) offering from DigitalOcean that allows @@ -781,6 +790,62 @@ paths: patch: $ref: "resources/addons/addons_update_plan.yml" + /v2/agents/sessions: + get: + $ref: "resources/agents/agents_list_sessions.yml" + post: + $ref: "resources/agents/agents_create_session.yml" + /v2/agents/sessions/policy/validate: + post: + $ref: "resources/agents/agents_validate_session_policy.yml" + /v2/agents/sessions/sandbox/sizes: + get: + $ref: "resources/agents/agents_list_session_sandbox_sizes.yml" + /v2/agents/sessions/{session_id}: + delete: + $ref: "resources/agents/agents_delete_session.yml" + get: + $ref: "resources/agents/agents_get_session.yml" + /v2/agents/sessions/{session_id}/hitl/{request_id}: + post: + $ref: "resources/agents/agents_post_session_hitl.yml" + /v2/agents/sessions/{session_id}/input: + post: + $ref: "resources/agents/agents_create_session_input.yml" + /v2/agents/sessions/{session_id}/pause: + post: + $ref: "resources/agents/agents_post_session_pause.yml" + /v2/agents/sessions/{session_id}/resume: + post: + $ref: "resources/agents/agents_post_session_resume.yml" + /v2/agents/sessions/{session_id}/sandbox/exec: + post: + $ref: "resources/agents/agents_post_session_sandbox_exec.yml" + /v2/agents/sessions/{session_id}/stream: + get: + $ref: "resources/agents/agents_get_session_stream.yml" + /v2/agents/sessions/{session_id}/workspace/download: + get: + $ref: "resources/agents/agents_get_session_workspace_download.yml" + /v2/agents/sessions/{session_id}/workspace/transfers: + post: + $ref: "resources/agents/agents_create_session_workspace_transfer.yml" + /v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}: + get: + $ref: "resources/agents/agents_get_session_workspace_transfer.yml" + /v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/cancel: + post: + $ref: "resources/agents/agents_cancel_session_workspace_transfer.yml" + /v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/commit: + post: + $ref: "resources/agents/agents_commit_session_workspace_transfer.yml" + /v2/agents/sessions/{session_id}/workspace/transfers/{transfer_id}/part-upload-urls: + post: + $ref: "resources/agents/agents_create_session_workspace_part_upload_urls.yml" + /v2/agents/sessions/{session_id}/workspace/upload: + post: + $ref: "resources/agents/agents_create_session_workspace_upload.yml" + /v2/apps: get: $ref: "resources/apps/apps_list.yml" diff --git a/specification/resources/agents/agents_cancel_session_workspace_transfer.yml b/specification/resources/agents/agents_cancel_session_workspace_transfer.yml new file mode 100644 index 00000000..504138b3 --- /dev/null +++ b/specification/resources/agents/agents_cancel_session_workspace_transfer.yml @@ -0,0 +1,70 @@ +operationId: agents_cancel_session_workspace_transfer +summary: Cancel a staged workspace transfer. +description: 'Aborts an in-flight transfer. Idempotent: cancelling an already-terminal transfer returns + `aborted: false` with the current status. The request body is optional.' +tags: +- Agents +parameters: +- in: path + name: session_id + required: true + description: The session UUID. + schema: + type: string + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +- in: path + name: transfer_id + required: true + description: The workspace transfer identifier. + schema: + type: string + example: tr_example + example: tr_example +requestBody: + required: false + content: + application/json: + schema: + type: object + properties: + reason: + type: string + description: Optional caller-visible audit/debug context. + example: example +responses: + '200': + description: Cancel processed. + headers: &id001 + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/workspace_transfer_cancelled + '401': + $ref: ../../shared/responses/unauthorized.yml + '404': + $ref: ../../shared/responses/not_found.yml + '501': + description: Cancel is not supported by the active sandbox driver. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '429': + $ref: ../../shared/responses/too_many_requests.yml + '500': + $ref: ../../shared/responses/server_error.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_cancel_session_workspace_transfer.yml +security: +- bearer_auth: + - agents:create diff --git a/specification/resources/agents/agents_commit_session_workspace_transfer.yml b/specification/resources/agents/agents_commit_session_workspace_transfer.yml new file mode 100644 index 00000000..22bfae57 --- /dev/null +++ b/specification/resources/agents/agents_commit_session_workspace_transfer.yml @@ -0,0 +1,86 @@ +operationId: agents_commit_session_workspace_transfer +summary: Finalize a staged upload. +description: Upload only. Call once, after all parts have been uploaded. Completes the multipart upload + and starts the asynchronous import into the workspace. Responds 202; poll the transfer until `completed` + or `failed`. +tags: +- Agents +parameters: +- in: path + name: session_id + required: true + description: The session UUID. + schema: + type: string + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +- in: path + name: transfer_id + required: true + description: The workspace transfer identifier. + schema: + type: string + example: tr_example + example: tr_example +requestBody: + required: false + content: + application/json: + schema: + type: object + properties: + sha256: + type: string + description: Optional lowercase hex SHA-256. Must match the value supplied at create when + both are set. + example: example +responses: + '202': + description: Upload committed; import in progress. + headers: &id001 + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/workspace_upload_committed + '400': + description: Missing transfer_id, sha256 mismatch, or invalid JSON. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '401': + $ref: ../../shared/responses/unauthorized.yml + '404': + $ref: ../../shared/responses/not_found.yml + '409': + description: Transfer is not in a committable state. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '501': + description: Staged upload is not supported by the active sandbox driver. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '429': + $ref: ../../shared/responses/too_many_requests.yml + '500': + $ref: ../../shared/responses/server_error.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_commit_session_workspace_transfer.yml +security: +- bearer_auth: + - agents:create diff --git a/specification/resources/agents/agents_create_session.yml b/specification/resources/agents/agents_create_session.yml new file mode 100644 index 00000000..5e4ac00a --- /dev/null +++ b/specification/resources/agents/agents_create_session.yml @@ -0,0 +1,128 @@ +operationId: agents_create_session +summary: CreateSession provisions a sandbox and starts the requested agent. +description: 'Returns once the session row is allocated. The sandbox boot completes asynchronously; clients + observe SESSION_STATUS_PROVISIONING → READY via StreamSession. + + + Two mutually exclusive request forms are selected by Content-Type. Existing YAML callers send a raw + customer `agents.yaml` Agent manifest with `application/x-yaml`, `application/yaml`, `text/yaml`, or + `text/x-yaml`; this flow is unchanged. Definition-backed callers send the strict `CreateSessionDefinitionRequest` + JSON object with `application/json`. Unknown JSON fields, including team identity, are rejected. An + omitted revision_id pins the definition''s current immutable revision. + + + Definition-backed execution requires an exactly matching credential binding set when the selected revision + declares logical secrets. Static values are fetched only by their persisted name/region/version and + are never returned or persisted. OAuth bindings currently fail closed with 501. + + + Every successful create atomically persists value-free execution provenance and an allowlisted agent-spec + audit snapshot. The team and user identity are taken from the authenticated principal, never the body. + `X-Device-UUID` (if present) is persisted on the session row.' +tags: +- Agents +parameters: +- in: header + name: X-Device-UUID + required: false + description: Optional hardware device id forwarded by doctl. Persisted on the session row for lifecycle + attribution. Values over 128 bytes are ignored. + schema: + type: string + example: device-uuid-example + example: device-uuid-example +requestBody: + required: true + content: + application/json: + schema: + $ref: models/definitions.yml#/create_session_definition_request + application/x-yaml: &id001 + schema: + $ref: models/definitions.yml#/agent_manifest + application/yaml: *id001 + text/yaml: *id001 + text/x-yaml: *id001 + description: Either a raw AgentManifest with a YAML Content-Type or CreateSessionDefinitionRequest with + application/json. The forms are mutually exclusive by Content-Type. +responses: + '200': + description: Session row allocated; sandbox boot continues asynchronously. + headers: &id002 + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/create_session_response + '400': + description: Invalid manifest/reference JSON, incompatible or missing binding set, env collision, + credential limit violation, or invalid session/origin identifier. + headers: *id002 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '401': + $ref: ../../shared/responses/unauthorized.yml + '403': + description: Secrets Manager denied access to a pinned credential. + headers: *id002 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '409': + description: Team is at the active-session quota, a live session name already exists, or the binding + set targets another revision. + headers: *id002 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '404': + $ref: ../../shared/responses/not_found.yml + '413': + description: JSON reference body exceeds 16 KiB or YAML body exceeds 1 MiB. + headers: *id002 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '415': + description: Unsupported Content-Type. + headers: *id002 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '501': + description: The selected binding set contains an OAuth assignment; execution-time OAuth brokering + is not available yet. + headers: *id002 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '503': + description: Secrets Manager is unavailable. + headers: *id002 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '500': + $ref: ../../shared/responses/server_error.yml + '429': + $ref: ../../shared/responses/too_many_requests.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_create_session.yml +security: +- bearer_auth: + - agents:create diff --git a/specification/resources/agents/agents_create_session_input.yml b/specification/resources/agents/agents_create_session_input.yml new file mode 100644 index 00000000..c9985cb3 --- /dev/null +++ b/specification/resources/agents/agents_create_session_input.yml @@ -0,0 +1,72 @@ +operationId: agents_create_session_input +summary: SendInput delivers a user chat message into the session. +description: The agent observes it on its next turn and emits subsequent events via StreamSession. The + input is forwarded to the owning microVM's OHR inbound surface, which attributes it to a run and returns + the run id. +tags: +- Agents +parameters: +- in: path + name: session_id + required: true + description: The session UUID. + schema: + type: string + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +requestBody: + required: true + content: + application/json: + schema: + $ref: models/definitions.yml#/send_input_request +responses: + '200': + description: Input accepted and attributed to a run. + headers: &id001 + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/send_input_response + '400': + description: Malformed JSON or empty text. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '401': + $ref: ../../shared/responses/unauthorized.yml + '403': + description: Session belongs to another team. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '404': + $ref: ../../shared/responses/not_found.yml + '409': + description: Session is not in a state that accepts input (not READY/DETACHED, or has no sandbox). + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '500': + $ref: ../../shared/responses/server_error.yml + '429': + $ref: ../../shared/responses/too_many_requests.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_create_session_input.yml +security: +- bearer_auth: + - agents:create diff --git a/specification/resources/agents/agents_create_session_workspace_part_upload_urls.yml b/specification/resources/agents/agents_create_session_workspace_part_upload_urls.yml new file mode 100644 index 00000000..88b5db44 --- /dev/null +++ b/specification/resources/agents/agents_create_session_workspace_part_upload_urls.yml @@ -0,0 +1,91 @@ +operationId: agents_create_session_workspace_part_upload_urls +summary: Mint presigned PUT URLs for one or more multipart upload parts. +description: Upload only. Pass one or more 1-based `part_numbers`; the response returns a presigned `upload_url` + per part (all sharing one `expires_at`), so a client can drive parallel part uploads without a round + trip per part. PUT each part's bytes directly to its URL (bypassing harness-api). If URLs expire before + the PUT, request them again. +tags: +- Agents +parameters: +- in: path + name: session_id + required: true + description: The session UUID. + schema: + type: string + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +- in: path + name: transfer_id + required: true + description: The workspace transfer identifier. + schema: + type: string + example: tr_example + example: tr_example +requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - part_numbers + properties: + part_numbers: + type: array + items: + type: integer + format: int32 + example: 1 + description: 1-based part indices to presign (single or batched). +responses: + '200': + description: Presigned PUT URLs for the requested parts. + headers: &id001 + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/workspace_part_upload_urls + '400': + description: Missing transfer_id, empty part_numbers, or a part number < 1, or invalid JSON. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '401': + $ref: ../../shared/responses/unauthorized.yml + '404': + $ref: ../../shared/responses/not_found.yml + '409': + description: Transfer is not in a state that accepts part uploads. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '501': + description: Staged upload is not supported by the active sandbox driver. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '429': + $ref: ../../shared/responses/too_many_requests.yml + '500': + $ref: ../../shared/responses/server_error.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_create_session_workspace_part_upload_urls.yml +security: +- bearer_auth: + - agents:create diff --git a/specification/resources/agents/agents_create_session_workspace_transfer.yml b/specification/resources/agents/agents_create_session_workspace_transfer.yml new file mode 100644 index 00000000..2113f4d4 --- /dev/null +++ b/specification/resources/agents/agents_create_session_workspace_transfer.yml @@ -0,0 +1,147 @@ +operationId: agents_create_session_workspace_transfer +summary: Start a staged (large-file) workspace transfer. +description: 'Creates an asynchronous, object-storage-backed transfer for payloads larger than the streaming + path supports (> ~50 MiB). Bulk bytes never traverse harness-api: the client PUTs/GETs presigned DO + Spaces URLs directly. + + + Set `direction` to `upload` or `download`. + + - `upload`: responds 201 with `transfer_id` + `part_size`; the client then requests per-part presigned + PUT URLs, uploads them to Spaces, and calls `commit`. + + - `download`: responds 202 with `transfer_id`; the client polls GET until `completed` and then fetches + `download_url` from Spaces. + + + Upload and cancel currently return 501 until the sandbox backend RPCs ship; download is live.' +tags: +- Agents +parameters: +- in: path + name: session_id + required: true + description: The session UUID. + schema: + type: string + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - direction + - path + properties: + direction: + type: string + enum: + - upload + - download + description: Transfer direction. + example: upload + path: + type: string + description: Workspace-relative path. Destination for upload, source for download. Paths that + escape the workspace root are rejected. + example: example + is_archive: + type: boolean + description: Upload only. When true, the payload is a tar the guest extracts at `path`. + example: true + as_archive: + type: boolean + description: Download only. When true, `path` is exported as a tar stream. + example: true + size_bytes: + type: string + format: int64 + description: Optional total payload size. Validated against the maximum staged object size + (50 GiB); a larger value returns 413. + example: example + sha256: + type: string + description: Optional lowercase hex SHA-256 of the full payload. If set on an upload, it must + match on commit. + example: example +responses: + '201': + description: Upload transfer created; proceed to request part upload URLs. + headers: &id001 + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/workspace_transfer_created + '202': + description: Download transfer accepted; poll the transfer until completed. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/workspace_transfer_created + '400': + description: Missing/invalid direction or path, or invalid JSON. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '401': + $ref: ../../shared/responses/unauthorized.yml + '403': + description: Path resolves outside the workspace, or the session belongs to another team. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '404': + $ref: ../../shared/responses/not_found.yml + '409': + description: Session has no sandbox, or the sandbox is not ready. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '413': + description: Declared size exceeds the maximum staged object size. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '501': + description: Staged transfer (or this direction) is not supported by the active sandbox driver. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '502': + description: Upstream sandbox transfer coordination failed. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '429': + $ref: ../../shared/responses/too_many_requests.yml + '500': + $ref: ../../shared/responses/server_error.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_create_session_workspace_transfer.yml +security: +- bearer_auth: + - agents:create diff --git a/specification/resources/agents/agents_create_session_workspace_upload.yml b/specification/resources/agents/agents_create_session_workspace_upload.yml new file mode 100644 index 00000000..28023754 --- /dev/null +++ b/specification/resources/agents/agents_create_session_workspace_upload.yml @@ -0,0 +1,131 @@ +operationId: agents_create_session_workspace_upload +summary: Upload a file or tar archive into the session's sandbox workspace. +description: Streams the raw request body to a path inside the sandbox workspace. Concurrent transfers + (upload + download) are capped server-side; over the cap the request blocks and may return 503. The + optional `X-Content-Sha256` request header carries a hex digest the guest verifies after the full payload + is written. +tags: +- Agents +parameters: +- in: path + name: session_id + required: true + description: The session UUID. + schema: + type: string + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +- in: query + name: path + required: true + description: Destination path inside the sandbox workspace. Relative paths resolve under the workspace + root; paths that escape the workspace are rejected. Required. + schema: + type: string + example: example + example: example +- in: query + name: is_archive + required: false + description: If true, the body is a tar stream that the guest extracts under `path`. Defaults to false + (single file). + schema: + type: boolean + example: true + example: true +- in: header + name: X-Content-Sha256 + required: false + description: Optional hex SHA-256 of the full payload. The guest verifies it after writing; a mismatch + returns 400. + schema: + type: string + example: example + example: example +requestBody: + required: true + content: + application/octet-stream: + schema: + type: string + format: binary + example: example + description: Raw file bytes (or tar stream when is_archive=true). Capped at 500 MiB. +responses: + '200': + description: Upload committed. + headers: &id001 + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/workspace_upload_response + '400': + description: Missing path, invalid query parameter, invalid path, or SHA-256 mismatch. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '401': + $ref: ../../shared/responses/unauthorized.yml + '403': + description: Path resolves outside the workspace, or the session belongs to another team. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '404': + $ref: ../../shared/responses/not_found.yml + '409': + description: Session has no sandbox, or the sandbox is not ready. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '413': + description: Payload exceeds the maximum allowed size. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '501': + description: Workspace file transfer is not supported by the active sandbox driver. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '502': + description: Upstream sandbox transfer failed. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '503': + description: Workspace transfer capacity exhausted; retry later. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '429': + $ref: ../../shared/responses/too_many_requests.yml + '500': + $ref: ../../shared/responses/server_error.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_create_session_workspace_upload.yml +security: +- bearer_auth: + - agents:create diff --git a/specification/resources/agents/agents_delete_session.yml b/specification/resources/agents/agents_delete_session.yml new file mode 100644 index 00000000..fab9dadc --- /dev/null +++ b/specification/resources/agents/agents_delete_session.yml @@ -0,0 +1,61 @@ +operationId: agents_delete_session +summary: DestroySession tears down the sandbox and marks the session DESTROYED. +description: Persistent workspace contents are retained per tenant policy. Returns 204 No Content on success. +tags: +- Agents +parameters: +- in: path + name: session_id + required: true + description: The session UUID. + schema: + type: string + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +- in: header + name: X-Device-UUID + required: false + description: Optional hardware device id forwarded by doctl. Recorded on the session row as the device + that performed the destroy. + schema: + type: string + example: device-uuid-example + example: device-uuid-example +responses: + '204': + description: Session destroyed; no response body. + headers: + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + '401': + $ref: ../../shared/responses/unauthorized.yml + '403': + description: Session belongs to another team. + headers: + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '404': + $ref: ../../shared/responses/not_found.yml + '500': + $ref: ../../shared/responses/server_error.yml + '429': + $ref: ../../shared/responses/too_many_requests.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_delete_session.yml +security: +- bearer_auth: + - agents:delete diff --git a/specification/resources/agents/agents_get_session.yml b/specification/resources/agents/agents_get_session.yml new file mode 100644 index 00000000..8f9ab01a --- /dev/null +++ b/specification/resources/agents/agents_get_session.yml @@ -0,0 +1,50 @@ +operationId: agents_get_session +summary: GetSession returns the current snapshot of a session. +description: GetSession returns the current snapshot of a session. +tags: +- Agents +parameters: +- in: path + name: session_id + required: true + description: The session UUID. + schema: + type: string + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +responses: + '200': + description: A successful response. + headers: &id001 + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/get_session_response + '401': + $ref: ../../shared/responses/unauthorized.yml + '403': + description: Session belongs to another team. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '404': + $ref: ../../shared/responses/not_found.yml + '500': + $ref: ../../shared/responses/server_error.yml + '429': + $ref: ../../shared/responses/too_many_requests.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_get_session.yml +security: +- bearer_auth: + - agents:read diff --git a/specification/resources/agents/agents_get_session_stream.yml b/specification/resources/agents/agents_get_session_stream.yml new file mode 100644 index 00000000..f3664e88 --- /dev/null +++ b/specification/resources/agents/agents_get_session_stream.yml @@ -0,0 +1,89 @@ +operationId: agents_get_session_stream +summary: StreamSession is the server-streaming event feed. +description: 'Returns a `text/event-stream` (SSE) feed that drives the interactive TUI / Web Console. + Supports both live attach and historical replay (replay_from cursor). Survives client disconnect — sessions + live server-side and reattach is supported from any machine. + + + Each SSE message is framed as: + + ``` + + id: + + event: + + data: + + + ``` + + A leading comment line (`: connected to `) is sent on open. Errors that occur before the + stream starts are returned as a JSON error envelope; once the event-stream has started, failures simply + close the connection.' +tags: +- Agents +parameters: +- in: path + name: session_id + required: true + description: The session UUID. + schema: + type: string + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + example: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +- in: query + name: replay_from + required: false + description: Optional replay cursor. Empty means "live from now". A previous event_id means "replay + events strictly after that id, then go live". + schema: + type: string + example: example + example: example +- in: query + name: replay_only + required: false + description: If true, only replay; close the stream when caught up. Otherwise the stream stays open + for live events. `doctl agents logs` sets this with an empty replay_from to read full history. + schema: + type: boolean + example: true + example: true +responses: + '200': + description: An SSE stream of session events (text/event-stream). The schema describes the JSON payload + carried in each event's `data:` field. + headers: &id001 + ratelimit-limit: + $ref: ../../shared/headers.yml#/ratelimit-limit + ratelimit-remaining: + $ref: ../../shared/headers.yml#/ratelimit-remaining + ratelimit-reset: + $ref: ../../shared/headers.yml#/ratelimit-reset + content: + application/json: + schema: + $ref: models/definitions.yml#/stream_event + '401': + $ref: ../../shared/responses/unauthorized.yml + '403': + description: Session belongs to another team. + headers: *id001 + content: + application/json: + schema: + $ref: models/definitions.yml#/error + '404': + $ref: ../../shared/responses/not_found.yml + '500': + $ref: ../../shared/responses/server_error.yml + '429': + $ref: ../../shared/responses/too_many_requests.yml + default: + $ref: ../../shared/responses/unexpected_error.yml +x-codeSamples: +- $ref: examples/curl/agents_get_session_stream.yml +security: +- bearer_auth: + - agents:read diff --git a/specification/resources/agents/agents_get_session_workspace_download.yml b/specification/resources/agents/agents_get_session_workspace_download.yml new file mode 100644 index 00000000..63f1643e --- /dev/null +++ b/specification/resources/agents/agents_get_session_workspace_download.yml @@ -0,0 +1,128 @@ +operationId: agents_get_session_workspace_download +summary: Download a file or tar archive from the session's sandbox workspace. +description: 'Streams the workspace payload back as `application/octet-stream` using chunked transfer + encoding, followed by a fixed integrity footer. + + + Response body layout: `` + `