[Tests] Add Qwen3 streaming parser delta boundary cases (#45708)
Signed-off-by: test test <2260891073@qq.com>
Palaiologos1453 committed
Jun 19, 2026 at 01:37 UTC
a0df04e4775efbfebd65c997259d63af0ec548ce
1 file changed
+67
tests/tool_parsers/test_qwen3coder_tool_parser.py
+67
@@ -1300,6 +1300,73 @@ def test_streaming_multi_param_single_chunk(qwen3_tool_parser, qwen3_tokenizer):
1300
assert args["unit"] == "fahrenheit"
1301
1302
1303
+def test_streaming_complete_tool_call_single_delta(qwen3_tool_parser):
1304
+ """Regression: one delta may contain a complete tool call."""
1305
+ request = ChatCompletionRequest(model=MODEL, messages=[])
1306
+
1307
+ from tests.tool_parsers.utils import (
1308
+ run_tool_extraction_streaming,
1309
+ )
1310
+
1311
+ reconstructor = run_tool_extraction_streaming(
1312
+ qwen3_tool_parser,
1313
+ [
1314
+ (
1315
+ "<tool_call>\n"
1316
+ "<function=get_current_weather>\n"
1317
+ "<parameter=city>\nDallas\n</parameter>\n"
1318
+ "<parameter=state>\nTX\n</parameter>\n"
1319
+ "</function>\n"
1320
+ "</tool_call>"
1321
+ )
1322
+ ],
1323
+ request,
1324
+ assert_one_tool_per_delta=False,
1325
+ )
1326
+
1327
+ assert len(reconstructor.tool_calls) == 1
1328
+ assert reconstructor.tool_calls[0].function.name == "get_current_weather"
1329
+ args = json.loads(reconstructor.tool_calls[0].function.arguments)
1330
+ assert args == {"city": "Dallas", "state": "TX"}
1331
+
1332
+
1333
+def test_streaming_next_tool_call_starts_in_close_delta(qwen3_tool_parser):
1334
+ """Regression: a close delta may also contain the next tool call."""
1335
+ request = ChatCompletionRequest(model=MODEL, messages=[])
1336
+
1337
+ from tests.tool_parsers.utils import (
1338
+ run_tool_extraction_streaming,
1339
+ )
1340
+
1341
+ reconstructor = run_tool_extraction_streaming(
1342
+ qwen3_tool_parser,
1343
+ [
1344
+ "<tool_call>\n",
1345
+ "<function=get_current_weather>\n",
1346
+ "<parameter=city>\nDallas\n</parameter>\n",
1347
+ "<parameter=state>\nTX\n</parameter>\n",
1348
+ "</function>",
1349
+ (
1350
+ "\n</tool_call>\n"
1351
+ "<tool_call>\n"
1352
+ "<function=get_current_weather>\n"
1353
+ "<parameter=city>\nOrlando\n</parameter>\n"
1354
+ "<parameter=state>\nFL\n</parameter>\n"
1355
+ "</function>\n"
1356
+ "</tool_call>"
1357
+ ),
1358
+ ],
1359
+ request,
1360
+ assert_one_tool_per_delta=False,
1361
+ )
1362
+
1363
+ assert len(reconstructor.tool_calls) == 2
1364
+ first_args = json.loads(reconstructor.tool_calls[0].function.arguments)
1365
+ second_args = json.loads(reconstructor.tool_calls[1].function.arguments)
1366
+ assert first_args == {"city": "Dallas", "state": "TX"}
1367
+ assert second_args == {"city": "Orlando", "state": "FL"}
1368
+
1369
+
1370
def test_no_double_serialization_string_args(qwen3_tool_parser):
1371
"""Regression: string arguments must not be double-serialized (PR #35615)."""
1372
tools = [