Skip to content

Tool parsers fixes for finish with incomplete output structure - #4493

Merged
mzegla merged 4 commits into
mainfrom
parsers_fixes
Sep 2, 2026
Merged

Tool parsers fixes for finish with incomplete output structure#4493
mzegla merged 4 commits into
mainfrom
parsers_fixes

Conversation

@mzegla

@mzegla mzegla commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Moving towards convention "if we can emit correct output, do it, even if it's not completely in line with expected structure".
This approach is more forgiving if model skips some closures. It also helps if model reaches max_tokens limit mid generation and is in general more live-streaming kind of approach.

Copilot AI lite review requested due to automatic review settings August 31, 2026 14:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts Gemma4 and LFM2 streaming tool-call parsers to avoid re-emitting tool arguments during the final STOP flush when the model output is structurally incomplete (e.g., missing end tags/closures), aligning with a more forgiving “emit correct output when possible” convention.

Changes:

  • Clear the internal ToolCall buffer immediately after emitting the arguments delta in the ToolCallEnded state (prevents duplicate argument emission on final flush).
  • Add regression tests for both Gemma4 and LFM2 covering missing end-tag scenarios where generation stops mid-structure.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/llm/io_processing/lfm2/lfm2_tool_parser.cpp Clears buffered tool-call data after emitting arguments to prevent duplicate emissions on STOP flush.
src/llm/io_processing/gemma4/gemma4_tool_parser.cpp Same buffering fix for Gemma4 tool-call streaming.
src/test/llm/output_parsers/lfm2_output_parser_test.cpp Adds regression test for STOP occurring before tool-call end markers; asserts arguments emitted exactly once.
src/test/llm/output_parsers/gemma4_output_parser_test.cpp Adds regression test for missing end tag with stray `<

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@mzegla mzegla added the 2026.4 label Aug 31, 2026
@mzegla
mzegla requested review from dtrawins and przepeck September 1, 2026 08:38
@mzegla mzegla changed the title Gemma4/LFM2 - clean arguments buffer once emitted Tool parsers fixes for finish with incomplete output structure Sep 1, 2026
@mzegla
mzegla requested a lite review from Copilot September 1, 2026 13:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comment on lines +287 to +293
if (this->currentState == State::Content ||
this->currentState == State::InsideFunctionName) {
// No usable function name was ever captured -- nothing to recover. Still clear the
// dangling partial state so it doesn't look like a call is still in flight.
resetParsingState();
return std::nullopt;
}
Comment on lines +217 to +224
if (this->currentState == State::Content ||
this->currentState == State::InsideToolCall ||
this->currentState == State::InsideFunctionName) {
// No usable function name was ever captured -- nothing to recover. Still clear the
// dangling partial state so it doesn't look like a call is still in flight.
resetParsingState();
return std::nullopt;
}
@mzegla
mzegla merged commit 503ff86 into main Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants