fix(mimo): MiMo 2.5 thinking loop fix + Go gateway workaround (#36) - #82
Merged
Conversation
MiMo 2.5 / 2.5 Pro can enter an infinite reasoning loop when reasoning_effort is set without a token budget cap. The model keeps generating thinking tokens indefinitely, ignoring idle timeout (2 min) since the stream stays active — user must wait up to 10 min total timeout. Fix: - src/thinking.ts: add budget_tokens per effort level (low=8K, medium=16K, high=32K) alongside reasoning_effort in the MiMo payload - src/retry.ts: add handler for HTTP 400 'budget_tokens' rejection so the extension gracefully falls back to reasoning_effort-only if the gateway doesn't support the field - docs/issues/36-20260723-mimo-thinking-infinite-loop.md: issue documentation Closes #36
Moves the MiMo budget_tokens + Go gateway workaround entries from [Unreleased] to the active [0.4.2] release section. Updates devlog with full session handoff, issue #36 analysis, and web research findings (upstream #37635, #35209, #36354). Updates issue doc with deep-dive root cause linking the Go gateway bug. Generated VSIX: opencode-copilot-chat-0.4.2.vsix (116 files, 1.07 MB) Installed locally: ltmoerdani.opencode-copilot-chat@0.4.2
MiMo model-level reasoning loop still occurs even with budget_tokens cap and treatReasoningAsContent workaround — model generates identical fragments indefinitely until budget runs out. Add two guards in OpenAiResponseExtractor: - Char budget: suppress if >2000 reasoning chars emitted as visible text without a content field appearing - Suffix repetition: suppress if same 40-char suffix repeats across 6+ consecutive reasoning chunks When triggered, a visible warning is emitted: '[MiMo seems stuck in a reasoning loop — output suppressed]' and further reasoning chunks are silently dropped until the stream ends (via budget_tokens). Rebuilt + reinstalled VSIX 0.4.2.
…#36) Root cause was two distinct problems: 1. Go gateway bug #37635 — ALL streaming output goes into reasoning_content instead of content. When MiMo thinking is OFF, the answer text gets swallowed by the thinking panel. 2. Model-level reasoning loop — MiMo 2.5 stuck in self-referential CoT, generating same fragments indefinitely. Three-layer fix applied: - budget_tokens cap per effort level (8K/16K/32K) in thinking.ts - treatReasoningAsContent workaround: ONLY activates when Go gateway AND reasoning_effort is NOT in body (MiMo thinking OFF). When thinking IS on, reasoning_content is genuine CoT → thinking panel. - Suffix-repetition detection in handleReasoning(): same 40-char suffix 6+ times → suppress thinking parts + emit warning. Key regression fixes in this commit: - Removed contentAfterReasoning guard (DeepSeek/GLM/Kimi legitimately use reasoning_content then content — this is normal, not degradation) - Removed shouldSuppressTextEmit (false-positived on all reasoning models, not just MiMo) - Reverted extractStreamParts delta block to main behavior Upstream issue #37635 still open (assigned MrMushrooooom). Workaround can be removed when gateway bug is fixed server-side.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix MiMo 2.5 infinite thinking loop and Go gateway
reasoning_contentleak that caused response text to disappear into the thinking panel.Root cause
Two distinct problems:
Go gateway bug #37635 — ALL streaming response text is placed in
reasoning_contentinstead ofcontent. When MiMo thinking is OFF, the answer text gets swallowed by the thinking panel.Model-level reasoning loop — MiMo 2.5 can enter a self-referential chain-of-thought loop, generating identical reasoning fragments indefinitely.
DEFAULT_STREAM_IDLE_TIMEOUT_MS(2 min) doesn't fire because the stream stays active.Fix (3 layers)
src/thinking.tssrc/streaming.tsreasoning_effortin body →reasoning_contentemitted as visible text. Whenreasoning_effortIS present → CoT stays in thinking panelsrc/streaming.tsRegression fixes
contentAfterReasoningguard (was false-positiving on all reasoning models)shouldSuppressTextEmitguard (was false-positiving on all reasoning models)extractStreamPartsdelta block to main behaviorDebug logging
Upstream
Files changed
src/thinking.tsbudget_tokensper MiMo effort levelsrc/retry.tsbudget_tokensrejectionsrc/streaming.tstreatReasoningAsContentconditional,shouldSuppressThinkingEmit(), suffix-repetition detectiondocs/issues/36-20260723-mimo-thinking-infinite-loop.mdCHANGELOG.md[0.4.2]docs/devlog.md