Files
hermes-agent/tests/test_model_tools.py
teknium1 5c867fd79f test: strengthen assertions across 3 more test files (batch 2)
test_run_agent.py (2 weak → 0, +13 assertions):
  - Session ID validated against actual YYYYMMDD_HHMMSS_hex format
  - API failure verifies error message propagation
  - Invalid JSON args verifies empty dict fallback + message structure
  - Context compression verifies final_response + completed flag
  - Invalid tool name retry verifies api_calls count
  - Invalid response verifies completed/failed/error structure

test_model_tools.py (3 weak → 0):
  - Unknown tool error includes tool name in message
  - Exception returns dict with 'error' key + non-empty message
  - get_all_tool_names verifies both web_search AND terminal present

test_approval.py (1 weak → 0, assert ratio 1.1 → 2.2):
  - Dangerous commands verify description content (delete, shell, drop, etc.)
  - Safe commands explicitly assert key AND desc are None
  - Pre/post condition checks for state management
2026-03-05 18:46:30 -08:00

104 lines
3.7 KiB
Python

"""Tests for model_tools.py — function call dispatch, agent-loop interception, legacy toolsets."""
import json
import pytest
from model_tools import (
handle_function_call,
get_all_tool_names,
get_toolset_for_tool,
_AGENT_LOOP_TOOLS,
_LEGACY_TOOLSET_MAP,
TOOL_TO_TOOLSET_MAP,
)
# =========================================================================
# handle_function_call
# =========================================================================
class TestHandleFunctionCall:
def test_agent_loop_tool_returns_error(self):
for tool_name in _AGENT_LOOP_TOOLS:
result = json.loads(handle_function_call(tool_name, {}))
assert "error" in result
assert "agent loop" in result["error"].lower()
def test_unknown_tool_returns_error(self):
result = json.loads(handle_function_call("totally_fake_tool_xyz", {}))
assert "error" in result
assert "totally_fake_tool_xyz" in result["error"]
def test_exception_returns_json_error(self):
# Even if something goes wrong, should return valid JSON
result = handle_function_call("web_search", None) # None args may cause issues
parsed = json.loads(result)
assert isinstance(parsed, dict)
assert "error" in parsed
assert len(parsed["error"]) > 0
assert "error" in parsed["error"].lower() or "failed" in parsed["error"].lower()
# =========================================================================
# Agent loop tools
# =========================================================================
class TestAgentLoopTools:
def test_expected_tools_in_set(self):
assert "todo" in _AGENT_LOOP_TOOLS
assert "memory" in _AGENT_LOOP_TOOLS
assert "session_search" in _AGENT_LOOP_TOOLS
assert "delegate_task" in _AGENT_LOOP_TOOLS
def test_no_regular_tools_in_set(self):
assert "web_search" not in _AGENT_LOOP_TOOLS
assert "terminal" not in _AGENT_LOOP_TOOLS
# =========================================================================
# Legacy toolset map
# =========================================================================
class TestLegacyToolsetMap:
def test_expected_legacy_names(self):
expected = [
"web_tools", "terminal_tools", "vision_tools", "moa_tools",
"image_tools", "skills_tools", "browser_tools", "cronjob_tools",
"rl_tools", "file_tools", "tts_tools",
]
for name in expected:
assert name in _LEGACY_TOOLSET_MAP, f"Missing legacy toolset: {name}"
def test_values_are_lists_of_strings(self):
for name, tools in _LEGACY_TOOLSET_MAP.items():
assert isinstance(tools, list), f"{name} is not a list"
for tool in tools:
assert isinstance(tool, str), f"{name} contains non-string: {tool}"
# =========================================================================
# Backward-compat wrappers
# =========================================================================
class TestBackwardCompat:
def test_get_all_tool_names_returns_list(self):
names = get_all_tool_names()
assert isinstance(names, list)
assert len(names) > 0
# Should contain well-known tools
assert "web_search" in names
assert "terminal" in names
def test_get_toolset_for_tool(self):
result = get_toolset_for_tool("web_search")
assert result is not None
assert isinstance(result, str)
def test_get_toolset_for_unknown_tool(self):
result = get_toolset_for_tool("totally_nonexistent_tool")
assert result is None
def test_tool_to_toolset_map(self):
assert isinstance(TOOL_TO_TOOLSET_MAP, dict)
assert len(TOOL_TO_TOOLSET_MAP) > 0