@@ -1314,17 +1314,56 @@ static common_chat_params common_chat_params_init_gpt_oss(const common_chat_temp
13141314 data.prompt = prompt;
13151315 data.format = COMMON_CHAT_FORMAT_GPT_OSS;
13161316
1317+ // These special tokens are required to parse properly, so we include them
1318+ // even if parse_tool_calls is false.
1319+ data.preserved_tokens = {
1320+ " <|channel|>" ,
1321+ " <|constrain|>" ,
1322+ " <|message|>" ,
1323+ " <|start|>" ,
1324+ " <|end|>" ,
1325+ };
1326+
13171327 // TODO: support tool calls in GPT-OSS?
13181328
13191329 return data;
13201330}
13211331static void common_chat_parse_gpt_oss (common_chat_msg_parser & builder) {
1322- // TODO @ngxson : this won't work with --special enabled, we should fix that
1323- builder.try_parse_reasoning (" <|channel|>analysis<|message|>" , " <|start|>assistant<|channel|>final<|message|>" );
1324- if (!builder.syntax ().parse_tool_calls ) {
1325- builder.add_content (builder.consume_rest ());
1326- return ;
1332+ static const common_regex end_regex (" <\\ |end\\ |>" );
1333+ static const common_regex analysis_regex (" <\\ |channel\\ |>analysis<\\ |message\\ |>" );
1334+ static const common_regex final_regex (" <\\ |channel\\ |>final<\\ |message\\ |>" );
1335+
1336+ if (builder.try_consume_regex (analysis_regex)) {
1337+ std::string reasoning;
1338+ bool has_end = false ;
1339+ if (auto res = builder.try_find_regex (end_regex, std::string::npos, false )) {
1340+ reasoning = res->prelude ;
1341+ has_end = true ;
1342+ } else {
1343+ reasoning = builder.consume_rest ();
1344+ }
1345+
1346+ if (builder.syntax ().reasoning_format == COMMON_REASONING_FORMAT_NONE || builder.syntax ().reasoning_in_content ) {
1347+ // the templates raise an exception if <|channel|> is present
1348+ // an assistant's content, so wrap it in think tags
1349+ builder.add_content (" <think>" );
1350+ builder.add_content (reasoning);
1351+ if (has_end) {
1352+ builder.add_content (" </think>" );
1353+ }
1354+ } else {
1355+ builder.add_reasoning_content (reasoning);
1356+ }
1357+ }
1358+
1359+ if (builder.try_find_regex (final_regex, std::string::npos, false )) {
1360+ if (!builder.try_find_regex (end_regex)) {
1361+ builder.add_content (builder.consume_rest ());
1362+ }
13271363 }
1364+
1365+ // no tool call support yet, so we have to consume everything else
1366+ builder.consume_rest ();
13281367}
13291368
13301369static common_chat_params common_chat_params_init_firefunction_v2 (const common_chat_template & tmpl, const struct templates_params & inputs) {
0 commit comments