feat(client): add missing agent-server endpoints and fix skills refresh#231
Closed
VascoSch92 wants to merge 3 commits into
Closed
feat(client): add missing agent-server endpoints and fix skills refresh#231VascoSch92 wants to merge 3 commits into
VascoSch92 wants to merge 3 commits into
Conversation
Cover agent-server REST endpoints that were unimplemented or mis-targeted by
the client (surfaced by the endpoint audit against the agent-server OpenAPI):
- GET/POST /api/init via a new InitClient (deferred-init / warm-pool servers),
wired into ConversationManager as the `init` namespace.
- GET /api/conversations/{id}/workspace and /workspace/{path} static workspace
file serving via ConversationClient.getWorkspaceRoot/getWorkspaceFile.
- GET /api/conversations/{id}/events server-side batch via
ConversationClient.batchGetEvents (distinct from the per-id getEvents loop).
- GET /api/bash/bash_events/ server-side batch via BashClient.batchGetEvents.
- POST /api/skills/installed/{name}/refresh — corrects refreshSkill from the
non-existent /update path to /refresh.
The batch return types use `(T | null)[]` instead of `Array<T | null>` so the
endpoint-audit's path extraction (which cannot parse the nested `>>` generic)
detects getConversations and the new batch methods.
Adds unit tests (mocked fetch) for every new method plus deterministic
integration contract guards against the pinned agent-server image.
Contributor
Endpoint audit❌ 7 off-contract call(s) — not on the agent-server · classifiers: cloud
❌ Not on agent-server (gated, 7)⛔ (no known backend) — served by no backend we can see (6)
|
The batchGetEvents methods sent event ids as query params, but the
agent-server's GET /api/conversations/{id}/events and GET
/api/bash/bash_events/ batch endpoints require the ids in the request
body, so the server returned 422 (missing required body).
fetch cannot send a body on a GET request (it throws), so route
GET-with-body requests through Node's http/https module while leaving the
fetch path untouched for every other request.
Update the conversation integration test to the real server contract:
unlike the bash endpoint, the conversation endpoint raises on unknown ids
rather than returning null, so round-trip a real event instead of
asserting missing-as-null. Update the unit tests to mock node:http and
assert the ids land in the body.
This was referenced Jun 29, 2026
Member
Author
|
Closing in favour of splitting this into one minimal PR per endpoint/feature, each carrying its own unit and integration tests:
The GET-with-body The two non-endpoint rows from this PR — the |
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
Adds client coverage for agent-server REST endpoints that the audit reported as missing (or that the client targeted incorrectly). Implementations follow the agent-server routers in
OpenHands/software-agent-sdk(verified against tag v1.29.0 — the pinned integration image).GET /api/initInitClient.getStatus()POST /api/initInitClient.initialize()(sendsX-Init-API-Key)GET /api/conversations/{id}/workspaceConversationClient.getWorkspaceRoot()GET /api/conversations/{id}/workspace/{path}ConversationClient.getWorkspaceFile()GET /api/conversations/{id}/events(batch)ConversationClient.batchGetEvents()GET /api/bash/bash_events/(batch)BashClient.batchGetEvents()POST /api/skills/installed/{name}/refresh/update)SkillsClient.refreshSkill()→/refreshGET /api/conversations(batch)GET /ServerClient.getRoot()Details
InitClient(newsrc/client/init-client.ts) wraps the deferred-init / warm-pool endpoints.POST /api/initauthenticates with the bootstrapX-Init-API-Keyheader (distinct from the per-sessionX-Session-API-Key). Exported fromclients.ts, model types (InitState/InitStatus/InitRequest) frommodels/api.ts, and wired intoConversationManageras theinitnamespace.Blob(call.text()for HTML/text), matchingFileClient.downloadTrajectory.refreshSkillpreviously POSTed to/api/skills/installed/{name}/update, which the agent-server does not expose — the route is/refresh. The mocked unit test asserting the old URL is updated.getConversations) now type the response as(T | null)[]instead ofArray<T | null>. This is behaviorally identical but lets theendpoint-auditpath extractor — which can't parse the nested>>generic — recognize these calls.Note on
GET /ServerClient.getRoot()already callsGET /, so the endpoint is functionally covered (the agent-server maps/to the sameget_server_infohandler as/server_info, whichgetServerInfo()also covers). The audit still lists it because itsPATH_LITmatcher only recognizes paths beginning with/api|/server_info|/alive|/health|/ready; a bare/is structurally undetectable without changing the audit script, which is out of scope here.Testing
src/__tests__/api-clients.test.ts, mockedfetch): new cases for theinitnamespace,BashClient.batchGetEvents,ConversationClient.batchGetEvents, the workspace serving methods, andInitClientget/post (header presence + omission). Full suite: 274 passing./refreshroute (404 for an uninstalled skill).bash.integration.test.tsalso exercises the new server-side bash batch endpoint.npm run build,lint(0 errors), andformat:checkall pass.