Skip to content

BYOK: providers.json is ignored without COPILOT_PROVIDER_BASE_URL — no file-based activation; --model silently substitutes a subscription model #5343

Open

Description

@doggy8088

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:

Tested on 1.0.105 (saw the same on 1.0.92), macOS arm64. Related: #4936, #5287, #4001.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:configurationConfig files, instruction files, settings, and environment variablesarea:modelsModel selection, availability, switching, rate limits, and model-specific behavior

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions