fix(tools): strip default from $ref nodes in tool schemas

Fireworks-hosted Kimi rejects tool requests when nullable MCP/Pydantic
schemas collapse to {"$ref": "...", "default": null}. Strip that sibling
during global schema sanitization so gateway and CLI calls succeed again.
This commit is contained in:
Brooklyn Nicholson
2026-06-12 00:30:51 -05:00
parent c574170050
commit b2d151abe2
2 changed files with 104 additions and 0 deletions
+66
View File
@@ -201,6 +201,72 @@ def test_items_sanitized_in_array_schema():
assert items == {"type": "object", "properties": {}}
def test_ref_with_default_sibling_stripped():
"""Strict backends reject ``default`` alongside ``$ref``."""
tools = [_tool("t", {
"type": "object",
"properties": {
"payload": {"$ref": "#/$defs/Payload", "default": None},
},
"$defs": {
"Payload": {
"type": "object",
"properties": {"q": {"type": "string"}},
},
},
})]
out = sanitize_tool_schemas(tools)
payload = out[0]["function"]["parameters"]["properties"]["payload"]
assert payload == {"$ref": "#/$defs/Payload"}
def test_nullable_union_collapse_does_not_leave_default_on_ref():
"""Nullable anyOf collapse must not attach ``default`` to a ``$ref`` branch."""
tools = [_tool("t", {
"type": "object",
"properties": {
"input": {
"anyOf": [
{"$ref": "#/$defs/Payload"},
{"type": "null"},
],
"default": None,
},
},
"$defs": {
"Payload": {
"type": "object",
"properties": {"q": {"type": "string"}},
},
},
})]
out = sanitize_tool_schemas(tools)
prop = out[0]["function"]["parameters"]["properties"]["input"]
assert prop["$ref"] == "#/$defs/Payload"
assert "default" not in prop
assert prop.get("nullable") is True
def test_ref_description_preserved():
"""Annotation siblings that strict backends allow should survive."""
tools = [_tool("t", {
"type": "object",
"properties": {
"payload": {
"$ref": "#/$defs/Payload",
"description": "The payload",
},
},
"$defs": {
"Payload": {"type": "object", "properties": {}},
},
})]
out = sanitize_tool_schemas(tools)
payload = out[0]["function"]["parameters"]["properties"]["payload"]
assert payload["description"] == "The payload"
assert payload["$ref"] == "#/$defs/Payload"
def test_empty_tools_list_returns_empty():
assert sanitize_tool_schemas([]) == []