npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

minimax-reasoning

v0.1.0

Published

OpenCode plugin that fixes MiniMax M3 <think> tag leakage in the TUI by injecting reasoning_split into the chat params. Also works for any OpenAI-compatible provider that uses the same pattern.

Downloads

37

Readme

minimax-reasoning

OpenCode plugin that fixes the <think> tag leakage in the TUI for MiniMax M3 and other OpenAI-compatible reasoning models.

Without this plugin, the model's chain-of-thought shows up as raw text in your TUI:

<think>The user is asking me to calculate 17 * 23. Let me compute...391.</think>
391

With this plugin, the thinking is split into a separate part and rendered as a collapsible thinking block:

▼ [Thinking]
  The user is asking me to calculate 17 * 23...
  391

Why this exists

OpenAI's Chat Completions spec predates reasoning models — it has no field for chain-of-thought. When MiniMax exposes M3's reasoning through that spec, it embeds the thinking inside the normal content field wrapped in <think>...</think> tags.

OpenCode's TUI does not parse <think> tags inside text. It only renders a collapsible thinking block when the reasoning arrives on a dedicated reasoning_content field (which is the shape Anthropic, OpenAI Responses, and DeepSeek use natively).

This plugin bridges the gap by injecting the official MiniMax reasoning_split: true flag into the LLM request. The server then returns the same thinking in a separate message.reasoning_content field, which OpenCode renders correctly.

Even better: MiniMax also offers an Anthropic-compatible API at /anthropic/v1. If you can switch to that, you don't need this plugin at all — see When to use this plugin below.

Quick install

Edit ~/.config/opencode/opencode.json and add the plugin:

{
  "plugin": [
    "oh-my-openagent@latest",
    "minimax-reasoning@latest"
  ]
}

OpenCode will install the plugin on next startup. Restart any active TUI session.

Local install (development / offline)

{
  "plugin": [
    "./local-plugins/minimax-reasoning"
  ]
}

When to use this plugin

Use this plugin only when you need to keep using MiniMax's OpenAI-compatible Chat Completions endpoint (baseURL: https://api.minimaxi.com/v1, npm: @ai-sdk/openai-compatible).

If you can switch endpoints, the cleaner fix is to use the Anthropic-compatible API natively:

{
  "provider": {
    "minimax": {
      "npm": "@ai-sdk/anthropic",
      "options": {
        "apiKey": "...",
        "baseURL": "https://api.minimaxi.com/anthropic/v1"
      }
    }
  }
}

The Anthropic endpoint returns reasoning as native thinking content blocks, so OpenCode's TUI handles them out of the box — no plugin needed.

How it works

OpenCode exposes a chat.params plugin hook that fires just before the LLM call. The hook receives a mutable output.options object; whatever you set there gets routed through OpenCode's Oo.providerOptions() translation layer into the AI SDK's providerOptions[<sdk-key>], which the openai-compatible provider's getArgs() spreads into the HTTP request body.

This plugin sets output.options.reasoning_split = true, which the MiniMax server reads and uses to move thinking out of content and into reasoning_content in the response.

The AI SDK's openai-compatible provider already parses delta.reasoning_content natively, emitting reasoning-start / reasoning-delta / reasoning-end events. OpenCode's event adapter then creates a separate reasoning part in the database, which the TUI renders as a collapsible block.

Zero custom rendering code in this plugin. All the reasoning-block UI is OpenCode's native behavior, just unlocked by the right request flag.

Configuration

| Env var | Values | Default | Effect | |---|---|---|---| | OPENCODE_REASONING_SPLIT_MODE | split / disable / off | split | Operating mode |

  • split (default): inject reasoning_split: true → thinking stays on, just split into a separate field
  • disable: inject thinking: { type: "disabled" } → model skips emitting thinking tags (faster, cheaper, no thinking shown)
  • off: plugin does nothing (effectively disabled)

Adding more providers

Edit PROVIDERS in src/index.ts:

const PROVIDERS: Record<string, Partial<Record<Mode, Record<string, unknown>>>> = {
  minimax: {
    split: { reasoning_split: true },
    disable: { thinking: { type: "disabled" } },
  },
  myProvider: {
    split:    { some_flag: true },
    disable: { another_flag: "off" },
  },
}

Then rebuild: npm run build.

Verify it works

# 1. Run a simple prompt
opencode run "Reply: 17 * 23 = ? Just the answer." --model minimax/MiniMax-M3
# Expected: no `<think>` block in visible output

# 2. Inspect DB to confirm reasoning is a separate part
SID=$(sqlite3 ~/.local/share/opencode/opencode.db \
  "SELECT id FROM session ORDER BY time_created DESC LIMIT 1")
sqlite3 ~/.local/share/opencode/opencode.db \
  "SELECT json_extract(p.data, '\$.type'), length(json_extract(p.data, '\$.text'))
   FROM part p JOIN message m ON p.message_id = m.id
   WHERE m.session_id = '$SID'
   AND json_extract(p.data, '\$.type') IN ('text', 'reasoning')"
# Expected output: two rows — one 'reasoning' and one 'text'

Caveats

  • Multi-turn thinking continuity: MiniMax's docs require the entire response_message (including reasoning_details) to be preserved in message history for the model's chain-of-thought to stay coherent across turns. This plugin preserves the thinking text in a separate DB part, but OpenCode's OpenAI-compatible path may not replay the full reasoning_details array on subsequent turns. If you see thinking quality degrade over long agentic sessions, switch to the Anthropic endpoint or set OPENCODE_REASONING_SPLIT_MODE=disable.
  • M2.x models: According to MiniMax's docs, thinking: { type: "disabled" } is a soft hint — M2.x models continue to reason even with this flag set, but the response is just cleaner.

Related ecosystem

Development

# Clone
git clone https://github.com/openopencode/minimax-reasoning.git
cd minimax-reasoning

# Install deps
npm install

# Build
npm run build

# Test locally — link into OpenCode's plugin dir
ln -s "$PWD" ~/.config/opencode/plugins/minimax-reasoning

# Or reference as file path in opencode.json:
#   "plugin": ["/absolute/path/to/minimax-reasoning"]

License

MIT — see LICENSE.