Add opt-in GitHub Copilot SDK transport for @theia/ai-copilot#17629
Draft
jdubois wants to merge 1 commit into
Draft
Add opt-in GitHub Copilot SDK transport for @theia/ai-copilot#17629jdubois wants to merge 1 commit into
jdubois wants to merge 1 commit into
Conversation
Add an experimental, opt-in transport for `@theia/ai-copilot` that routes model discovery and chat through the official Copilot CLI via `@github/copilot-sdk`, instead of the direct REST API. The direct REST path sends the raw `gho_` OAuth token without the `Copilot-Integration-Id`/`Editor-Version` headers GitHub uses to gate model access, so only a baseline model set (e.g. GPT-4o) is exposed. The SDK/CLI is a recognized integration and surfaces the full current model lineup. Scope (gated behind the `ai-features.copilot.useSdk` preference, default off): - model discovery via `CopilotClient.listModels()` - single-turn streaming chat with all tools disabled and permission requests rejected (the CLI owns its own agent loop, incompatible with Theia's model-as-a-function + Theia-driven tool loop) New (node): - `copilot-sdk-mappers.ts` (+ spec): pure, testable model-id selection and message->prompt flattening (type-only SDK import) - `copilot-sdk-client-provider.ts`: token-keyed CLI client lifecycle - `copilot-sdk-language-model.ts`: streaming session -> Theia stream bridge, terminating on `session.idle`/`session.error`/cancellation Wiring: `useSdk` preference, manager branches discovery + model class on the flag, DI binding, frontend rebuilds the model set on toggle. README documents the mode and its known limitations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
Thanks a lot for putting this together. I haven't gone through the details properly yet, but wanted to reply right away to say we really appreciate your thorough investigation and write-up. We'll also keep looking into the OAuth App entitlement angle and follow up on that, since that caveat seems like it could point to the real root cause. I'll come back with more substantive feedback once I've had a proper look. Thanks again! |
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.
What it does
Project leads reported that the
@theia/ai-copilotintegration "works, but only older models (e.g. GPT-4o) are available to users." This PR adds an opt-in transport that routes the extension through the official Copilot CLI via@github/copilot-sdk, as an alternative to the existing direct-REST path, so model discovery and chat go through a first-party recognized Copilot integration.The new path is gated behind a preference (
ai-features.copilot.useSdk, default off), so existing behavior is unchanged unless a user explicitly enables it. Scope is deliberately narrow:CopilotClient.listModels()(returns a curated, deduplicated chat-model list with policy state).Design notes:
copilot-sdk-mappers.ts(pure, unit-tested model-id selection + message-to-prompt flattening; type-only SDK import),copilot-sdk-client-provider.ts(token-keyed CLI client lifecycle), andcopilot-sdk-language-model.ts(bridges SDK session events to Theia stream parts, terminating onsession.idle/session.error/ cancellation).LanguageModelimplementation on theuseSdkflag; the frontend rebuilds the Copilot model set when the preference is toggled.Honest caveat on the root cause (please read): A live experiment during development calls into question the simple "REST transport is limited to old models" framing. Calling the raw REST endpoint
GET https://api.githubcopilot.com/modelswith a capablegho_token already returns the full modern lineup (gpt-5.5, claude-opus-4.8, gemini-3.1-pro-preview, ...), in fact more entries thanlistModels(). The two paths differ mainly in curation (REST returns the raw catalog including embeddings and legacy IDs; the SDK returns a curated chat list). This strongly suggests the "only GPT-4o" symptom is tied to the entitlement of Theia's own OAuth App (clientId: Ov23liS2vINy9VOAweyv) rather than the REST-vs-SDK transport itself. The SDK likely helps in production because the@github/copilotCLI authenticates as a first-party integration (token exchange + integration headers), but this has not been confirmed against a token minted by Theia's OAuth App.How to test
Offline verification (done):
npx lerna run compile --scope @theia/ai-copilotnpx lerna run lint --scope @theia/ai-copilotnpx lerna run test --scope @theia/ai-copilot(29 passing, including 10 newcopilot-sdk-mappersunit tests)Manual / interactive:
"ai-features.copilot.useSdk": truein preferences.Note: the live chat path could not be end-to-end tested in CI here (requires an authenticated CLI). The model-discovery comparison above was validated with a standalone
listModels()run.Follow-ups
/modelswith it, to verify whether that app is under-entitled.copilot_internal/v2/tokenexchange plusCopilot-Integration-Id/Editor-Versionheaders (and/or a registered integration id). This would avoid the heavy@github/copilotCLI dependency (native binaries for all platforms are added to the lockfile).Signed-off-byline to satisfy the Eclipse Contributor Agreement (ECA) check.Breaking changes
N/A. The new behavior is fully opt-in and off by default.
Attribution
N/A
Review checklist
nlsservice (for details, please see the Internationalization/Localization section in the Coding Guidelines)Reminder for reviewers