Repository navigation
Add Hosted Agents /v2/agents OpenAPI (triggers, event stream, port-forward; supersedes #1233) - #1255
Merged
SSharma-10 merged 22 commits intoOct 13, 2026
Conversation
Document all 38 OHS public endpoints (configs, sessions, checkpoints, fork, workspace transfers, and templates) for client generation and docs. Co-authored-by: Cursor <[email protected]>
Expose a single requestBody media type so Autorest can generate agents_create_session, while documenting YAML/JSON dual forms via description and x-content-schemas to match harness swagger. Co-authored-by: Cursor <[email protected]>
… OpenAPI Adds the 15 operations missing from digitalocean#1233 (point 3 of the API Engineering review): - Triggers Config API (13 ops): CRUD + pause/resume on /v2/agents/triggers, webhook secret rotation, execution history + cancel, by-session lookup, reusable-session picker, the webhook-providers registry, and the HMAC-authenticated webhook ingress endpoint. Mirrored from harness-trigger/contracts/trigger.swagger.json. - Session event stream: GET /v2/agents/sessions/{session_id}/events (Server-Sent Events), mirrored from contracts/mars-dataplane-sse.openapi.yaml. Documents the shipping params (replay_only, replay_from, cursor, device_id, Last-Event-ID, X-Device-UUID). - Port-forward: GET /v2/agents/sessions/{session_id}/port-forward/{port}, the WebSocket tunnel to a guest TCP port (documented as the 101 upgrade handshake). The webhook ingress body is modeled as application/octet-stream (binary), not '*/*': the latter crashes the autorest/modelerfour pre-namer ('Name cannot be empty') that the pydo client-gen CI runs. Validation: make lint 0 errors; make bundle ok; autorest --python generate exits 0. Co-authored-by: Cursor <[email protected]>
sdharavath
force-pushed
the
sdharavath/OAR-15627/agents-triggers-events-portforward
branch
from
October 8, 2026 07:51
a732f80 to
0a4e12a
Compare
…/v2/agents errors
Anup Deka (API Eng) asked for the standard envelope; cthulhu#179553 (merged) makes
harness-api emit it and the Oceanus edge already returns it. Point the agents error
schema at shared/models/error.yml so all 128 error responses across the 53 ops use
{id, message, request_id} instead of the old nested {error:{code,message}}, removing
the split where only 401/404/429/500 used the standard shape.
make lint 0 errors; make bundle ok (old nested shape gone); autorest --python exits 0.
Co-authored-by: Cursor <[email protected]>
- digitalocean#1: events-stream errors are text/plain (OHP, not JSON) for 404/429/500/503; drop the 400; keep 401 JSON (edge). OHP moves to JSON under MARSOHS-2065. - digitalocean#2: add 402 to the 16 billing-gated operations (cthulhu#179578). - digitalocean#3: add GET /v2/agents/sessions/{id}/ingress (publicly routed; replaces the port-forward bridge for browser clients). - digitalocean#4: trigger create/update return 422 (trigger limit) and 503 (upstream check); webhook ingress returns 400 (body too large/unreadable). - digitalocean#5: add stream.state to the stream_event type enum + a stream_state schema. - digitalocean#6: trigger reads return 404 not 403 for another team's trigger; create can return 403 (config permission denied). - digitalocean#7: correct the port-forward description (ingress replaced it for browsers; paused sessions are woken and served) and document the handshake 400. - digitalocean#8: webhook body lists concrete content types (json/form/octet-stream). - digitalocean#9: drop the ignored Content-Type response header on the events 200. Deferred (cosmetic): renaming the 53 Go-method summaries to DO reference style. make lint 0 errors; make bundle ok; autorest --python exits 0. Co-authored-by: Cursor <[email protected]>
…lope
Matches OHP after cthulhu#179797 (MARSOHS-2065): OHP routes its refusals through
common/httpapi.WriteError + httpapi.RequestID and emits {id, message, request_id}
on 404/429/500/503 (the 401 is the edge). GATED ON #179797's DEPLOY: until it is
rolled out to the OHP instance behind api.digitalocean.com the live stream still
returns text/plain, so digitalocean#1255 must merge only after #179797 is deployed.
make lint 0 errors; make bundle ok.
Co-authored-by: Cursor <[email protected]>
- create and update trigger document 502 (config service error); update also documents 403 (config permission denied) - both via writeConfigErr's default and PermissionDenied branches (handlers.go:1244/1248). - webhook ingress application/json body is type: object (additionalProperties: true) so real JSON deliveries validate under a contract check; form and octet-stream stay strings. make lint 0 errors; make bundle ok; autorest --python exits 0. Co-authored-by: Cursor <[email protected]>
anup-deka
previously approved these changes
Oct 8, 2026
3 of 5 tasks
SSharma-10
approved these changes
Oct 12, 2026
This was referenced Oct 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Supersedes #1233 and continues @SSharma-10's work (her commits are included here). Adds the
publicly-routed
/v2/agentssurfaces that #1233 was missing — point 3 of the API Engineering review(OAR-15627 / MARSOHS-1858) — and incorporates the follow-up API review of this PR.
Surfaces added on top of #1233's 38 ops:
/v2/agents/triggers, webhook-secret rotation,execution history + get + cancel,
by-sessionlookup, thereusable-sessionspicker, the/v2/agents/webhook-providersregistry, and the HMAC-authenticated webhook ingress.GET /v2/agents/sessions/{session_id}/events(SSE).GET /v2/agents/sessions/{session_id}/port-forward/{port}(WebSocket,101).GET /v2/agents/sessions/{session_id}/ingress(OpenHands-only, team-gated; the URLthat replaced the port-forward bridge for browser clients).
Full
/v2/agentssurface: 54 operations.Deliberately excluded (11 ops, still under development)
Left out on purpose, not an oversight:
POST /v2/agents/auth/{provider},GET /auth/{provider}/poll,GET+POST /auth/{provider}/connections,GET+DELETE /auth/{provider}/connections/{id}.GET+POST /v2/agents/workspaces,GET+DELETE /v2/agents/workspaces/{workspace_id}.POST /v2/agents/sessions/{session_id}/cancel.Error envelopes
All error responses use the DO-standard JSON
{id, message, request_id}(shared/models/error.yml),matching the Oceanus edge and cthulhu#179553 (deployed to preview + production).
Addressed in the API review of this PR
create and update can return 403 (backing-config permission denied) and 502 (config service
error) via
writeConfigErr; 400 (body too large/unreadable) on webhook ingress; trigger readsreturn 404 (not 403) for another team's trigger.
stream.stateadded to thestream_eventtype enum (+ astream_stateschema).served) and the handshake 400 documented.
application/json(type: object),application/x-www-form-urlencodedandapplication/octet-stream(strings).Test plan
make lint→ 0 errors (source + bundled ruleset).make bundle→ ok.autorest --pythonexits 0.Follow-ups (out of scope here)
agent_harness_trigger:*scope.harness.swagger.json/trigger.swagger.json(the contract testing in point 5 of the design review).