fix(mcp): preserve nullable schema coercion

This commit is contained in:
Pony.Ma
2026-04-28 12:25:10 +08:00
committed by Teknium
parent 1350d12b0b
commit aa94883288
4 changed files with 66 additions and 5 deletions

View File

@@ -67,7 +67,7 @@ class TestCoerceNumber:
def test_inf_stays_string_for_integer_only(self):
"""Infinity should not be converted to int."""
result = _coerce_number("inf")
assert result == float("inf")
assert result == "inf"
def test_negative_float(self):
assert _coerce_number("-2.5") == -2.5
@@ -255,6 +255,35 @@ class TestCoerceToolArgs:
result = coerce_tool_args("test_tool", args)
assert result["config"] == {"max": 50}
def test_coerces_string_null_for_nullable_object_arg(self):
"""Models often emit literal "null" for optional MCP object args."""
schema = self._mock_schema({
"setting": {
"type": "object",
"additionalProperties": True,
"nullable": True,
"default": None,
},
})
with patch("model_tools.registry.get_schema", return_value=schema):
args = {"setting": "null"}
result = coerce_tool_args("test_tool", args)
assert result["setting"] is None
def test_coerces_string_null_for_nullable_array_arg(self):
schema = self._mock_schema({
"stages": {
"type": "array",
"items": {"type": "object"},
"nullable": True,
"default": None,
},
})
with patch("model_tools.registry.get_schema", return_value=schema):
args = {"stages": "null"}
result = coerce_tool_args("test_tool", args)
assert result["stages"] is None
def test_invalid_json_array_preserved_as_string(self):
"""If the string isn't valid JSON, pass it through — let the tool decide."""
schema = self._mock_schema({"items": {"type": "array"}})

View File

@@ -285,6 +285,7 @@ class TestSchemaConversion:
assert schema["properties"]["workdir"] == {
"type": "string",
"nullable": True,
"default": None,
"description": "Optional working directory",
}
@@ -314,6 +315,7 @@ class TestSchemaConversion:
assert schema["properties"]["filters"]["items"] == {
"type": "object",
"properties": {"field": {"type": "string"}},
"nullable": True,
}
def test_convert_mcp_schema_survives_missing_inputschema_attribute(self):