Skip to content

feat(openai): support adjusting thinking level for MiniMax-M3#3594

Merged
esengine merged 1 commit into
main-v2from
fix/minimax-thinking-rebased
Jun 8, 2026
Merged

feat(openai): support adjusting thinking level for MiniMax-M3#3594
esengine merged 1 commit into
main-v2from
fix/minimax-thinking-rebased

Conversation

@esengine

@esengine esengine commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Rebased @lightfront's #3432 onto current main-v2 and reconciled it with the reasoning-protocol refactor + the effort=auto handling that landed since it was opened (#3571).

What it does

Teaches the openai provider to speak MiniMax-M3's binary thinking knob (adaptive | disabled) for api.minimaxi.com (and *.minimaxi.com), mirroring the existing DeepSeek wire shape:

  • emits thinking.type = adaptive|disabled and omits reasoning_effort (M3 rejects it)
  • /effort exposes auto|adaptive|disabled (default adaptive); stale level names from other vendors map to the nearest valid M3 value
  • new host.go (IsDeepSeek/IsMiniMax) centralizes vendor-host detection

Reconciliation notes (vs the original)

  • Kept main-v2's reasoning_protocol machinery: minimax is gated by protocol == "" (like deepseek), so an explicit protocol override still wins.
  • Adopted IsDeepSeek from the new host.go and dropped the now-redundant local isDeepSeekBaseURL (identical semantics).
  • MiniMax routes through the isMiniMaxEntry fallback in EffortCapability / NormalizeEffort (it isn't a ReasoningProtocol value), leaving the deepseek/openai protocol paths intact.

Testing

  • go build ./..., go vet, go test ./internal/provider/openai ./internal/config all green (MiniMax + the existing DeepSeek/OpenAI/effort-auto tests).

Closes #3432

Original work by @lightfront.

MiniMax-M3 exposes a single binary thinking knob (adaptive|disabled)
on its OpenAI-compatible endpoint at api.minimaxi.com, but our
provider unconditionally emits reasoning_effort — which M3 rejects.
Detect api.minimaxi.com as a separate wire shape alongside
api.deepseek.com and:

  - emit thinking.type=adaptive|disabled in buildRequest
  - omit reasoning_effort entirely (M3 has no level scale)
  - translate /effort auto to 'adaptive' (the M3 default, since M3
    ships with thinking on out of the box and 'auto' semantically
    means 'don't override the model default')
  - map legacy level names from other vendors so a stale /effort
    value still resolves to a valid M3 level:
      off        → disabled  (retired DeepSeek 'no thinking' — M3
                              actually supports 'thinking off')
      low/medium/high → adaptive
      xhigh/max  → disabled
  - in NormalizeEffort, surface a MiniMax-specific usage hint
    (auto|adaptive|disabled) when an unknown level is supplied

internal/config/effort.go mirrors the change: M3 entries now expose
/levels=[auto,adaptive,disabled] with default=adaptive. Tests cover
the wire shape (TestBuildRequestMiniMaxThinking) and the
config-layer remap (TestNormalizeEffortMiniMax,
TestNormalizeEffortMiniMaxRejectsGarbage,
TestEffectiveEffortMiniMax).

Refactor: the host-matching logic was duplicated across
internal/provider/openai/openai.go (private *BaseURL helpers) and
internal/config/effort.go (private *Entry wrappers). Extract the
shared primitive into internal/provider/openai/host.go as
matchesVendorHost, plus thin exported wrappers IsDeepSeek and
IsMiniMax. The *Entry wrappers in effort.go now just gate on the
openai kind and delegate. Adding a new gateway is now a one-line
change in host.go rather than a four-line change across two files.

Add internal/provider/openai/host_test.go pinning the matching
rule (canonical hostname exact match, plus any subdomain of the
apex) directly at the source.
@esengine esengine requested a review from SivanCola as a code owner June 8, 2026 13:03
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development config Configuration & setup (internal/config) provider Model providers & selection (internal/provider) and removed v2 Go rewrite (1.x) — main-v2 branch, active development labels Jun 8, 2026
@esengine esengine merged commit 8b2028e into main-v2 Jun 8, 2026
10 checks passed
@esengine esengine deleted the fix/minimax-thinking-rebased branch June 8, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Configuration & setup (internal/config) provider Model providers & selection (internal/provider)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant