"""Tests for the tool registry and argument validation.""" from stt_daemon.assistant.tools import Tool, ToolRegistry, default_registry def test_default_registry_exposes_get_datetime(): registry = default_registry() tool = registry.get("get_datetime") assert tool is not None assert tool.side_effect == "read_only" spec = registry.specs()[0] assert spec["type"] == "function" assert spec["function"]["name"] == "get_datetime" def test_get_datetime_returns_iso_timestamp(): tool = default_registry().get("get_datetime") assert tool is not None assert "T" in tool.run({}) def test_validate_rejects_unknown_tool(): args, error = default_registry().validate("nope", "{}") assert args is None assert error is not None and "unknown tool" in error def test_validate_rejects_malformed_json(): args, error = default_registry().validate("get_datetime", "{not json") assert args is None assert error is not None and "invalid JSON" in error def test_validate_rejects_non_object_arguments(): args, error = default_registry().validate("get_datetime", "[1, 2]") assert args is None assert error is not None and "object" in error def test_validate_accepts_empty_object(): args, error = default_registry().validate("get_datetime", "{}") assert args == {} assert error is None def test_schema_requires_checks_unknown_and_types(): registry = ToolRegistry() registry.register( Tool( name="set_volume", description="Set the volume", parameters={ "type": "object", "properties": {"level": {"type": "integer"}}, "required": ["level"], }, run=lambda args: "ok", ) ) def reject(arguments, fragment): args, error = registry.validate("set_volume", arguments) assert args is None assert error is not None and fragment in error reject("{}", "missing required") reject('{"level": 1, "x": 2}', "unexpected argument") reject('{"level": "loud"}', "must be integer") reject('{"level": true}', "must be integer") assert registry.validate("set_volume", '{"level": 5}') == ({"level": 5}, None)