""" Unit tests for the tool registry. Tests: - BUILTIN_TOOLS contains all 4 expected tools - get_tools_for_agent filters correctly based on agent.tool_assignments - to_litellm_format produces valid OpenAI function-calling schema - ToolDefinition model validation """ from __future__ import annotations import uuid from unittest.mock import MagicMock # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- def make_agent(tool_list: list[str]) -> MagicMock: """Create a mock Agent with tool_assignments set.""" agent = MagicMock() agent.id = uuid.uuid4() agent.tool_assignments = tool_list return agent # --------------------------------------------------------------------------- # Tests # --------------------------------------------------------------------------- class TestBuiltinTools: """BUILTIN_TOOLS registry contains the correct tool definitions.""" def test_all_four_tools_present(self): from orchestrator.tools.registry import BUILTIN_TOOLS assert "web_search" in BUILTIN_TOOLS assert "kb_search" in BUILTIN_TOOLS assert "http_request" in BUILTIN_TOOLS assert "calendar_lookup" in BUILTIN_TOOLS def test_tool_definitions_have_required_fields(self): from orchestrator.tools.registry import BUILTIN_TOOLS for name, tool in BUILTIN_TOOLS.items(): assert tool.name == name, f"Tool name mismatch for {name}" assert tool.description, f"Tool {name} missing description" assert isinstance(tool.parameters, dict), f"Tool {name} parameters must be dict" assert "type" in tool.parameters, f"Tool {name} parameters missing 'type' key" assert tool.handler is not None, f"Tool {name} has no handler" def test_http_request_requires_confirmation(self): from orchestrator.tools.registry import BUILTIN_TOOLS assert BUILTIN_TOOLS["http_request"].requires_confirmation is True def test_web_search_no_confirmation(self): from orchestrator.tools.registry import BUILTIN_TOOLS assert BUILTIN_TOOLS["web_search"].requires_confirmation is False def test_kb_search_no_confirmation(self): from orchestrator.tools.registry import BUILTIN_TOOLS assert BUILTIN_TOOLS["kb_search"].requires_confirmation is False def test_calendar_lookup_no_confirmation(self): from orchestrator.tools.registry import BUILTIN_TOOLS assert BUILTIN_TOOLS["calendar_lookup"].requires_confirmation is False class TestGetToolsForAgent: """get_tools_for_agent filters BUILTIN_TOOLS by agent's tool_assignments list.""" def test_filters_to_assigned_tools(self): from orchestrator.tools.registry import get_tools_for_agent agent = make_agent(["web_search", "kb_search"]) result = get_tools_for_agent(agent) assert set(result.keys()) == {"web_search", "kb_search"} def test_empty_tool_list_returns_empty(self): from orchestrator.tools.registry import get_tools_for_agent agent = make_agent([]) result = get_tools_for_agent(agent) assert result == {} def test_unknown_tools_ignored_silently(self): """Tools in agent.tool_assignments that don't exist in BUILTIN_TOOLS are skipped.""" from orchestrator.tools.registry import get_tools_for_agent agent = make_agent(["web_search", "nonexistent_tool"]) result = get_tools_for_agent(agent) assert "web_search" in result assert "nonexistent_tool" not in result def test_all_tools_accessible(self): from orchestrator.tools.registry import BUILTIN_TOOLS, get_tools_for_agent agent = make_agent(list(BUILTIN_TOOLS.keys())) result = get_tools_for_agent(agent) assert set(result.keys()) == set(BUILTIN_TOOLS.keys()) class TestToLitellmFormat: """to_litellm_format converts tool definitions to OpenAI function-calling schema.""" def test_returns_list_of_dicts(self): from orchestrator.tools.registry import BUILTIN_TOOLS, to_litellm_format result = to_litellm_format({"web_search": BUILTIN_TOOLS["web_search"]}) assert isinstance(result, list) assert len(result) == 1 def test_openai_schema_structure(self): """Each entry must have type='function' and a nested function object.""" from orchestrator.tools.registry import BUILTIN_TOOLS, to_litellm_format result = to_litellm_format({"web_search": BUILTIN_TOOLS["web_search"]}) entry = result[0] assert entry["type"] == "function" assert "function" in entry func = entry["function"] assert func["name"] == "web_search" assert "description" in func assert "parameters" in func def test_empty_tools_returns_empty_list(self): from orchestrator.tools.registry import to_litellm_format assert to_litellm_format({}) == [] def test_multiple_tools_converted(self): from orchestrator.tools.registry import BUILTIN_TOOLS, to_litellm_format result = to_litellm_format(BUILTIN_TOOLS) assert len(result) == 4