@@ -1360,23 +1360,32 @@ static void common_chat_parse_gpt_oss(common_chat_msg_parser & builder) {
1360
1360
static const common_regex end_regex (" <\\ |end\\ |>" );
1361
1361
static const common_regex to_regex (" to=" );
1362
1362
static const common_regex channel_type_regexp (" (final|analysis|commentary)" );
1363
- static const common_regex tool_call_regex (
1363
+ static const common_regex user_tool_call_regex (
1364
1364
" functions\\ .([a-zA-Z_][a-zA-Z0-9_]*)\\ s?(?:<\\ |constrain\\ |>([a-zA-Z]+))?<\\ |message\\ |>"
1365
1365
);
1366
+ static const common_regex browser_tool_call_regex (" browser\\ .(search|open|find)[\\ s\\ S]*<\\ |message\\ |>" );
1367
+ static const common_regex python_tool_call_regex (" python\\ s?(?:<|constrain|>code)?<\\ |message\\ |>" );
1366
1368
1367
- auto user_function_call = [&]() {
1368
- if (auto res = builder.try_consume_regex (tool_call_regex )) {
1369
+ auto tool_call = [&]() {
1370
+ if (auto res = builder.try_consume_regex (user_tool_call_regex )) {
1369
1371
auto name = builder.str (res->groups [1 ]);
1370
1372
auto args = builder.consume_rest ();
1371
1373
builder.add_tool_call (name, " " , args);
1374
+ } else if (auto res = builder.try_consume_regex (browser_tool_call_regex)) {
1375
+ auto code = builder.consume_rest ();
1376
+ LOG_DBG (" builtin tool call to python code: %s" , code.c_str ());
1377
+ } else if (auto res = builder.try_consume_regex (python_tool_call_regex)) {
1378
+ auto name = builder.str (res->groups [1 ]);
1379
+ auto args = builder.consume_rest ();
1380
+ LOG_DBG (" builtin tool call to browser.%s %s" , name.c_str (), args.c_str ());
1372
1381
} else {
1373
- throw common_chat_msg_parse_exception (" expected user function call" );
1382
+ throw common_chat_msg_parse_exception (" expected function call" );
1374
1383
}
1375
1384
};
1376
1385
1377
1386
auto commentary = [&]() {
1378
1387
if (builder.try_consume_regex (to_regex)) {
1379
- user_function_call ();
1388
+ tool_call ();
1380
1389
} else if (builder.try_consume_regex (message_regex)) {
1381
1390
if (!builder.try_find_regex (end_regex)) {
1382
1391
builder.add_content (builder.consume_rest ());
@@ -1395,7 +1404,9 @@ static void common_chat_parse_gpt_oss(common_chat_msg_parser & builder) {
1395
1404
};
1396
1405
1397
1406
auto analysis = [&]() {
1398
- if (builder.try_consume_regex (message_regex)) {
1407
+ if (builder.try_consume_regex (to_regex)) {
1408
+ tool_call (); // built-in tools can be called in the analysis channel
1409
+ } else if (builder.try_consume_regex (message_regex)) {
1399
1410
if (auto res = builder.try_find_regex (end_regex, std::string::npos, false )) {
1400
1411
builder.add_reasoning_content (res->prelude );
1401
1412
} else {
@@ -1425,11 +1436,9 @@ static void common_chat_parse_gpt_oss(common_chat_msg_parser & builder) {
1425
1436
1426
1437
auto start = [&]() {
1427
1438
if (builder.try_consume_regex (assistant_regex)) {
1428
- try {
1429
- channel ();
1430
- } catch (const common_chat_msg_parse_exception & e) {
1431
- LOG_ERR (" Parse error: %s, skipping to next valid start" , e.what ());
1432
- }
1439
+ channel ();
1440
+ } else {
1441
+ throw common_chat_msg_parse_exception (" expected: <|assistant|>" );
1433
1442
}
1434
1443
};
1435
1444
@@ -1439,8 +1448,13 @@ static void common_chat_parse_gpt_oss(common_chat_msg_parser & builder) {
1439
1448
LOG_ERR (" Parse error: %s" , e.what ());
1440
1449
}
1441
1450
1451
+ // Read in complete messages until done or partial exception raised
1442
1452
while (builder.try_find_literal (" <|start|>" )) {
1443
- start ();
1453
+ try {
1454
+ start ();
1455
+ } catch (const common_chat_msg_parse_exception & e) {
1456
+ LOG_ERR (" Parse error: %s" , e.what ());
1457
+ }
1444
1458
}
1445
1459
1446
1460
builder.consume_rest ();
0 commit comments