Repository navigation
BYOK Support for Copilot Agent Host Harness #340335
Description
Environments
Environments- Local (Same Machine)
- Remote
- WSL
- SSH
- Dev Containers
- Tunnels
- Web Socket
Status
- 🟢 Local
- Local agent host supports BYOK models from in-built and extension contributed models using a proxy from the agent host
- 🔴 Remote
Invariants
- Multi Surface must work (VS Code and any other Copilot SDK consumer)
- Multi device should work (Local and remote environments with multiple clients)
Note: Roaming is not required. if you set up BYOK on one machine, it is not expected to automatically propagate credentials to other machines
Problem
1. Dependence on the Extension Host
The existing BYOK support is dependent on the existence of the extension host with the support of
- In-built BYOK providers
- Extension contributed BYOK providers
Support in the Copilot Harness should enable users to use the same BYOK configuration across all Copilot SDK surfaces, and that can not happen with the dependence on the current extension host.
2. Continuity across Clients
Currently, the Client connecting to the Agent Host owns and manages the BYOK models.
To maintain continuity across clients (remotely) connecting to a single agent host, the models must be provided from and be owned by the Agent Host itself.
eg:
Client Aconnects to Agent Host and starts aSession Ausing modelBYOK Model AClient Bconnects to Agent HostClient Adisconnects
Client Bshould be able to continueSession AwithBYOK Model A
This is not possible today as the client's extension host runs the inference to model providers.
Proposed Solution
Support BYOK through Model Providers configured in GitHub Copilot Plugins.
This will enable:
- The Agent Host to own and manage Model Providers
- enables continuity across clients
- Multiple SDK Surfaces to configure BYOK models the same way (eg: GitHub Copilot App, Copilot CLI, etc)
This will also make configuring models a 'Customization' concept, which conceptually makes sense.
Tasks
- Add support for GitHub Copilot Plugins to provide Configurable Model Providers
- Add support for plugins to run outside the scope of sessions
- Model Providers should be able to provide models across all sessions and not need to be started per session
- Add support for plugins to specify that it provides models in the manifest
- Add support for plugins to run outside the scope of sessions
- Create popularly used Model Provider Plugins for users to migrate to
- Create an experience in VS Code to configure Plugin-provided model providers Locally
- Create an experience in VS Code to configure Plugin-provided model providers Remotely
Activity
khanhkit commentedon Oct 9, 2026
I hit the same remote-continuity problem while running Copilot Agent Host through code-server/web and have a working implementation/proof-of-concept that may be useful as reference for this issue.
The failure mode matches the issue exactly: a BYOK turn routed through the renderer/extension-host bridge is tied to the client lifecycle, so a hard reload or full tab/browser disconnect can kill active inference even though the server-side Agent Host remains alive.
What I validated:
2a59476c9bfcb90b3ddc372c36762471b7dfad1c) and reran the targeted contracts:build:vscode/core-ci, code-server build, and release all pass; exact release verification is 5897/5897 files.The proof-of-concept takes a conservative approach:
Reference implementation and motivation are currently visible in coder/code-server#8047. The code-server maintainer suggested upstreaming this directly because the problem should apply equally to Codespaces / VS Code Web.
I see this issue proposes Plugin-provided configurable model providers, which is a broader and cleaner long-term ownership model than my direct-descriptor bridge. I do not want to open a competing PR blindly. If useful, I can split out the validated pieces/tests from the proof-of-concept, or adapt them to the plugin-provider direction here.
khanhkit commentedon Oct 9, 2026
One additional finding while aligning the PoC with the Option B / plugin-provider direction here: the Copilot SDK/runtime substrate is already much closer to this design than the current VS Code integration suggests.
In the SDK bundled with the validated VS Code 1.141 candidate, the experimental session API already exposes:
session.providers.getCatalog / discover / getStatus / models.list / models.prepareConfigurationbuiltIn | configured | extension | custom, with stable opaqueadapterId/ owner attributionautomatic | configuredOnly | explicit, network scope, input requirements, and trust requirementssession.provider.add / sync / withdrawfor the per-session selectable provider/model registryproviderToken.getTokenfor on-demand bearer/OAuth tokens; the token callback stays SDK-side rather than being serializedThe generated contract for
provider.withdraweven explicitly notes that unrelated registry entries may have been added by “a plugin callingprovider.addat runtime”.VS Code already supplies a connection-level
extensionLaunchProviderbefore sessions are created. Its Agent Host resolver can launch trustedextension.mjsentrypoints fromuser/pluginsources through the bundled SDK bootstrap, so the process-lifecycle substrate also appears to exist.What I do not see in current VS Code
mainis the product integration for this provider surface: there are no callers ofsession.providers.*, andPluginComponentstill covers commands/skills/agents/rules/hooks/MCP/automations but no model-provider component. An isolated tokenless 1.141 runtime session also returns an empty provider catalog with no provider plugin/config present.So I would no longer upstream the PoC's credential-bearing
syncEphemeralByokModelstransport as the target architecture. A cleaner split appears to be: provider plugin/runtime owns the adapter and discovery/configuration, VS Code consumes the catalog/configuration plan, and the preparedNamedProviderConfig+ProviderModelConfigis applied throughsession.provider.add.The reusable pieces from the PoC are mainly the renderer-detach continuity contract, capability/fallback regressions, and credential redaction/no-persistence tests. I’ll keep the code-server implementation as reference evidence and wait for owner guidance on which VS Code-side slice is useful before opening a competing PR.
khanhkit commentedon Oct 10, 2026
Follow-up from current
main/@github/copilot-sdk 1.0.19-preview.0: I was able to close one uncertainty from my previous comment with an isolated runtime probe using the same extension bootstrap contract VS Code installs.The extension process successfully executed:
extension.mjs -> joinSession() -> session.rpc.provider.add({ providers, models }) -> session.rpc.model.list()and
model.listreturned the newly registeredplugin-proof/proof-model. The probe used a loopback-unused endpoint, no real credentials, and performed no inference, so this proves the plugin-to-session provider registration/control-plane path only (not provider inference).That makes the smaller architecture clearer: VS Code does not need to reproduce the earlier renderer credential/direct-provider bridge just to register plugin-owned BYOK models. The remaining gap for #340335 is provider-specific discovery/configuration/lifecycle outside an already-created session, plus a safe way to request provider plugin extensions without implicitly broadening arbitrary project/user extension execution. Today the public SDK still has global
extensions.*, while provider catalog/configuration remains undersession.providers.*; VS Code's session config also currently tiesrequestExtensionsto the canvas runtime gate.I would therefore avoid a broad
requestExtensions = trueworkaround and keep provider/model/credential semantics in the runtime/plugin owner. Once a provider-specific/global lifecycle contract exists, the VS Code-side delta should be much smaller than the reference code-server PoC.Additional isolation finding (2026-10-10): I tested the coarse extension gate directly. With the same Agent Plugin under
com.github.copilot/extensions/,requestExtensions: falseproduced no launch;requestExtensions: truelaunched it andprovider.addsucceeded. When user + project + plugin extensions were all discoverable, the connection-global launch provider could deny user/project and launch only the plugin.The remaining problem is concurrency/session ownership: the released
ExtensionLaunchProviderResolveRequestcontainsid/name/modulePath/sourcebut nosessionId. Since the resolver is connection-global, a process-wide “canvas enabled” flag/count cannot safely distinguish a plugin-only BYOK session from another concurrent canvas-enabled session. This is not hypothetical:github/copilot-sdk#2637previously prototyped exactly the stronger contract (sessionId,defaultLaunch, explicit deny), andmicrosoft/vscode#335951used exact-session launch authorization. That SDK PR was closed and current SDK main (snapshot for CLI1.0.96-2) is back to the simpler request shape; npm1.0.20-preview.2is the same in this respect.So the minimal safe VS Code change appears dependency-blocked on restoring an equivalent session-scoped launch-admission primitive (or a session-level extension-source allowlist). Without that, simply enabling
requestExtensionsfor provider plugins risks broadening project/user extension execution across concurrent sessions. I am intentionally not proposing that workaround.Clarification against this issue's stated target: the
sessionIdlaunch contract above would only make a session-extension workaround isolatable. The issue explicitly calls for model-provider plugins to run outside the scope of sessions and provide models across all sessions. I therefore do not think restoring session-scoped launch admission is the target solution for #340335; the probe is useful mainly because it rules outrequestExtensions: trueas a safe/minimal substitute. The actual dependency remains the runtime/plugin-level global provider lifecycle + manifest declaration described in the task list, after which VS Code should only need the configuration UX/integration slice.