@@ -1438,89 +1438,9 @@ static common_chat_params common_chat_params_init_phi_4(const common_chat_templa
1438
1438
}
1439
1439
1440
1440
static common_chat_msg common_chat_parse_phi_4 (const std::string & input) {
1441
- common_chat_msg result;
1442
- result.role = " assistant" ;
1443
-
1444
- std::string final_content = " " ;
1445
-
1446
- const std::string opening_tag = " <|tool_call|>" ;
1447
- const std::string closing_tag = " </|tool_call|>" ;
1448
-
1449
- size_t start_pos = 0 ;
1450
- while (true ) {
1451
- // Find next tool call
1452
- size_t tool_start = input.find (opening_tag, start_pos);
1453
- if (tool_start == std::string::npos) {
1454
- // No more tool calls.
1455
-
1456
- // Is start_pos within string bounds?
1457
- if (start_pos < input.length ()) {
1458
- // Add the rest of the string to final_content
1459
- final_content += input.substr (start_pos);
1460
- }
1461
- break ;
1462
- }
1463
-
1464
- // Add content before the tool call to final_content
1465
- final_content += input.substr (start_pos, tool_start - start_pos);
1466
-
1467
- // Find closing tag
1468
- size_t content_start = tool_start + opening_tag.length ();
1469
- size_t tool_end = input.find (closing_tag, content_start);
1470
-
1471
- if (tool_end == std::string::npos) {
1472
- // No closing tag found, so just include the rest of the string as tool.
1473
- tool_end = input.length ();
1474
- }
1475
-
1476
- // Extract tool call content
1477
- std::string tool_content = input.substr (
1478
- content_start,
1479
- tool_end - content_start
1480
- );
1481
-
1482
- // Try to parse the tool call
1483
- try {
1484
- auto tool_call = json::parse (tool_content);
1485
-
1486
- // Verify the required fields exist
1487
- if (!tool_call.contains (" name" )) {
1488
- throw std::runtime_error (" Missing 'name' field in tool call" );
1489
- }
1490
-
1491
- if (!tool_call.contains (" arguments" )) {
1492
- throw std::runtime_error (" Missing 'arguments' field in tool call" );
1493
- }
1494
-
1495
- std::string name = tool_call[" name" ].get <std::string>();
1496
-
1497
- std::string arguments;
1498
- try {
1499
- arguments = tool_call[" arguments" ].dump ();
1500
- } catch (const std::exception & e) {
1501
- LOG_ERR (" Failed to serialize arguments: %s\n " , e.what ());
1502
- arguments = " {}" ;
1503
- }
1504
-
1505
- result.tool_calls .push_back ({
1506
- name,
1507
- arguments,
1508
- /* id= */ " " ,
1509
- });
1510
- } catch (const std::exception & e) {
1511
- // If parsing fails, include the entire tool call in the content
1512
- final_content += input.substr (
1513
- tool_start,
1514
- tool_end + closing_tag.length () - tool_start
1515
- );
1516
- }
1517
-
1518
- // Move past this tool call for next iteration
1519
- start_pos = tool_end + closing_tag.length ();
1520
- }
1521
-
1522
- result.content = final_content;
1523
- return result;
1441
+ static std::regex function_regex (" <\\ |tool_call\\ |>\\ s*\\ {\\ s*\" name\"\\ s*:\\ s*\" ([^\" ]+)\"\\ s*,\\ s*\" arguments\"\\ s*:" );
1442
+ static std::regex close_regex (R"( \}\s*(</\|tool_call\|>)?)" );
1443
+ return parse_json_tool_calls (input, std::nullopt, function_regex, close_regex);
1524
1444
}
1525
1445
1526
1446
0 commit comments