From c024d859082183bc4e9446e0a56c8299b23def0f Mon Sep 17 00:00:00 2001 From: "Piotr Wilkin (ilintar)" Date: Sat, 7 Mar 2026 01:55:33 +0100 Subject: [PATCH] Autoparser: True streaming (#20177) * Relax atomicity constraint for nicer, more pleasent, True Streaming parsing * Whitespace * Remove redundant atomics --- common/chat-auto-parser-generator.cpp | 30 +++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/common/chat-auto-parser-generator.cpp b/common/chat-auto-parser-generator.cpp index 9a936f892b..01787cc8dc 100644 --- a/common/chat-auto-parser-generator.cpp +++ b/common/chat-auto-parser-generator.cpp @@ -239,8 +239,6 @@ common_peg_parser analyze_tools::build_tool_parser_tag_json(parser_build_context if (!function.close.empty()) { func_parser = func_parser + function.close; } - func_parser = p.atomic(func_parser); - tool_choice |= p.rule("tool-" + name, func_parser); }); @@ -357,13 +355,31 @@ common_peg_parser analyze_tools::build_tool_parser_tag_tagged(parser_build_conte // Build call_id parser based on position (if supported) common_peg_parser call_id_section = p.eps(); + bool have_call_id = false; if (call_id.pos == call_id_position::BETWEEN_FUNC_AND_ARGS && !call_id.prefix.empty() && !call_id.suffix.empty()) { - call_id_section = p.optional(call_id.prefix + p.tool_id(p.until(call_id.suffix))) + call_id.suffix; + have_call_id = true; + call_id_section = p.optional(call_id.prefix + p.tool_id(p.until(call_id.suffix)) + call_id.suffix); } - auto func_parser = p.tool_open(function.name_prefix + p.tool_name(p.literal(name)) + function.name_suffix) + - call_id_section + p.space() + args_seq; + bool matched_atomic = false; + common_peg_parser func_parser = p.eps(); + if (!function.name_suffix.empty()) { + func_parser = p.tool_open(function.name_prefix + p.tool_name(p.literal(name)) + function.name_suffix) + + call_id_section + p.space() + args_seq; + matched_atomic = true; + } else if (have_call_id) { + func_parser = p.atomic(p.tool_open(function.name_prefix + p.tool_name(p.literal(name)) + function.name_suffix) + + call_id_section) + p.space() + args_seq; + matched_atomic = true; + } else if (!arguments.name_prefix.empty() && properties.size() > 0) { + func_parser = p.atomic(p.tool_open(function.name_prefix + p.tool_name(p.literal(name)) + function.name_suffix) + + call_id_section + p.space() + p.peek(p.literal(arguments.name_prefix))) + args_seq; + matched_atomic = true; + } else { + func_parser = p.tool_open(function.name_prefix + p.tool_name(p.literal(name)) + function.name_suffix) + + call_id_section + p.space() + args_seq; + } if (!function.close.empty()) { func_parser = func_parser + p.space() + p.tool_close(p.literal(function.close)); @@ -377,8 +393,10 @@ common_peg_parser analyze_tools::build_tool_parser_tag_tagged(parser_build_conte func_parser = func_parser + p.tool_close(p.space()); // force this to process tool closing callbacks in mapper } + if (!matched_atomic) { + func_parser = p.atomic(func_parser); + } - func_parser = p.atomic(func_parser); tool_choice |= p.rule("tool-" + name, func_parser); });