Repository navigation
Description
I'm trying to use my own model provider (an OpenAI-compatible endpoint) together with plugins that make their own copilot -p calls from hook processes, and I keep running into what looks like a gap in how BYOK mode gets activated.
copilot help providers says BYOK is activated by the COPILOT_PROVIDER_BASE_URL env var. I was hoping providers.json would work as the file-based equivalent, since it already accepts a static apiKey/bearerToken (what #4936 and #5287 are about). Mine looks like this:
{
"providers": [
{ "name": "myprov", "type": "openai", "wireApi": "responses",
"baseUrl": "https://api.example.com/v1", "apiKey": "<redacted>" }
],
"models": [
{ "provider": "myprov", "id": "mymodel", "modelId": "mymodel", "wireModel": "mymodel" }
]
}But with that in place and no COPILOT_PROVIDER_* env vars, this:
copilot -p "Reply with exactly: OK" --model mymodel --output-format json
gives me:
session.info {"infoType": "model_unavailable", "message": "Model \"mymodel\" is no longer available. Using \"claude-sonnet-5.5\" instead."}
model.call_final_result {"model": "claude-sonnet-5.5", "isByok": false, "result": "success"}
So the --model I asked for quietly gets dropped and the request runs on my Copilot subscription instead. If I delete providers.json the same command fails loudly ("Model "mymodel" from --model flag is not available"), so the file is being read and the model is recognized — it's just unusable unless the env var flips BYOK on.
When I do set COPILOT_PROVIDER_BASE_URL (plus COPILOT_PROVIDER_TYPE / _WIRE_API), the request finally goes to my provider ("isByok": true) — but the apiKey sitting in providers.json still isn't used. The request goes out unauthenticated and I get session.error: "Authentication failed with provider at … (HTTP 401)". Only COPILOT_PROVIDER_API_KEY / _BEARER_TOKEN from the environment authenticate.
This matters for me beyond interactive use: plugins that call copilot -p from hook processes (I use microsoft/TokenEconomizer, whose loop guard and fact proposer work exactly this way) can't reach BYOK at all, because hooks don't inherit the session's COPILOT_PROVIDER_*. Before I figured out what was going on I got "not signed in" errors; after "fixing" it with providers.json my calls silently started billing my Copilot subscription instead of my own provider, which honestly feels worse.
What I'd love to see:
providers.jsonalone activates BYOK (env vars keep working as an override)- or hooks get the
COPILOT_PROVIDER_*variables, orproviders.jsongrowsapiKeyCommandas Allow a credential command in providers.json and managed settings so BYOK providers work without a per-invocation launcher #4936 asks - and either way, an explicit
--modelthat can't be honored should error out rather than swap in a subscription model
Tested on 1.0.105 (saw the same on 1.0.92), macOS arm64. Related: #4936, #5287, #4001.
Activity