Skip to content

feat(core): read model reasoning from config - #55853

Merged
vimtor merged 4 commits into
devfrom
config-reasoning-options
Oct 16, 2026
Merged

vimtor merged 4 commits into
devfrom
config-reasoning-options

Conversation

@vimtor

@vimtor vimtor commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Why

Org admins can now set which reasoning controls a model accepts in the OpenCode Console (anomalyco/opencode-console#3690): none, fixed, effort levels, or a token budget. The Console sends these controls in the pulled config, but OpenCode had no config field for them. So a team couldn't fix a custom model's reasoning variants without writing raw request bodies for each provider.

What changes

  • Config: adds providers.*.models.*.capabilities.reasoning in models.dev v2's shape: { supported, toggle?, effort?, budget?: { min?, max? } }.
  • Variants:
    • When capabilities.reasoning is set, OpenCode builds the model's variants from it for the model's package. These replace the base variants.
    • supported: false, or supported: true with no controls ("fixed"), means no variants.
    • The default effort adds no variant, since it means the provider's own default.
    • Configured variants still apply on top.
  • Console config: the OpenCode Console provider applies the same reasoning and release date to the models it loads, so Console edits reach signed-in users. Before this, the Console provider kept the catalog variants.
  • Model metadata: the Console also sends metadata the 1.x config already had, so V2 reads it too:
    • releaseDate (YYYY-MM-DD or YYYY-MM) sets the model's release time.
    • capabilities.temperature records whether the model accepts a temperature. Model capabilities now carry it as optional metadata.
    • The reasoning field already worked through compatibility.reasoningField; the Console now sends it.
  • Generated files: regenerated the client types and OpenAPI files.
  • Docs: documented the field in Models and Providers.

Verification

  • bun run check passes.
  • Added tests for Variant.supports, for the config plugin with effort, fixed, and unsupported models, and for the release date, temperature, and reasoning field. Tests run in CI. Checked end to end against a local Console: a GPT-5.2 override of effort: ["low", "high"] gave exactly low and high variants, while the unchanged branch kept all five catalog levels.

Added by the opencode bot (AI-generated).

Related: #53202, #51846, #50257

Public API: adds the optional config key providers.*.models.*.capabilities.reasoning and the Config.Model.Reasoning schema to the OpenAPI spec and client types (backwards compatible)

@vimtor
vimtor force-pushed the config-reasoning-options branch from ec18200 to 4db586a Compare October 15, 2026 20:50

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found nothing that should block this. I ran serve from source on the base and on this branch with one config for a custom aisdk:@ai-sdk/openai provider and checked GET /api/model:

  • On the base, capabilities.reasoning is ignored and every model gets the full default variant list.
  • On this branch, effort: ["default","low","high"] gives low/high, and supported: true with no controls gives no variants. A model without reasoning keeps the default list.

The new tests in packages/core and the typecheck scripts in packages/core and packages/schema pass. The change reuses Variant.resolve the same way the models.dev loader does.

Public API: this adds the optional config key providers.*.models.*.capabilities.reasoning ({ supported, toggle?, effort?, budget?: { min?, max? } }). It also adds the schema Config.Model.Reasoning to the OpenAPI spec and the generated client types. Nothing is removed or renamed, so it is backwards compatible: existing configs behave as before. Model.mergeCapabilities still drops reasoning, so GET /api/model does not report capabilities.reasoning.

Related: #53202, #51846, #50257

@vimtor
vimtor force-pushed the config-reasoning-options branch from 4db586a to 7238523 Compare October 16, 2026 10:46
@vimtor vimtor changed the title feat(core): build variants from configured model reasoning feat(core): read model reasoning from config Oct 16, 2026
@vimtor
vimtor merged commit d889cb2 into dev Oct 16, 2026
21 checks passed
@vimtor
vimtor deleted the config-reasoning-options branch October 16, 2026 11:36
zhengkaics added a commit to zhengkaics/opencode that referenced this pull request Oct 17, 2026
Follow-up to the port, now layered on top of the rich
Config.Model.Reasoning that landed in anomalyco#55853:

- capabilities: mergeCapabilities accepts the rich config reasoning
  object and derives the runtime reasoning flag from its `supported`
  value, so a config-declared capability survives into Model.Info
- v1 migration: migrateModel keeps a declared reasoning flag by
  translating it to { supported } and includes reasoning-only models
  in the capabilities guard
- protocol/client: regenerate generated outputs (Model.Capabilities.reasoning)
- tests: v1 migration + config overlay coverage

Co-authored-by: hril3 <hril3@users.noreply.github.com>
zhengkaics added a commit to zhengkaics/opencode that referenced this pull request Oct 25, 2026
Follow-up to the port, now layered on top of the rich
Config.Model.Reasoning that landed in anomalyco#55853:

- capabilities: mergeCapabilities accepts the rich config reasoning
  object and derives the runtime reasoning flag from its `supported`
  value, so a config-declared capability survives into Model.Info
- v1 migration: migrateModel keeps a declared reasoning flag by
  translating it to { supported } and includes reasoning-only models
  in the capabilities guard
- protocol/client: regenerate generated outputs (Model.Capabilities.reasoning)
- tests: v1 migration + config overlay coverage

Co-authored-by: hril3 <hril3@users.noreply.github.com>
zhengkaics added a commit to zhengkaics/opencode that referenced this pull request Oct 28, 2026
Follow-up to the port, now layered on top of the rich
Config.Model.Reasoning that landed in anomalyco#55853:

- capabilities: mergeCapabilities accepts the rich config reasoning
  object and derives the runtime reasoning flag from its `supported`
  value, so a config-declared capability survives into Model.Info
- v1 migration: migrateModel keeps a declared reasoning flag by
  translating it to { supported } and includes reasoning-only models
  in the capabilities guard
- protocol/client: regenerate generated outputs (Model.Capabilities.reasoning)
- tests: v1 migration + config overlay coverage

Co-authored-by: hril3 <hril3@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant