Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions examples/server/parsers/qwen3_parser.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "json.hpp"
#include "../../common/common.h"
#include <string>
#include <regex>

Expand Down Expand Up @@ -102,12 +103,8 @@ static std::string extract_content_during_parsing(const std::string& text, bool
}
}

// Clean up extra whitespace
content = std::regex_replace(content, std::regex(R"(\n\s*\n)"), "\n");

// Trim leading/trailing whitespace
content.erase(0, content.find_first_not_of(" \t\n\r"));
content.erase(content.find_last_not_of(" \t\n\r") + 1);
// Only trim leading/trailing whitespace, preserve internal formatting
content = string_strip(content);

} catch (const std::exception&) {
// Return original text on regex errors
Expand Down
35 changes: 35 additions & 0 deletions tests/test-function-calls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2214,6 +2214,40 @@ void test_xml_tool_call_parsing() {
std::cout << " ✅ XML tool call parsing works correctly!" << std::endl;
}

// Test whitespace preservation in qwen3 content extraction
void test_qwen3_whitespace_preservation() {
std::cout << "\n🧹 Testing Qwen3 Whitespace Preservation Fix:" << std::endl;

// Test case with PEP 8 style: 2 empty lines between functions
const std::string pep8_content = R"(def celsius_to_fahrenheit(celsius):
return celsius * 9/5 + 32


def fahrenheit_to_celsius(fahrenheit):
return (fahrenheit - 32) * 5/9)";

std::cout << "🎯 Testing PEP 8 compliance (2 empty lines between functions)..." << std::endl;
std::cout << "Original content has: 2 empty lines between functions" << std::endl;

// Test the qwen3 content extraction directly
std::string result = qwen3::extract_content_during_parsing(pep8_content, false);

// Check if the double newlines are preserved (should have \n\n\n for 2 empty lines)
bool has_double_empty_lines = result.find("\n\n\n") != std::string::npos;

std::cout << "Result content: '" << result << "'" << std::endl;
std::cout << "Has 2 empty lines preserved: " << (has_double_empty_lines ? "YES" : "NO") << std::endl;

test_assert(has_double_empty_lines, "Qwen3: PEP 8 double empty lines preserved");

// Additional test: ensure no excessive trimming
test_assert(!result.empty(), "Qwen3: Content not empty after processing");
test_assert(result.find("celsius_to_fahrenheit") != std::string::npos, "Qwen3: Function content preserved");
test_assert(result.find("fahrenheit_to_celsius") != std::string::npos, "Qwen3: Second function preserved");

std::cout << " ✅ Qwen3 whitespace preservation working correctly!" << std::endl;
}

// Test the streaming tool calls fix implementation
void test_streaming_tool_calls_fix() {
std::cout << "\n=== Streaming Tool Calls Fix Validation ===" << std::endl;
Expand Down Expand Up @@ -2774,6 +2808,7 @@ int main() {
test_content_cleaning();
test_contamination_reproduction(); // Added this test
test_mixed_formats();
test_qwen3_whitespace_preservation(); // Test whitespace fix

std::cout << "\n🌍 Unicode & International Tests:" << std::endl;
test_unicode_support();
Expand Down