fix(small-model): send configured provider headers (#3214)

readProviderConfig read only options.baseURL and options.apiKey, and the
OpenAI-compatible dispatch hardcoded a bearer token, so provider
options.headers never reached the request. OpenCode sends those headers on
every chat turn, which left the small model authenticating differently from
the request path against the same URL.

Providers behind a gateway that authenticates on its own header, such as the
Ocp-Apim-Subscription-Key default of Azure API Management, answered 401 for
walkthroughs, session goal audits, titles and commit summaries while the same
model worked in chat.

Read options.headers alongside the API key, resolve {env:...} and {file:...}
in the values with the existing resolveConfigApiKey, and merge them into the
request after the bearer default so a gateway whose header is the credential
can override it.

Closes #3213
This commit is contained in:
Dmitrii
2026-08-28 23:46:05 +03:00
committed by GitHub
parent 8bd4995b8b
commit 3903cb53b1
3 changed files with 69 additions and 5 deletions
@@ -116,9 +116,11 @@ other runtime API.
endpoint, (3) the endpoint OpenCode resolved at runtime, or (4) the
provider's `api` field from the models.dev catalog. The credential follows
the same shape: config `options.apiKey`, then the runtime credential, then
the auth.json entry. Configured API keys honor OpenCode's `{env:NAME}` and
`{file:path}` substitutions; file contents and resolved credentials remain
server-side.
the auth.json entry. `provider.<id>.options.headers` is sent with the
request and overrides the bearer default, so gateways that authenticate on
their own header work here exactly as they do in a chat turn. Configured API
keys and header values honor OpenCode's `{env:NAME}` and `{file:path}`
substitutions; file contents and resolved credentials remain server-side.
- The runtime credential is refused for providers listed in
`OWN_CREDENTIAL_HANDLING`. Their branches need the stored entry rather than
a bearer token: the clearest case is the ChatGPT-plan `openai` login, whose