Skip to content

feat(opencode-go): add top-level reasoning_effort support for DeepSeek models #21577

@Caio-Sc

Description

@Caio-Sc

Feature Description

When using DeepSeek models (e.g., deepseek-v4-flash, deepseek-v4-pro) via the opencode-go provider, the reasoning_effort parameter is not passed as a top-level API kwarg. DeepSeek requires reasoning_effort at the top level of the request body and uses "max" as its highest reasoning level (vs OpenAI "xhigh").

Currently, only LM Studio and Kimi/Moonshot have top-level reasoning_effort support in agent/transports/chat_completions.py. opencode-go is missing.

Motivation

Without this, /reasoning xhigh doesn't work properly with opencode-go + DeepSeek — the reasoning effort falls back to the default instead of respecting the user's configuration.

Proposed Solution

Add a block in build_kwargs() in agent/transports/chat_completions.py (after the LM Studio block, before extra_body assembly) that:

  1. Checks params.get("is_opencode_go", False)
  2. Maps Hermes effort levels (minimal, low, medium, high, xhigh) to DeepSeek-compatible values
  3. Maps xhigh → max (DeepSeek's highest level, analogous to Claude thinking mode's max budget)
  4. Sets api_kwargs["reasoning_effort"] as a top-level parameter

And in run_agent.py, detect the opencode-go provider by host matching opencode.ai + provider string "opencode-go".

Implementation Reference

This is the exact patch we have been carrying downstream:

run_agent.py — add detection after _is_lmstudio:

_is_opencode_go = (
    base_url_host_matches(self._base_url_lower, "opencode.ai")
    and self.provider == "opencode-go"
)

Then pass is_opencode_go=_is_opencode_go in the params dict to the transport.

agent/transports/chat_completions.py — add after the LM Studio block:

# opencode-go: top-level reasoning_effort with DeepSeek effort mapping.
if params.get("is_opencode_go", False):
    _oc_thinking_off = bool(
        reasoning_config
        and isinstance(reasoning_config, dict)
        and reasoning_config.get("enabled") is False
    )
    if not _oc_thinking_off:
        _oc_effort = "medium"
        if reasoning_config and isinstance(reasoning_config, dict):
            _e = (reasoning_config.get("effort") or "").strip().lower()
            if _e in ("minimal", "low", "medium", "high"):
                _oc_effort = _e
            elif _e == "xhigh":
                _oc_effort = "max"
        api_kwargs["reasoning_effort"] = _oc_effort

Alternatives Considered

  • Using extra_body.reasoning — but DeepSeek via opencode-go expects reasoning_effort at the top level of the request, not nested in extra_body.
  • Generalizing the existing supports_reasoning path — would conflict with how other providers handle the field (some expect it in extra_body, others at top level). The opencode-go case is distinct.

Environment

  • opencode-go provider with DeepSeek models (deepseek-v4-flash, deepseek-v4-pro)
  • Hermes agent/transports/chat_completions.py v2026.4.30

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havecomp/agentCore agent loop, run_agent.py, prompt builderprovider/deepseekDeepSeek APIsweeper:implemented-on-mainSweeper: behavior already present on current maintype/featureNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions