Skip to content

common : rework gpt-oss parser#20393

Merged
pwilkin merged 4 commits intoggml-org:masterfrom
aldehir:rework-gpt-oss
Mar 18, 2026
Merged

common : rework gpt-oss parser#20393
pwilkin merged 4 commits intoggml-org:masterfrom
aldehir:rework-gpt-oss

Conversation

@aldehir
Copy link
Copy Markdown
Contributor

@aldehir aldehir commented Mar 11, 2026

Rework the gpt-oss parser.

  • Tighten up the grammar, gpt-oss is very good at following its own Harmony spec.
  • Allow any sequence of analysis/preamble.
  • Clean up the trigger rules, gpt-oss may sometimes invoke a builtin function if not constrained when emitting the tool namespace.
  • Include fix from common : fix gpt-oss Jinja error with content and thinking on tool-call messages #19704.
  • Fix response_format not being enforced.
  • Remove parallel call logic, gpt-oss is trained to only emit single tool calls.
  • Removed support for reasoning-format = none. It makes no sense for gpt-oss. Users can choose to ignore reasoning_content.
  • Remove invalid test cases.

fixes #20344
fixes #20500

common/chat.cpp Outdated

auto analysis = p.rule("analysis", p.literal("<|channel|>analysis<|message|>") + p.reasoning(content) + end);
auto preamble = p.rule("preamble", p.literal("<|channel|>commentary<|message|>") + p.content(content) + end);
auto final = p.rule("final", p.literal("<|channel|>final<|message|>") + p.content(content));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final is a keyword, does this work correctly? I'd change it anyway just in case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, which is why I kept it. But I'll change it. Most syntax highlighters are not semantic aware so it'll highlight it as a keyword.

Copy link
Copy Markdown
Member

@pwilkin pwilkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll trust you on this one :)

@pwilkin
Copy link
Copy Markdown
Member

pwilkin commented Mar 11, 2026

Just two issues:
-> support for reasoning_format: none should stay, since some people want just raw template output to further process with their own custom parsers / apps (I think SillyTavern does stuff like that) and not outputting the reasoning in content breaks this
-> since you're saying this fixes structured output, better add a test for structured output :)

@aldehir
Copy link
Copy Markdown
Contributor Author

aldehir commented Mar 12, 2026

I'll add the logic back in, but it truly makes no sense. For one, the official template will throw an exception if it sees any harmony tags in the message. Ultimately, this model is incapable of not reasoning. Even when constrained, it will leak reasoning traces inside the final response if it can.

That said, if clients depend on this then I guess 🤷‍♂️

@pwilkin
Copy link
Copy Markdown
Member

pwilkin commented Mar 12, 2026

@aldehir reasoning_format: none is not enable_thinking: false, it just means you don't process the reasoning tags and you spill them all in the content.

@aldehir
Copy link
Copy Markdown
Contributor Author

aldehir commented Mar 12, 2026

@aldehir reasoning_format: none is not enable_thinking: false, it just means you don't process the reasoning tags and you spill them all in the content.

I'm fully aware of the difference. See point 2. The responsibility is pushed to the client to strip the tags. Currently there is a hack to remove the exception, but then the model will in-context learn and start to emit bad harmony output, thus breaking parsing.

I've been down this road when I implemented the original parsing.

Edit: I can see my phrasing conflated the two. Ignore the second part.

@pwilkin
Copy link
Copy Markdown
Member

pwilkin commented Mar 12, 2026

@aldehir I know this is generally non-feasible, but there exists a small but vocal group of people who use their own parsing tools for whatever reasons and they really like to get the raw unprocessed contents :)

But I just realized you can not change it and instead approve my #20289 to satisfy them :)

@aldehir
Copy link
Copy Markdown
Contributor Author

aldehir commented Mar 12, 2026

But I just realized you can not change it and instead approve my #20289 to satisfy them :)

Yes, I rather just give them the whole harmony output. I've seen complaints about "missing tokens" too, it's never ending!

@aldehir aldehir requested a review from a team as a code owner March 18, 2026 06:02
@aldehir
Copy link
Copy Markdown
Contributor Author

aldehir commented Mar 18, 2026

@pwilkin added structured output test.

@pwilkin pwilkin merged commit 5e8910a into ggml-org:master Mar 18, 2026
47 of 48 checks passed
@pwilkin pwilkin deleted the rework-gpt-oss branch March 18, 2026 09:41
for (auto msg : inputs.messages) {
if (msg.contains("reasoning_content") && msg.at("reasoning_content").is_string()) {
msg["thinking"] = msg.at("reasoning_content");
msg.erase("content");
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I messed up, need to only do this for tool calls.

@Mo-Hashem
Copy link
Copy Markdown

@aldehir I like your dedication in making gpt-oss work as intended for all since it launched .
I am also writing to let you know that @pwilkin is totally right about the reasoning-format = none
it must stay, I personally have my template that use reasoning-format = none
that enables agents that doesn't support interleaved CoT (which is 90% of all Agents)

and llama.cpp philosophy is power and high customization, now what is the deference between it and Ollama/LM-studio

@aldehir
Copy link
Copy Markdown
Contributor Author

aldehir commented Mar 20, 2026

@Mo-Hashem, unfortunately it will cause double tags to render and contradicts the template. The official template normally throws an exception. Nonetheless, I can add it back in.

@Mo-Hashem
Copy link
Copy Markdown

Yes add it back please, it is a serious blocker
I fixed the double tags with simple template customization (will release it to community after an edge case fix)
templates can be customized, but this no way
thanks @aldehir

Ethan-a2 pushed a commit to Ethan-a2/llama.cpp that referenced this pull request Mar 20, 2026
* common : rework gpt-oss parser

* cont : fix gpt-oss tests

* cont : add structured output test

* cont : rename final to final_msg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testing Everything test related

Projects

None yet

3 participants