Skip to content

Typed client: Model provider methods + nested-model types (#15492) - #336

Draft
juanmichelini wants to merge 5 commits into
mainfrom
feat/provider-connections-client
Draft

Typed client: Model provider methods + nested-model types (#15492)#336
juanmichelini wants to merge 5 commits into
mainfrom
feat/provider-connections-client

Conversation

@juanmichelini

@juanmichelini juanmichelini commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Typed client: Model providers (provider-first)

Adds typed @openhands/typescript-client methods and types for the Model providers endpoints, aligned to the reworked provider-centric backend (OpenHands/software-agent-sdk#4455). A provider holds one key (named secret) and a nested list of models. Tracks OpenHands/OpenHands#15492.

The frontend PR (OpenHands/OpenHands#16499) uses raw fetch and does not block on this PR; this typed client is for consumers that want the typed surface.

What this adds

  • Client methods on LLMMetadataClient, all under /api/llm/model-providers:
    • listProviders / createProvider / getProvider / updateProvider / deleteProvider
    • addProviderModel / updateProviderModel / removeProviderModel (nested model CRUD)
    • testProvider (optional key probe; returns suggested_models and never mutates the curated model list)
  • Types mirroring the backend contract: ModelProvider, ProviderModel { name, wire_api? }, WireApi, CreateProviderRequest, UpdateProviderRequest, ProviderModelPayload, TestProviderResponse. The provider view is masked — api_key_set only, no raw key and no secret_name.

Changed vs. the previous iteration

  • Replaced the ProviderConnection + validateConnection + createProfileFromConnection surface with provider CRUD + nested model CRUD.
  • testProvider replaces validateConnection; it offers an optional catalog suggestion and never implies the model list was overwritten.
  • Replaced connections-client.test.ts with providers-client.test.ts.

Testing

  • providers-client.test.ts (12 tests): each endpoint hits the right method/path/body, responses unpack correctly, id/model-name path encoding, and typed HttpError on non-2xx.
  • Full suite green (315 tests); tsc --noEmit and eslint clean.

Related PRs


This PR was created by an AI agent (OpenHands) on behalf of the user.

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Endpoint audit

⚠️ 14 actionable Agent Server contract divergence(s) · report-only

Contract: pinned release artifact

Category Count
Actionable client-only calls 7
Actionable server-only operations 7
Documented non-divergences 13
Agent Server contract operations 117
Audited handwritten client endpoints 126

Actionable client-only calls (7)

  • DELETE /api/llm/model-providers/{}
  • GET /api/llm/model-providers
  • GET /api/llm/model-providers/{}
  • PATCH /api/llm/model-providers/{}
  • POST /api/llm/model-providers
  • POST /api/llm/model-providers/{}/models
  • POST /api/llm/model-providers/{}/test

Actionable server-only operations (7)

  • GET /api/conversations/{}/events
  • GET /api/file/archive
  • GET /api/git/commits
  • GET /api/git/commits/{}/changes
  • GET /api/init
  • POST /api/conversations/{}/load_plugin
  • POST /api/init
Documented non-divergences (13)

Client calls intentionally absent from the filtered contract (11)

  • GET /
  • GET /alive
  • GET /health
  • GET /ready
  • GET /server_info

Reason: Operational Agent Server endpoints intentionally excluded from the filtered public release artifact.
Owner: OpenHands runtime maintainers

  • DELETE /api/meta-profiles/{}
  • GET /api/meta-profiles
  • GET /api/meta-profiles/{}
  • POST /api/meta-profiles/{}
  • POST /api/meta-profiles/{}/activate

Reason: Client-ahead API stacked on the pending Agent Server meta-profiles implementation.
Owner: OpenHands SDK maintainers
Tracking: OpenHands/software-agent-sdk#3744

  • POST /api/profiles/{}/validate

Reason: Client-ahead API stacked on the pending Agent Server pre-flight LLM validation endpoint.
Owner: OpenHands TypeScript client maintainers
Tracking: OpenHands/software-agent-sdk#4422

Server operations covered by an exposed browser URL (2)

  • GET /api/conversations/{}/workspace
  • GET /api/conversations/{}/workspace/{}

Reason: RemoteWorkspace.startWorkspaceSession exposes these authenticated URLs for browser iframe and file requests; they are not HttpClient method calls.
Owner: OpenHands TypeScript client maintainers

Add typed client methods for the new /api/llm/connections endpoints from
software-agent-sdk. Connect a vendor once with one key, pick from its model
catalog; the key is stored as a named secret server-side and never returned
(api_key_set only).

- models/api: ProviderConnection, CreateConnectionRequest,
  UpdateConnectionRequest, ValidateConnectionResponse types.
- LLMMetadataClient: listConnections / createConnection / getConnection /
  updateConnection (rotate key, rename, set models) / deleteConnection /
  validateConnection. Connection ids are URL-encoded in the path.
- Re-export the new types from the package index.
- Remove the stub src/llm/connections.ts (replaced by the real client methods).

Tests: 8 new tests covering each endpoint (method, path, body unpacking,
key rotation, id encoding). Full suite green: 311 passed. Lint clean (0
errors), build succeeds.

Release gate: bump @openhands/typescript-client version and publish to npm
before the OpenHands frontend consumes these endpoints.

Refs OpenHands/OpenHands#15492, Linear OSS-5295.

Co-authored-by: openhands <[email protected]>
…yped disconnect

- ValidateConnectionResponse gains a `verified` boolean so consumers can tell a
  real network check from a catalog-only lookup
- validateConnection accepts { live } and forwards ?live=true
- deleteConnection now returns DisconnectConnectionResponse (affected profiles)
  instead of void, matching the backend
- add createProfileFromConnection + request/response types for the
  'pick a model the provider offers' Agent Profile flow
- export the new types from the package entrypoint
- tests: live-flag query, profile-creation body, and a typed HttpError
  error-path assertion (status + parsed server body)

Co-authored-by: openhands <[email protected]>
@juanmichelini juanmichelini changed the title [draft] Client types/methods for provider connections (release gate) Typed client: Provider Connection methods + types (#15492) Aug 11, 2026
@juanmichelini juanmichelini changed the title Typed client: Provider Connection methods + types (#15492) Typed client: Model provider methods + nested-model types (#15492) Aug 14, 2026
Align the typed client with the reworked backend (software-agent-sdk#4455):
providers hold one key (named secret) and a nested, user-managed model list.

- api.ts: replace ProviderConnection/*Connection* types with ModelProvider,
  ProviderModel, Create/UpdateProviderRequest, ProviderModelPayload and
  TestProviderResponse (masked view: api_key_set only, no secret_name).
- llm-client.ts: replace the connection + validate + profile-from-connection
  methods with provider CRUD, nested model CRUD (add/update/remove) and
  testProvider (optional key probe; never mutates the curated model list),
  all under /api/llm/model-providers.
- index.ts: export the new provider types.
- Replace connections-client.test.ts with providers-client.test.ts (12 tests).

Refs OpenHands/OpenHands#15492.

Co-authored-by: openhands <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants