Skip to content

fix(server): route reasoning_format to split thinking into reasoning_content - #1305

Draft
RemiliaForever (RemiliaForever) wants to merge 2 commits into
mainfrom
fix/serve-reasoning-format
Draft

fix(server): route reasoning_format to split thinking into reasoning_content#1305
RemiliaForever (RemiliaForever) wants to merge 2 commits into
mainfrom
fix/serve-reasoning-format

Conversation

@RemiliaForever

Copy link
Copy Markdown
Contributor

Summary

geniex serve always emitted a thinking model's chain-of-thought inside message.content, with no way to disable it or move it to the OpenAI-ecosystem-standard reasoning_content field (#1294).

This honors the per-request reasoning_format body param (mirroring the llama.cpp backend that already understands it):

  • "" / none — keep thinking inline in content (default, behavior unchanged).
  • deepseek / deepseek-legacy / auto — move the chain-of-thought into message.reasoning_content (blocking) or delta.reasoning_content (streaming).

Tool-call requests ignore the flag, since tool parsing needs the raw <think>-tagged text.

The reasoning split reuses the token FSM that geniex infer/run already render with, extracted into a new dependency-free cli/internal/thinkfsm package so both the terminal and the server drive one transition table. reasoning_content is not a field in openai-go (no version has it — it is a DeepSeek-originated de-facto standard), so the separated responses use small local structs; the default inline path still serializes the exact openai.ChatCompletion shape byte-for-byte.

Test plan

  • bazelisk test //cli/internal/thinkfsm:thinkfsm_test — FSM split across plain / inline-think / gpt-oss / gemma / unterminated inputs.
  • bazelisk test //cli/server/handler:handler_testreasoningSeparated mapping and reasoningSink routing (separation on/off).
  • bazelisk build //cli — full CLI builds.
  • gofmt clean on all touched Go files.

Closes #1294

…content

geniex serve always inlined a thinking model's chain-of-thought in
message.content with no way to separate it. Honor the per-request
reasoning_format body param: deepseek / deepseek-legacy / auto move the
chain-of-thought into message.reasoning_content, while "" / none keep it
inline (default, unchanged). Reasoning splitting reuses the shared token
FSM extracted into internal/thinkfsm (also used by geniex infer/run).

Closes #1294

Signed-off-by: RemiliaForever <remilia@koumakan.cc>
Add the reasoning_format usage to the local-server guide (CN/EN) and a
pointer under geniex serve in the CLI reference.

Signed-off-by: RemiliaForever <remilia@koumakan.cc>
@mintlify

mintlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
qualcomm-0801e48b 🟢 Ready View Preview Aug 7, 2026, 12:20 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@RemiliaForever

Copy link
Copy Markdown
Contributor Author

still too complex, need refactor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

geniex serve: thinking/<think> reasoning always emitted in content — no flag or request param to disable or move it to reasoning_content

1 participant