Skip to content

[FEATURE]: expose provider-specific reasoning/thinking field schemas for custom models #33013

Closed as not planned

Description

@woohahahaaa
  • I have verified this feature I'm about to request hasn't been suggested before.

Feature Request

OpenCode currently supports reasoning/thinking variants for many built-in providers through internal provider transforms. However, many third-party OpenAI-compatible APIs expose different request fields for enabling/disabling reasoning, and there is no documented/configurable schema for users to define these fields for custom providers/models.

Examples

OpenAI Reasoning Effort

{
  "reasoning_effort": "medium"
}

Supported values may include:

["none", "minimal", "low", "medium", "high", "xhigh"]

Claude / Anthropic adaptive thinking

{
  "thinking": {
    "type": "adaptive",
    "display": "summarized"
  },
  "output_config": {
    "effort": "high"
  }
}

Volcengine Ark / Doubao Coding Plan

{
  "thinking": {
    "type": "enabled"
  },
  "reasoning_effort": "medium"
}

Some models may require disabling thinking with:

{
  "thinking": {
    "type": "disabled"
  }
}

MiniMax

{
  "thinking": {
    "type": "adaptive"
  },
  "reasoning_split": false
}

Or disabled:

{
  "thinking": {
    "type": "disabled"
  }
}

Problem

The current documentation shows examples for OpenAI reasoningEffort and Anthropic thinking, but it does not explain how users should configure reasoning/thinking fields for custom providers where the required request fields differ.

For example:

  • OpenAI uses reasoning_effort or SDK-level reasoningEffort.
  • Anthropic uses thinking.type, thinking.budgetTokens, or adaptive thinking fields.
  • Volcengine Ark / Doubao may use both thinking.type and reasoning_effort.
  • MiniMax may use thinking.type and reasoning_split.
  • DashScope may require enable_thinking: true.

OpenCode already handles some of these internally in ProviderTransform, but users cannot easily define or inspect these mappings for custom providers.

Proposed Solution

Add a provider/model-level configurable reasoning schema, for example:

{
  "provider": {
    "volcengine": {
      "models": {
        "doubao-seed-coding": {
          "reasoning": {
            "variants": {
              "none": {
                "thinking": {
                  "type": "disabled"
                }
              },
              "medium": {
                "thinking": {
                  "type": "enabled"
                },
                "reasoning_effort": "medium"
              },
              "high": {
                "thinking": {
                  "type": "enabled"
                },
                "reasoning_effort": "high"
              }
            }
          }
        }
      }
    }
  }
}

Or expose a more generic field schema:

{
  "reasoningFields": [
    {
      "label": "Thinking state",
      "target": "thinking.type",
      "default": "disabled",
      "options": ["enabled", "disabled"]
    },
    {
      "label": "Reasoning effort",
      "target": "reasoning_effort",
      "default": "medium",
      "options": ["minimal", "low", "medium", "high", "max"],
      "enableWhen": "thinking.type != disabled"
    }
  ]
}

This could power:

  • /models or ctrl+t reasoning variants.
  • Custom provider configuration.
  • Documentation generation.
  • UI hints for supported thinking modes.

Benefits

  • Makes custom OpenAI-compatible providers much easier to configure.
  • Avoids hardcoding every provider/model in ProviderTransform.
  • Helps users understand whether /thinking only displays reasoning or actually enables model reasoning.
  • Provides a path for providers like MiniMax, Volcengine Ark/Doubao, DashScope, Zhipu, Kimi, etc. to define their own reasoning controls.
  • Keeps OpenCode compatible with rapidly changing third-party model APIs.

Related Current Behavior

OpenCode already contains provider-specific reasoning handling in packages/opencode/src/provider/transform.ts, including OpenAI, Anthropic, Google/Gemini, Bedrock, OpenRouter, DashScope, MiniMax, etc. This feature request is mainly about exposing a configurable/documented mechanism for custom providers and models instead of requiring source-code changes.

Activity

  1. github-actions commented on Jun 19, 2026

    @github-actions
    Contributor

    This issue doesn't fully meet our contributing guidelines.

    What needs to be fixed:

    • The issue title must start with [FEATURE]: (e.g., [FEATURE]: expose provider-specific reasoning/thinking field schemas for custom models)
    • The feature request template requires a verification checkbox confirming the feature hasn't been suggested before ("I have verified this feature I'm about to request hasn't been suggested before.")

    Please edit this issue to address the above within 2 hours, or it will be automatically closed.

    If you believe this was flagged incorrectly, please let a maintainer know.

  2. changed the title [-]Feature request: expose provider-specific reasoning/thinking field schemas for custom models[/-] [+][FEATURE]: expose provider-specific reasoning/thinking field schemas for custom models[/+] on Jun 19, 2026
  3. github-actions commented on Jun 19, 2026

    @github-actions
    Contributor

    Thanks for updating the issue! It now follows the contributing guidelines and feature request template. The needs:compliance label has been removed.

  4. Necmttn commented on Jun 21, 2026

    @Necmttn

    I would separate this into capability metadata instead of hard-coding provider transforms. Each custom model could declare request fields for reasoning/thinking, allowed values, disabled form, token-budget field, and response usage buckets. Then OpenCode can validate config before the first call and normalize telemetry as reasoning/thinking output without assuming OpenAI or Anthropic field names.


    Generated with ax.

  5. TensorTemplar commented on Jul 9, 2026

    @TensorTemplar

    The inline-tag case is an example of this that's currently unhandled: a self-hosted MiniMax-M3 on vLLM (OpenAI-compatible API) streams its reasoning inline in the content as <mm:think>…</mm:think> rather than on a reasoning_content field. Upstream only toggles M3 thinking on/off — it never parses those tags — so on vLLM the whole <mm:think> block leaks into the rendered message (same "reasoning doesn't display right" symptom as #31569 / #22684 / #20782).

    I took the capability-metadata direction @Necmttn described and prototyped it as an interleaved variant on the model capability:

    "interleaved": { "tag": "mm:think" }   // model emits reasoning inline wrapped in this tag
    • Response: wrap the model with extractReasoningMiddleware({ tagName }) so the block becomes a proper reasoning part shown separately.
    • Request: re-inline the stored reasoning wrapped in the same tag, since M3 expects it back interleaved.
    • Auto-detected for openai-compatible ids containing minimax-m3; otherwise opt-in via the config above.

    It's scoped to the inline-tag transport, not the full request-field schema this issue asks for but it slots into the same capability-metadata design. I've been running it locally against vLLM and cut a disclaimered fork release for testing simplicity: https://github.com/TensorTemplar/opencode/releases/tag/v1.17.15-minimax. Happy to open a PR if that's a direction the maintainers want.

  6. github-actions commented on Sep 8, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions