[Misc] Add 20 regression tests for 11 tool parser bug fixes (#38172)
Signed-off-by: Ben Browning <bbrownin@redhat.com> Co-authored-by: Chauncey <chaunceyjiang@gmail.com>
This commit is contained in:
@@ -5,6 +5,10 @@ import json
|
||||
|
||||
import pytest
|
||||
|
||||
from vllm.entrypoints.openai.chat_completion.protocol import (
|
||||
ChatCompletionToolsParam,
|
||||
FunctionDefinition,
|
||||
)
|
||||
from vllm.tool_parsers.minimax_m2_tool_parser import (
|
||||
MinimaxM2ToolParser,
|
||||
)
|
||||
@@ -442,3 +446,105 @@ class TestLargeChunks:
|
||||
"city": "Seattle",
|
||||
"days": "5",
|
||||
}
|
||||
|
||||
|
||||
class TestAnyOfNullableParam:
|
||||
"""Regression: anyOf nullable parameter parsing (PR #32342)."""
|
||||
|
||||
def test_anyof_nullable_param_non_null_value(self):
|
||||
"""A valid non-null string should be preserved, not collapsed to None."""
|
||||
tools = [
|
||||
ChatCompletionToolsParam(
|
||||
function=FunctionDefinition(
|
||||
name="update_profile",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"nickname": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
]
|
||||
parser = MinimaxM2ToolParser(FakeTokenizer(), tools=tools)
|
||||
|
||||
results = _feed(
|
||||
parser,
|
||||
[
|
||||
'<minimax:tool_call><invoke name="update_profile">'
|
||||
'<parameter name="nickname">Alice</parameter>'
|
||||
"</invoke></minimax:tool_call>",
|
||||
],
|
||||
)
|
||||
tc = _collect_tool_calls(results)
|
||||
assert len(tc) == 1
|
||||
parsed = json.loads(tc[0]["arguments"])
|
||||
assert parsed["nickname"] == "Alice"
|
||||
|
||||
def test_anyof_nullable_param_null_value(self):
|
||||
"""An actual null-like value should be returned as None/null."""
|
||||
tools = [
|
||||
ChatCompletionToolsParam(
|
||||
function=FunctionDefinition(
|
||||
name="update_profile",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"nickname": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
]
|
||||
parser = MinimaxM2ToolParser(FakeTokenizer(), tools=tools)
|
||||
|
||||
results = _feed(
|
||||
parser,
|
||||
[
|
||||
'<minimax:tool_call><invoke name="update_profile">'
|
||||
'<parameter name="nickname">null</parameter>'
|
||||
"</invoke></minimax:tool_call>",
|
||||
],
|
||||
)
|
||||
tc = _collect_tool_calls(results)
|
||||
assert len(tc) == 1
|
||||
parsed = json.loads(tc[0]["arguments"])
|
||||
assert parsed["nickname"] is None
|
||||
|
||||
def test_anyof_nullable_param_object_value(self):
|
||||
"""A valid object value in anyOf with null should parse as dict."""
|
||||
tools = [
|
||||
ChatCompletionToolsParam(
|
||||
function=FunctionDefinition(
|
||||
name="update_settings",
|
||||
parameters={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"anyOf": [{"type": "object"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
]
|
||||
parser = MinimaxM2ToolParser(FakeTokenizer(), tools=tools)
|
||||
|
||||
results = _feed(
|
||||
parser,
|
||||
[
|
||||
'<minimax:tool_call><invoke name="update_settings">'
|
||||
'<parameter name="config">{"theme": "dark", "fontSize": 14}'
|
||||
"</parameter>"
|
||||
"</invoke></minimax:tool_call>",
|
||||
],
|
||||
)
|
||||
tc = _collect_tool_calls(results)
|
||||
assert len(tc) == 1
|
||||
parsed = json.loads(tc[0]["arguments"])
|
||||
assert parsed["config"] == {"theme": "dark", "fontSize": 14}
|
||||
assert isinstance(parsed["config"], dict)
|
||||
|
||||
Reference in New Issue
Block a user