Skip to content

feat: add MetaProfilesClient and meta-profile types#212

Merged
juanmichelini merged 1 commit into
mainfrom
feat/meta-profiles-client
Jun 17, 2026
Merged

feat: add MetaProfilesClient and meta-profile types#212
juanmichelini merged 1 commit into
mainfrom
feat/meta-profiles-client

Conversation

@juanmichelini

Copy link
Copy Markdown
Contributor

Summary

Adds first-class support for the agent-server /api/meta-profiles endpoints (introduced in software-agent-sdk #3744) to the TypeScript client.

A meta-profile is a declarative model-routing configuration consumed by the classify_and_switch_llm tool: it names a classifier_model, a default_model, and a list of task classes, where every model reference is the name of a saved LLM profile.

Until now, consumers (e.g. agent-canvas) had to redefine these request/response interfaces locally and drive the raw HttpClient themselves. This PR moves the shapes into the shared client so they can be imported directly — the same pattern as ProfilesClient.

Changes

  • models/api.ts — add MetaProfile, MetaProfileClass, MetaProfileInfo, and the MetaProfileListResponse / MetaProfileDetailResponse / MetaProfileMutationResponse / ActivateMetaProfileResponse interfaces.
  • client/meta-profiles-client.ts — new MetaProfilesClient mirroring ProfilesClient (listMetaProfiles / getMetaProfile / saveMetaProfile / deleteMetaProfile / activateMetaProfile). Meta-profiles carry no secrets, so there is no X-Expose-Secrets handling.
  • conversation/conversation-manager.ts — expose a metaProfiles namespace and close it alongside the other clients.
  • clients.ts / index.ts — export the client, its options type, and the new API types.
  • Tests — 5 new cases covering each MetaProfilesClient method (endpoint, HTTP verb, percent-encoding, request body) plus a ConversationManager wiring assertion.

Verification

  • npm run build
  • npm run lint ✅ (0 errors; pre-existing warnings only)
  • npm run format:check
  • npm test ✅ — 229/229 unit tests pass (the one test-utils failure only occurs when AGENT_SERVER_URL is set in the shell; it passes in a clean env and is unrelated to this change)

Follow-up

Once released, agent-canvas (PR #1395) will drop its locally-defined interfaces and import them from here, mirroring ProfilesService.


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

Adds first-class support for the agent-server `/api/meta-profiles`
endpoints (introduced in software-agent-sdk PR #3744) so consumers no
longer have to redefine the request/response shapes or drive the raw
HttpClient themselves.

- models/api.ts: add MetaProfile, MetaProfileClass, MetaProfileInfo and the
  list/detail/mutation/activate response interfaces.
- client/meta-profiles-client.ts: new MetaProfilesClient mirroring
  ProfilesClient (list/get/save/delete/activate). Meta-profiles carry no
  secrets, so there is no X-Expose-Secrets handling.
- conversation-manager.ts: expose `metaProfiles` namespace and close it.
- clients.ts / index.ts: export the client, its options and the new types.
- tests: cover all five MetaProfilesClient methods (endpoint, verb,
  percent-encoding, body) and assert the manager wires the namespace.

Co-authored-by: openhands <openhands@all-hands.dev>

all-hands-bot commented Jun 17, 2026

Copy link
Copy Markdown

Review complete.

This review was performed through OpenHands Cloud Automation. You can log in and view the conversation here.

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Good taste — Elegant, minimal addition that follows established patterns exactly.

This PR adds MetaProfilesClient as a first-class citizen of the TypeScript client. The implementation is a clean mirror of ProfilesClient, the types are well-structured, all five CRUD+activate methods are tested, and the wiring into ConversationManager (construction + close()) is correct. No issues found.

A few observations worth noting for awareness (none blocking):

  • MetaProfileMutationResponse and ActivateMetaProfileResponse are structurally identical { name: string; message: string }. This is consistent with how ProfileMutationResponse and ActivateProfileResponse are handled and is a deliberate semantic distinction — fine as-is.
  • saveMetaProfile takes config: MetaProfile directly (no wrapper type), which correctly reflects that meta-profiles carry no secrets and need no include_secrets flag, unlike SaveProfileRequest for LLM profiles.
  • The test for activateMetaProfile correctly verifies the '{}' body, matching the same pattern used by ProfilesClient.activateProfile.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟢 LOW
    Pure additive change — new exports, new client class, new types, new tests. No existing interfaces or behaviour are modified. Risk is minimal.

VERDICT:
Worth merging: Core logic is sound, pattern is consistent, tests cover all methods.

KEY INSIGHT:
Strict adherence to the ProfilesClient pattern keeps the surface area of this PR minimal and the cognitive overhead for future maintainers near zero.

This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. View conversation

@juanmichelini juanmichelini merged commit c6c6d1a into main Jun 17, 2026
6 of 7 checks passed
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.

3 participants