mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-29 18:46:59 +00:00
fix(schema): preserve dependentRequired property names
This commit is contained in:
parent
3cedac00b7
commit
9dcb44a219
2 changed files with 73 additions and 1 deletions
|
|
@ -867,3 +867,73 @@ def test_unrename_passes_unknown_keys_through():
|
|||
def test_sanitize_property_key_empty_falls_back():
|
||||
assert sanitize_property_key("~~~") == "___"
|
||||
assert sanitize_property_key("") == "param"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# dependentRequired -- literal property-name strings must survive
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_dependent_required_preserved_through_public_api():
|
||||
"""dependentRequired values are literal property names, not schemas."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"owner": {"type": "string"},
|
||||
"repo": {"type": "string"},
|
||||
"organization": {"type": "string"},
|
||||
},
|
||||
"dependentRequired": {
|
||||
"owner": ["repo", "organization"],
|
||||
"repo": ["owner"],
|
||||
},
|
||||
}
|
||||
tools = [_tool("t", copy.deepcopy(schema))]
|
||||
out = sanitize_tool_schemas(tools)
|
||||
params = out[0]["function"]["parameters"]
|
||||
dep = params.get("dependentRequired", {})
|
||||
# Values are the original property-name strings unchanged.
|
||||
assert dep.get("owner") == ["repo", "organization"]
|
||||
assert dep.get("repo") == ["owner"]
|
||||
# Normal property schemas are still present and valid.
|
||||
assert params["properties"]["owner"] == {"type": "string"}
|
||||
assert params["properties"]["repo"] == {"type": "string"}
|
||||
assert params["properties"]["organization"] == {"type": "string"}
|
||||
|
||||
|
||||
def test_dependent_required_does_not_mutate_original_input():
|
||||
"""The original schema's dependentRequired must be unchanged after sanitize."""
|
||||
original_dep = {"owner": ["repo", "organization"], "repo": ["owner"]}
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"owner": {"type": "string"},
|
||||
"repo": {"type": "string"},
|
||||
"organization": {"type": "string"},
|
||||
},
|
||||
"dependentRequired": {k: list(v) for k, v in original_dep.items()},
|
||||
}
|
||||
saved_copy = copy.deepcopy(schema)
|
||||
tools = [_tool("t", schema)]
|
||||
_ = sanitize_tool_schemas(tools)
|
||||
assert schema == saved_copy
|
||||
assert schema["dependentRequired"] == original_dep
|
||||
|
||||
|
||||
def test_dependent_schemas_still_recursively_sanitized():
|
||||
"""dependentSchemas (real schemas, not literal lists) must still be sanitized."""
|
||||
schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"owner": {"type": "string"},
|
||||
},
|
||||
"dependentSchemas": {
|
||||
"owner": {"type": "object"}, # bare object -- needs properties: {}
|
||||
},
|
||||
}
|
||||
tools = [_tool("t", copy.deepcopy(schema))]
|
||||
out = sanitize_tool_schemas(tools)
|
||||
dep_schemas = out[0]["function"]["parameters"]["dependentSchemas"]
|
||||
assert dep_schemas["owner"] == {"type": "object", "properties": {}}, (
|
||||
f"dependentSchemas['owner'] was not fully sanitized: {dep_schemas['owner']!r}"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -406,11 +406,13 @@ def _sanitize_node(node: Any, path: str) -> Any:
|
|||
_sanitize_node(item, f"{path}.{key}[{i}]")
|
||||
for i, item in enumerate(value)
|
||||
]
|
||||
elif key in {"required", "enum", "examples"}:
|
||||
elif key in {"required", "enum", "examples", "dependentRequired"}:
|
||||
# Schema "sibling" keywords whose values are NOT schemas:
|
||||
# - ``required``: list of property-name strings
|
||||
# - ``enum``: list of literal values (any JSON type)
|
||||
# - ``examples``: list of example values (any JSON type)
|
||||
# - ``dependentRequired``: mapping of property names to lists of
|
||||
# required property-name strings (JSON Schema 2020-12)
|
||||
# Recursing into these with _sanitize_node() would mis-interpret
|
||||
# literal strings like "path" as bare-string schemas and replace
|
||||
# them with {"type": "object"} dicts. Pass through unchanged
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue