agent host: route Claude through CAPI's user-discovered Bearer auth (#316695)
* agent host: route Claude through CAPI's user-discovered Bearer auth Replace CopilotApiService's fictitious /copilot_internal/v2/token mint flow with what the @github/copilot CLI actually does: discover the user's CAPI endpoint via GET /copilot_internal/user, then send the GitHub user token directly as Authorization: Bearer to /v1/messages and /models. Empirically verified against github/copilot-agent-runtime@8f7f8d3: - fetchCopilotUser at src/core/github/gitHubApi.ts:384-401 GETs /copilot_internal/user with Bearer <user-token>. - The response.endpoints.api is fed through capiClient.updateDomains and used as the baseURL for the Anthropic SDK (src/model/capi/copilot-anthropic-client.ts:155-182). - The Anthropic SDK is constructed with authToken = <user-token>, so /v1/messages also gets Bearer <user-token>. Net effect for the agent host: - Claude tests now work with a vanilla `gh auth token` (previously required a Copilot-OAuth token captured from VS Code's GitHub auth provider). - Enterprise users (where endpoints.api -> api.enterprise.githubcopilot.com) work without any extra config. - One round-trip removed per cold start (no separate session-token mint). Test changes: - copilotApiService.test.ts: rename Token Minting -> Endpoint Discovery, drop two tests that asserted on server-supplied refresh_in/expires_at (no longer applicable), update auth-header assertions to expect the user token verbatim. - claudeRealSdk.integrationTest.ts: drop AGENT_HOST_REAL_SDK_CLAUDE opt-in env var (no longer needed) and rewrite the auth section of the docstring. Verified locally: - copilotApiService unit tests: 82/82 pass. - Copilot real-SDK integration suite: 12/12 pass. - Claude real-SDK integration suite (with `gh auth token` only): 6/6 active pass; 3 pending (worktree, subagents, plan-mode \u2014 capability-flag-gated, unchanged from previous PR). * agent host: per-token CAPIClient to avoid endpoint/token race Address review feedback on #316695: the previous version mutated a single shared CAPIClient via updateDomains while allowing discovery for different GitHub tokens to run concurrently. If token A discovered endpoint A and token B discovered endpoint B before A's request fired, A's request could be routed to endpoint B while still carrying A's bearer token. Fix by caching a separate CAPIClient per GitHub token (with the same fixed TTL as before). The token-independent parts (extensionInfo, machineId/deviceId, userUrl) are still memoized once via _capiBasePromise so we don't re-derive them on every cache miss. * agent host: drop dev-stub URLs no longer needed after _mintToken removal These two URLs were added in #316532 only to keep the now-removed CopilotApiService._mintToken from hitting 'Failed to parse URL from undefined' in dev builds. With this PR routing Claude through /copilot_internal/user (hardcoded), neither URL is referenced by the agent host any more, so the dev stub no longer needs them.
T
Tyler James Leonhardt committed
712b46f6a58c726756d2aff481a619e34a0ab75f
Parent: eb840b1
Committed by GitHub <noreply@github.com>
on 5/16/2026, 12:04:44 AM