@@ -656,7 +656,6 @@ static void parse_json_tool_calls(
656
656
}
657
657
from = std::string::npos;
658
658
659
- builder.add_content (res->prelude );
660
659
auto maybe_raw_python = name == " python" && allow_raw_python;
661
660
if (builder.input ()[builder.pos ()] == ' {' || !maybe_raw_python) {
662
661
if (auto arguments = builder.try_consume_json_with_dumped_args ({{}})) {
@@ -686,7 +685,6 @@ static void parse_json_tool_calls(
686
685
};
687
686
if (block_open) {
688
687
if (auto res = builder.try_find_regex (*block_open)) {
689
- builder.add_content (res->prelude );
690
688
parse_tool_calls ();
691
689
} else {
692
690
builder.add_content (builder.consume_rest ());
@@ -699,7 +697,6 @@ static void parse_json_tool_calls(
699
697
static void parse_prefixed_json_tool_call_array (common_chat_msg_parser & builder, const common_regex & prefix, size_t rstrip_prefix = 0 ) {
700
698
static const std::vector<std::vector<std::string>> args_paths = {{" arguments" }};
701
699
if (auto res = builder.try_find_regex (prefix)) {
702
- builder.add_content (res->prelude );
703
700
builder.move_back (rstrip_prefix);
704
701
auto tool_calls = builder.consume_json_with_dumped_args (args_paths);
705
702
if (!builder.add_tool_calls (tool_calls.value ) || tool_calls.is_partial ) {
@@ -835,6 +832,10 @@ static common_chat_params common_chat_params_init_generic(const common_chat_temp
835
832
return data;
836
833
}
837
834
static void common_chat_parse_generic (common_chat_msg_parser & builder) {
835
+ if (!builder.syntax ().parse_tool_calls ) {
836
+ builder.add_content (builder.consume_rest ());
837
+ return ;
838
+ }
838
839
static const std::vector<std::vector<std::string>> content_paths = {
839
840
{" response" },
840
841
};
@@ -907,6 +908,11 @@ static common_chat_params common_chat_params_init_mistral_nemo(const common_chat
907
908
return data;
908
909
}
909
910
static void common_chat_parse_mistral_nemo (common_chat_msg_parser & builder) {
911
+ if (!builder.syntax ().parse_tool_calls ) {
912
+ builder.add_content (builder.consume_rest ());
913
+ return ;
914
+ }
915
+
910
916
static const common_regex prefix (regex_escape (" [TOOL_CALLS]" ));
911
917
parse_prefixed_json_tool_call_array (builder, prefix);
912
918
}
@@ -1001,7 +1007,6 @@ static void common_chat_parse_command_r7b(common_chat_msg_parser & builder) {
1001
1007
1002
1008
if (auto res = builder.try_find_regex (start_action_regex)) {
1003
1009
// If we didn't extract thoughts, prelude includes them.
1004
- builder.add_content (res->prelude );
1005
1010
auto tool_calls = builder.consume_json_with_dumped_args ({{" parameters" }});
1006
1011
for (const auto & tool_call : tool_calls.value ) {
1007
1012
std::string name = tool_call.contains (" tool_name" ) ? tool_call.at (" tool_name" ) : " " ;
@@ -1016,11 +1021,7 @@ static void common_chat_parse_command_r7b(common_chat_msg_parser & builder) {
1016
1021
}
1017
1022
builder.consume_regex (end_action_regex);
1018
1023
} else if (auto res = builder.try_find_regex (start_response_regex)) {
1019
- // If we didn't extract thoughts, prelude includes them.
1020
- builder.add_content (res->prelude );
1021
- if (auto res = builder.try_find_regex (end_response_regex)) {
1022
- builder.add_content (res->prelude );
1023
- } else {
1024
+ if (!builder.try_find_regex (end_response_regex)) {
1024
1025
builder.add_content (builder.consume_rest ());
1025
1026
throw common_chat_msg_partial_exception (end_response_regex.str ());
1026
1027
}
@@ -1128,6 +1129,11 @@ static common_chat_params common_chat_params_init_llama_3_x(const common_chat_te
1128
1129
return data;
1129
1130
}
1130
1131
static void common_chat_parse_llama_3_1 (common_chat_msg_parser & builder, bool with_builtin_tools = false ) {
1132
+ if (!builder.syntax ().parse_tool_calls ) {
1133
+ builder.add_content (builder.consume_rest ());
1134
+ return ;
1135
+ }
1136
+
1131
1137
static const common_regex function_regex (
1132
1138
" \\ s*\\ {\\ s*(?:\" type\"\\ s*:\\ s*\" function\"\\ s*,\\ s*)?\" name\"\\ s*:\\ s*\" ([^\" ]+)\"\\ s*,\\ s*\" parameters\"\\ s*: " );
1133
1139
static const common_regex close_regex (" \\ }\\ s*" );
@@ -1138,8 +1144,6 @@ static void common_chat_parse_llama_3_1(common_chat_msg_parser & builder, bool w
1138
1144
if (with_builtin_tools) {
1139
1145
static const common_regex builtin_call_regex (" <\\ |python_tag\\ |>" );
1140
1146
if (auto res = builder.try_find_regex (builtin_call_regex)) {
1141
- builder.add_content (res->prelude );
1142
-
1143
1147
auto fun_res = builder.consume_regex (function_name_regex);
1144
1148
auto function_name = builder.str (fun_res.groups [1 ]);
1145
1149
@@ -1255,6 +1259,10 @@ static common_chat_params common_chat_params_init_deepseek_r1(const common_chat_
1255
1259
}
1256
1260
static void common_chat_parse_deepseek_r1 (common_chat_msg_parser & builder) {
1257
1261
builder.try_parse_reasoning (" <think>" , " </think>" );
1262
+ if (!builder.syntax ().parse_tool_calls ) {
1263
+ builder.add_content (builder.consume_rest ());
1264
+ return ;
1265
+ }
1258
1266
1259
1267
static const common_regex tool_calls_begin (" (?:<|tool▁calls▁begin|>|<|tool_calls_begin|>|<|tool calls begin|>|<|tool\\\\ _calls\\\\ _begin|>|<|tool▁calls|>)" );
1260
1268
static const common_regex tool_calls_end (" <|tool▁calls▁end|>" );
@@ -1316,6 +1324,10 @@ static common_chat_params common_chat_params_init_firefunction_v2(const common_c
1316
1324
return data;
1317
1325
}
1318
1326
static void common_chat_parse_firefunction_v2 (common_chat_msg_parser & builder) {
1327
+ if (!builder.syntax ().parse_tool_calls ) {
1328
+ builder.add_content (builder.consume_rest ());
1329
+ return ;
1330
+ }
1319
1331
static const common_regex prefix (regex_escape (" functools[" ));
1320
1332
parse_prefixed_json_tool_call_array (builder, prefix, /* rstrip_prefix= */ 1 );
1321
1333
}
@@ -1457,15 +1469,12 @@ static common_chat_params common_chat_params_init_functionary_v3_1_llama_3_1(con
1457
1469
return data;
1458
1470
}
1459
1471
static void common_chat_parse_functionary_v3_1_llama_3_1 (common_chat_msg_parser & builder) {
1460
- // This version of Functionary still supports the llama 3.1 tool call format for the python tool.
1461
- static const common_regex python_tag_regex (regex_escape (" <|python_tag|>" ));
1462
-
1463
- if (auto res = builder.try_find_regex (python_tag_regex)) {
1464
- builder.add_content (res->prelude );
1465
- auto arguments = wrap_code_as_arguments (builder, builder.consume_rest ());
1466
- builder.add_tool_call (" python" , " " , arguments);
1472
+ if (!builder.syntax ().parse_tool_calls ) {
1473
+ builder.add_content (builder.consume_rest ());
1467
1474
return ;
1468
1475
}
1476
+ // This version of Functionary still supports the llama 3.1 tool call format for the python tool.
1477
+ static const common_regex python_tag_regex (regex_escape (" <|python_tag|>" ));
1469
1478
1470
1479
static const common_regex function_regex (R"( <function=(\w+)>)" );
1471
1480
static const common_regex close_regex (R"( </function>)" );
@@ -1477,6 +1486,12 @@ static void common_chat_parse_functionary_v3_1_llama_3_1(common_chat_msg_parser
1477
1486
function_regex,
1478
1487
close_regex,
1479
1488
std::nullopt);
1489
+
1490
+ if (auto res = builder.try_find_regex (python_tag_regex)) {
1491
+ auto arguments = wrap_code_as_arguments (builder, builder.consume_rest ());
1492
+ builder.add_tool_call (" python" , " " , arguments);
1493
+ return ;
1494
+ }
1480
1495
}
1481
1496
1482
1497
static common_chat_params common_chat_params_init_hermes_2_pro (const common_chat_template & tmpl, const struct templates_params & inputs) {
@@ -1595,6 +1610,10 @@ static common_chat_params common_chat_params_init_hermes_2_pro(const common_chat
1595
1610
}
1596
1611
static void common_chat_parse_hermes_2_pro (common_chat_msg_parser & builder) {
1597
1612
builder.try_parse_reasoning (" <think>" , " </think>" );
1613
+ if (!builder.syntax ().parse_tool_calls ) {
1614
+ builder.add_content (builder.consume_rest ());
1615
+ return ;
1616
+ }
1598
1617
1599
1618
static const common_regex open_regex (
1600
1619
" (?:"
@@ -1616,8 +1635,6 @@ static void common_chat_parse_hermes_2_pro(common_chat_msg_parser & builder) {
1616
1635
);
1617
1636
1618
1637
if (auto res = builder.try_find_regex (open_regex)) {
1619
- builder.add_content (res->prelude );
1620
-
1621
1638
const auto & block_start = res->groups [1 ];
1622
1639
std::string block_end = block_start.empty () ? " " : " ```" ;
1623
1640
@@ -1853,10 +1870,10 @@ static void common_chat_parse_content_only(common_chat_msg_parser & builder) {
1853
1870
builder.add_content (builder.consume_rest ());
1854
1871
}
1855
1872
1856
- static void common_chat_parse (common_chat_msg_parser & builder, common_chat_format format ) {
1857
- LOG_DBG (" Parsing input with format %s: %s\n " , common_chat_format_name (format), builder.input ().c_str ());
1873
+ static void common_chat_parse (common_chat_msg_parser & builder) {
1874
+ LOG_DBG (" Parsing input with format %s: %s\n " , common_chat_format_name (builder. syntax (). format ), builder.input ().c_str ());
1858
1875
1859
- switch (format) {
1876
+ switch (builder. syntax (). format ) {
1860
1877
case COMMON_CHAT_FORMAT_CONTENT_ONLY:
1861
1878
common_chat_parse_content_only (builder);
1862
1879
break ;
@@ -1891,15 +1908,15 @@ static void common_chat_parse(common_chat_msg_parser & builder, common_chat_form
1891
1908
common_chat_parse_command_r7b (builder);
1892
1909
break ;
1893
1910
default :
1894
- throw std::runtime_error (std::string (" Unsupported format: " ) + common_chat_format_name (format));
1911
+ throw std::runtime_error (std::string (" Unsupported format: " ) + common_chat_format_name (builder. syntax (). format ));
1895
1912
}
1896
1913
builder.finish ();
1897
1914
}
1898
1915
1899
1916
common_chat_msg common_chat_parse (const std::string & input, bool is_partial, const common_chat_syntax & syntax) {
1900
1917
common_chat_msg_parser builder (input, is_partial, syntax);
1901
1918
try {
1902
- common_chat_parse (builder, syntax. format );
1919
+ common_chat_parse (builder);
1903
1920
} catch (const common_chat_msg_partial_exception & ex) {
1904
1921
LOG_DBG (" Partial parse: %s\n " , ex.what ());
1905
1922
if (!is_partial) {
0 commit comments