Skip to content

Conversation

atobiszei
Copy link
Collaborator

@atobiszei atobiszei commented Oct 8, 2025

Without escaping several multi turn scenarios in BFCL had problem parsing model response. While this escaping is shallow (does not differentiate at which level of JSON/array we are) it improves results, and we don't have for now examples of this being to eager with escaping.

Additionally:
-> treat improper begining of tool (<function=...>) as an additional start of tool section. Several issues in BFCL were due to improper model output (lack of <tool_call>), but there were <function=...>

Ticket:CVS-174650

@atobiszei atobiszei added the WIP Do not merge until resolved label Oct 8, 2025
@atobiszei atobiszei force-pushed the atobisze_check_qwen3coder_fix branch from 0b9b92d to cca1f42 Compare October 8, 2025 13:52
@atobiszei atobiszei force-pushed the atobisze_check_qwen3coder_fix branch from 6b13486 to 8b7f8f6 Compare October 13, 2025 14:28
@atobiszei atobiszei requested a review from Copilot October 14, 2025 07:16
Copy link
Contributor

@Copilot Copilot AI left a comment

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 adds whitespace escaping functionality to the Qwen3Coder tool output parser and improves handling of improperly formatted tool calls that begin with <function=...> tags instead of the expected <tool_call> tags.

  • Introduces an escapeString function to properly escape newlines in tool call arguments
  • Adds support for parsing tool calls that start with <function=...> directly (without <tool_call>)
  • Updates test cases to reflect the new escaped output format and additional parsing scenarios

Reviewed Changes

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

File Description
qwen3coder_tool_parser.cpp Implements whitespace escaping function and enhanced parsing logic for malformed tool calls
qwen3coder_tool_parser.hpp Adds <function= tag to special parsing start tags set
qwen3coder_output_parser_test.cpp Updates tests for escaped output and adds test for improper tag handling
spelling-whitelist.txt Removes specific line reference for test file spelling issues

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

atobiszei and others added 2 commits October 14, 2025 10:58
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@atobiszei atobiszei removed the WIP Do not merge until resolved label Oct 14, 2025
this->lastProcessedPosition = pos + Qwen3CoderToolParser::TOOL_START_TAG.length();
this->currentState = State::InsideToolCall;
this->toolCallPositions.begin.push(pos);
// normally we expect <tool_call> tag but we observerd that sometimes model generates <function=...> directly
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// normally we expect <tool_call> tag but we observerd that sometimes model generates <function=...> directly
// normally we expect <tool_call> tag but we observed that sometimes model generates <function=...> directly

this->currentState = State::InsideToolCall;
this->toolCallPositions.begin.push(posTool);
} else {
// found <function=...> first, we will assume <tool_call> is missing and we will add it
Copy link
Collaborator

Choose a reason for hiding this comment

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

"we will add it" - do you inject "<tool_call>" somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

misleading comment - i will remove it.

Comment on lines +182 to +187
} else if (posTool < posFunc) {
// found <tool_call> first
this->lastProcessedPosition = posTool + Qwen3CoderToolParser::TOOL_START_TAG.length();
this->currentState = State::InsideToolCall;
this->toolCallPositions.begin.push(posTool);
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does it cover well cases when posTool == std::string::npos or posFunc == std::string::npos?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

then posTool != posFunc so we hit either else if or else

@atobiszei atobiszei requested a review from mzegla October 17, 2025 06:39
@atobiszei atobiszei merged commit 18fb0fa into main Oct 17, 2025
1 check passed
@atobiszei atobiszei deleted the atobisze_check_qwen3coder_fix branch October 17, 2025 12:32
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.

3 participants