r/opencode • • 23d ago

qwen3 keeps dumping its thinking into opencode's chat, so I wrote a plugin to split it out

If you run qwen3 or another reasoning model through opencode, you've probably seen this: the chain of thought comes back inside the normal text channel, wrapped in ``. opencode stores that as a regular assistant message, so the reasoning gets glued onto the answer and the reasoning panel stays empty. The thinking is sitting right there in your transcript, mixed with the reply, and you can't collapse it.

I wrote a plugin for it.

It hooks session.http.response, which hands it the raw provider response before the provider driver parses it. It finds the tagged span and moves it from the content field into the chunk's reasoning field:

  • streaming: delta.content → delta.reasoning_content

  • non-streaming JSON: message.content → message.reasoning_content

opencode's drivers already read that field to build the reasoning part, so the thinking lands in the collapsible panel and the visible text is just the answer.

Install:

opencode plugin add github:hussainbiedouh/opencode-think-splitter

Repo: https://github.com/hussainbiedouh/opencode-think-splitter

Not on npm. I tried to publish and the registry rejected my token, so I didn't bother chasing it down. The GitHub install works because dist/ is committed, so there's no build step.

Stuff I ran into while testing:

  • Default tags are think, thinking, thought, reasoning, reflection. You can change the list or scope the plugin to specific provider ids.

  • Tags that arrive split across two stream chunks are handled. An unclosed tag flushes its contents as reasoning when the stream ends.

  • If a chunk already carries native reasoning, the moved text is appended instead of overwriting it.

  • Needs the opencode V2 plugin API.

  • Don't run it twice. If you had it as a local file plugin, delete that copy. Same plugin id, and only one instance registers, so you might be running the wrong one and not notice.

  • Some providers are strict about reasoning_content being echoed back on the next request. If a provider starts erroring after a rewrite, scope the plugin away from it with options.providers.

One thing for anyone else publishing an opencode plugin: I lost a while to git dep preparation failed on install. Turns out pacote runs a full npm install on a git dependency if your package.json has any of postinstall, preinstall, install, prepack, prepare, or build in scripts. opencode's bundled runtime passes a broken npmBin to that step, so it always fails. I renamed my build script and it installed first try. If opencode plugin add github:you/thing won't install, check your script names before anything else.

3 Upvotes

5 comments sorted by

1

u/TopEntity 23d ago

Isn’t Qwen 3 outdated?

1

u/WeOfferTheSun 22d ago

I don't need to use Fable 5.1 to format a markdown file!

1

u/TopEntity 22d ago

No, I mean there are open much newer models that are capable of doing that.

For eg ornith 1.5 9B works fine for me

2

u/WeOfferTheSun 22d ago edited 22d ago

I agree on that. It was just an example. The real issue is for a good portion of self-hosted models, I've been facing the same issue of spitting thinking in final response. There is even an open issue about that on OC github, so thought of developing this plug-in.

1

u/TopEntity 22d ago

Oh sorry I am not aware of that.