feat(acp): AcpClient.getAuthStatus for /api/acp/auth-status#196
feat(acp): AcpClient.getAuthStatus for /api/acp/auth-status#196simonrosenberg wants to merge 1 commit into
Conversation
Adds a thin client for the agent server's ACP auth-status probe endpoint
(software-agent-sdk #3452), so the agent-canvas onboarding can detect an
existing subscription/login instead of unconditionally asking for an API key.
- `AcpClient.getAuthStatus(server)` → `GET /api/acp/auth-status?server=<key>`,
returning `ACPAuthStatusResponse { server, status, auth_methods, agent_name,
agent_version, detail }` where `status ∈ {authenticated, unauthenticated,
unknown}`.
- `ACPAuthStatusValue` / `ACPAuthStatusResponse` types mirror the server model.
- Exported from `clients.ts` (+ `AcpClientOptions`) and `index.ts`.
- Unit tests cover authenticated, unknown-without-throw, and the 422
unknown-provider path.
Refs OpenHands/agent-canvas#964
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
✅ Review complete. This review was performed through OpenHands Cloud Automation. You can log in and view the conversation here. |
all-hands-bot
left a comment
There was a problem hiding this comment.
This is a clean, focused addition that follows the established client pattern faithfully. The types are well-documented, the implementation is minimal and correct, and the three test cases cover the meaningful behavioral branches. A couple of minor observations inline.
This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. View conversation
|
|
||
| const client = new AcpClient({ host: 'http://example.com' }); | ||
| await expect(client.getAuthStatus('nope')).rejects.toMatchObject({ status: 422 }); | ||
| }); |
There was a problem hiding this comment.
🟡 Suggestion: The three tested cases cover authenticated, unknown, and 422. Consider adding a test for the unauthenticated status to complete the coverage of all three ACPAuthStatusValue variants — its behaviour at the client layer is identical to authenticated (the response object is returned as-is), but it would confirm the enum round-trip and make the test suite exhaustive:
| }); | |
| }); | |
| it('AcpClient.getAuthStatus returns unauthenticated without throwing', async () => { | |
| global.fetch = jest.fn().mockResolvedValue( | |
| new Response( | |
| JSON.stringify({ | |
| server: 'claude-code', | |
| status: 'unauthenticated', | |
| auth_methods: ['login'], | |
| agent_name: 'claude-code-acp', | |
| agent_version: '1.2.3', | |
| detail: null, | |
| }), | |
| { status: 200, headers: { 'content-type': 'application/json' } } | |
| ) | |
| ) as typeof fetch; | |
| const client = new AcpClient({ host: 'http://example.com' }); | |
| const result = await client.getAuthStatus('claude-code'); | |
| expect(result.status).toBe('unauthenticated'); | |
| expect(result.auth_methods).toEqual(['login']); | |
| }); |
| baseUrl: this.host, | ||
| apiKey: this.apiKey, | ||
| timeout: options.timeout || 60000, | ||
| }); |
There was a problem hiding this comment.
🟡 Suggestion: options.timeout || 60000 is consistent with the pattern used across all other clients in this codebase (e.g. VSCodeClient, DesktopClient). If the project ever adds a lint rule preferring ?? over || for default-value assignments, this and its siblings would need updating together — but that is out of scope here.
Summary
TypeScript-client side of the ACP subscription/login detection feature (OpenHands/agent-canvas#964). Adds a thin client for the new agent-server endpoint introduced in software-agent-sdk#3452, so the agent-canvas onboarding can show "✓ you're already logged in" instead of unconditionally asking for an API key.
Changes
AcpClient(src/client/acp-client.ts) withgetAuthStatus(server)→GET /api/acp/auth-status?server=<key>, returning the typedACPAuthStatusResponse.ACPAuthStatusValue('authenticated' | 'unauthenticated' | 'unknown') andACPAuthStatusResponse({ server, status, auth_methods, agent_name, agent_version, detail }) insrc/models/api.ts, mirroring the server model.clients.ts(AcpClient+AcpClientOptions) andindex.ts(the two types).api-clients.test.ts: authenticated probe (asserts URL/query param + session-key header),unknownreturned without throwing, and a422for an unknown provider.The endpoint always responds
200with astatusofauthenticated/unauthenticated/unknown(a probe that can't run isunknown, not an HTTP error), so a caller can mapstatus1:1 onto the canvasuseAcpAuthStatushook.Consumed by
agent-canvas PR (wires
useAcpAuthStatusto this endpoint). The agent-server endpoint lands in software-agent-sdk#3452.Refs OpenHands/agent-canvas#964
🤖 Generated with Claude Code