Repository navigation
fix(core): don't enable catalog providers from setting-only config overrides - #59440
opencode-agent[bot] wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
The fix works. I ran opencode models from source with a config that only sets a timeout on openai. On the base it lists all 76 openai models with no credential; with this PR only the opencode models remain. The two new tests fail on the base and pass here, test/config/provider.test.ts passes (41 tests), and tsc -b in packages/core is clean.
The public API is unchanged: no config schema, SDK, HTTP or plugin changes.
One gap is worth addressing: a credential sent in a configured header doesn't count (see the inline comment).
| provider.activation = "enabled" | ||
| // A provider first declared here (including a `canonical` copy) or by an integration needs no connection. | ||
| // Overriding an existing provider's settings does not authenticate it unless the settings carry a credential. | ||
| if ( |
There was a problem hiding this comment.
Only settings.apiKey, authToken and accessToken count as a credential here. If someone points an existing catalog provider at a gateway and authenticates with a configured header (headers: { Authorization: "Bearer …" } or x-api-key), that provider was usable before this change but now disappears until they add a connection or a dummy apiKey. #42790 describes exactly that header-auth gateway setup, though for custom provider IDs. Should a configured auth header also count as a credential here, or is the regression intended? Either way, a shared helper with hasConfiguredAuth in model-resolver.ts would stop the two checks from drifting apart.
Problem
The config provider plugin set
activation = "enabled"on every provider entry in user and project config.Provider.snapshottreatsenabledas available whether or not there is a connection. So an entry that only tunes a catalog provider, for example{ "provider": { "openai": { "settings": { "timeout": 60000 } } } }made
openaiand its whole catalog show up as available with no key, even though requests still need one.Rule
overlayProvidernow only enables a provider when one of these is true:integrate(...)). This is unchanged: these providers stay enabled and bound to the integration's connection throughsourceConnection.settings.apiKey,settings.authTokenorsettings.accessToken, the same keys the model resolver treats as configured auth. These providers can authenticate, so they stay enabled. This matches the behavior before activation was introduced, when a stringsettings.apiKeymade a provider available.In every other case the existing provider keeps its activation (for example
autofrom models.dev, orenabledfrom a local discovery plugin). It still needs a real connection.Edge cases:
canonicalcopies under a new ID ({"my-openai": {"canonical": "openai"}}) count as new providers and are enabled, as before.modelson an existing provider does not enable it. Aliases onopenaistill need anopenaiconnection.Tests
auto, is unavailable without a connection, and becomes available once a key credential exists. A custom config provider and acanonicalcopy are available with no connection.apiKeyon a catalog provider enables it; an emptyapiKeydoes not.bun test test/config/provider.test.ts: 41 pass.packages/coresuite only fails in host-environment tests (ShellTool env, test-env isolation, flock contention). Those also fail onorigin/devon this host.bun run typecheckinpackages/coreis clean, and oxlint is clean on the touched files.Visual
Requested by: @rekram1-node (Aiden Cline via Slack)
Added by the opencode bot (AI-generated).
Fixes #54686
Related: #42790