test_parameter_sanitization.py•5.48 kB
"""Tests for parameter name sanitization in the LLM tool specification manager."""
from jentic.lib.agent_runtime.tool_specs import (
create_llm_tool_manager,
)
def test_anthropic_parameter_sanitization():
"""Test that parameter names are properly sanitized for Anthropic schema."""
# Operation with problematic keys (dots, spaces, etc.)
sample_operation = {
"method": "GET",
"path": "/users",
"inputs": {
"properties": {
"user.id": {"type": "string"},
"name.first": {"type": "string"},
"complex-key.with space": {"type": "string"},
},
"required": ["user.id"],
},
}
manager = create_llm_tool_manager()
manager.load_operations({"test-op-uuid": sample_operation})
# Get anthropic tool specs
specs = manager.get_tool_specs("anthropic")
tool = specs["tools"][0]
properties = tool["input_schema"]["properties"]
required = tool["input_schema"]["required"]
# Verify keys were sanitized correctly
assert "user_id" in properties
assert "name_first" in properties
assert "complex-key_with_space" in properties
assert "user.id" not in properties
# Verify required list was also sanitized
assert "user_id" in required
# Verify mapping is created for restoration
mapping = manager._parameter_mappings[tool["name"]]
assert mapping["user_id"] == "user.id"
# Test parameter restoration
test_inputs = {"user_id": "123", "name_first": "John"}
restored = manager.restore_input_parameter_names(tool["name"], test_inputs)
assert "user.id" in restored
assert restored["user.id"] == "123"
def test_edge_case_parameter_sanitization():
"""Test edge cases for parameter name sanitization."""
sample_operation = {
"method": "GET",
"path": "/edge-cases",
"inputs": {
"properties": {
"": {"type": "string"}, # Empty string
"a" * 100: {"type": "string"}, # Very long key
"!@#$%^&*()": {"type": "string"}, # Only special chars
" leading-trailing ": {"type": "string"}, # Leading/trailing spaces
"..multiple...dots..": {"type": "string"}, # Multiple dots
},
"required": ["!@#$%^&*()"],
},
}
manager = create_llm_tool_manager()
manager.load_operations({"edge-case-uuid": sample_operation})
# Get anthropic tool specs
specs = manager.get_tool_specs("anthropic")
tool = specs["tools"][0]
properties = tool["input_schema"]["properties"]
required = tool["input_schema"]["required"]
# Verify edge cases were handled correctly
assert "param" not in properties # Empty string or special chars should be excluded
assert "" not in properties # Empty string should be excluded
assert "!@#$%^&*()" not in properties # Special chars should be excluded
assert len(list(filter(lambda k: k.startswith("a" * 60), properties.keys()))) == 1 # Truncated
assert "leading-trailing" in properties # Spaces removed
assert "multiple_dots" in properties # Multiple dots/underscores consolidated
# Check that empty and special char keys were excluded, not added to mappings
mapping = manager._parameter_mappings[tool["name"]]
assert "" not in mapping.values() # Empty string should be excluded
assert "!@#$%^&*()" not in mapping.values() # Special chars should be excluded
# Verify required list excludes invalid parameters
assert len(required) == 0 # Special chars in required list should be excluded
# Test restoration with valid sanitized parameter names only
edge_inputs = {
list(filter(lambda k: k.startswith("a" * 60), properties.keys()))[0]: "truncated",
"leading-trailing": "spaces_removed",
"multiple_dots": "dots_consolidated",
}
restored = manager.restore_input_parameter_names(tool["name"], edge_inputs)
# Verify proper restoration of valid sanitized names
assert any(key.startswith("a" * 60) for key in restored)
assert " leading-trailing " in restored
assert "..multiple...dots.." in restored
long_key = list(filter(lambda k: len(k) >= 100, mapping.values()))
assert len(long_key) == 1 # Should have one long key in mappings
assert long_key[0] in restored # Long key restored
def test_valid_parameter_names_unchanged():
"""Test that valid parameter names are not modified."""
sample_operation = {
"method": "GET",
"path": "/users",
"inputs": {
"properties": {
"user_id": {"type": "string"},
"name": {"type": "string"},
"page-number": {"type": "integer"},
},
"required": ["user_id"],
},
}
manager = create_llm_tool_manager()
manager.load_operations({"op-uuid": sample_operation})
# Get anthropic tool specs
specs = manager.get_tool_specs("anthropic")
tool = specs["tools"][0]
properties = tool["input_schema"]["properties"]
# Verify valid keys remain unchanged
assert "user_id" in properties
assert "name" in properties
assert "page-number" in properties
# Verify mapping doesn't contain entries for valid keys
mapping = manager._parameter_mappings.get(tool["name"], {})
assert "user_id" not in mapping
assert "name" not in mapping
assert "page-number" not in mapping