@@ -2096,7 +2096,7 @@ static void common_chat_parse_seed_oss(common_chat_msg_parser & builder) {
20962096 static const common_regex tool_call_begin_regex (" <seed:tool_call>" );
20972097 static const common_regex tool_call_end_regex (" </seed:tool_call>" );
20982098 static const common_regex function_regex (" <function=([^>]+)>" );
2099- static const common_regex close_function_regex (" </function >" );
2099+ static const common_regex param_regex (" <parameter=([^>]+) >" );
21002100
21012101 while (auto tool_res = builder.try_find_regex (tool_call_begin_regex)) {
21022102 builder.consume_spaces (); // Consume whitespace after <seed:tool_call>
@@ -2107,7 +2107,6 @@ static void common_chat_parse_seed_oss(common_chat_msg_parser & builder) {
21072107
21082108 // Parse Seed-OSS parameters <parameter=name>value</parameter>
21092109 json args = json::object ();
2110- static const common_regex param_regex (" <parameter=([^>]+)>" );
21112110 // Parse all parameters
21122111 while (auto param_res = builder.try_find_regex (param_regex, std::string::npos, false )) {
21132112 // again, ignore noise around parameters
@@ -2128,40 +2127,28 @@ static void common_chat_parse_seed_oss(common_chat_msg_parser & builder) {
21282127 args[param_name] = param;
21292128 }
21302129 } else {
2131- try {
2132- if (auto param_res = builder.try_consume_json ()) {
2133- auto json_obj = param_res->json ;
2134- purge_healing_marker (json_obj, builder.healing_marker ());
2135- if (!json_obj.is_null ()) {
2136- args[param_name] = json_obj;
2137- }
2138- } else {
2139- auto rest = builder.consume_rest ();
2140- args[param_name] = rest;
2141- }
2142- } catch (json::exception &) {
2143- auto rest = builder.consume_rest ();
2144- args[param_name] = rest;
2145- }
2146- builder.add_tool_call (function_name, " " , args.dump ());
21472130 throw common_chat_msg_partial_exception (" Incomplete tool parameter" );
21482131 }
2149- }
2132+ }
21502133 // Look for closing function tag
21512134 auto end_func = builder.try_find_literal (" </function>" );
21522135 if (end_func) {
21532136 builder.move_to (end_func->groups [0 ].end );
21542137 builder.consume_spaces (); // Consume whitespace after </function>
21552138
2156- // Add the tool call with parsed arguments
2157- if (!builder.add_tool_call (function_name, " " , args.dump ())) {
2139+ // Add the tool call with parsed arguments, but only if we REALLY got the literal
2140+ auto eaten_fragment = builder.input ().substr (end_func->groups [0 ].begin , end_func->groups [0 ].end );
2141+ auto funlen = std::string (" </function>" ).length ();
2142+ if (eaten_fragment.length () >= funlen && eaten_fragment.substr (0 , funlen) == std::string (" </function>" )) {
2143+ if (!builder.add_tool_call (function_name, " " , args.dump ())) {
2144+ throw common_chat_msg_partial_exception (" Incomplete tool call" );
2145+ }
2146+ } else {
21582147 throw common_chat_msg_partial_exception (" Incomplete tool call" );
21592148 }
21602149 } else {
2161- builder.add_tool_call (function_name, " " , args.dump ()); // add partial tool parse
21622150 throw common_chat_msg_partial_exception (" Incomplete tool call" );
21632151 }
2164-
21652152 // Look for closing tool call tag
21662153 if (auto end_tool = builder.try_find_regex (tool_call_end_regex, std::string::npos, false )) {
21672154 builder.move_to (end_tool->groups [0 ].end );
@@ -2228,8 +2215,8 @@ static common_chat_params common_chat_params_init_seed_oss( const common_chat_t
22282215 std::string param_rules;
22292216 if (parameters.contains (" properties" )) {
22302217 for (const auto & [key, value] : parameters.at (" properties" ).items ()) {
2231- param_rules += " <parameter=" + key + " >" + builder.add_schema (name + " -arg-" + key, value) +
2232- " </parameter>" ;
2218+ param_rules += " \" <parameter=" + key + " >\" " + builder.add_schema (name + " -arg-" + key, value) +
2219+ " \" </parameter>\" " ;
22332220 }
22342221 }
22352222
0 commit comments