Lazy-load agent registry (frontmatter index, parse on demand), copy agents by path during install, fix Makefile template tab lint issue, add registry performance tests, bump to 1.1.0, document CLI reinstall after pull.
252 lines
6.8 KiB
Python
252 lines
6.8 KiB
Python
"""Tests for agent registry functionality."""
|
|
|
|
from kaizen_agentic.registry import AgentRegistry, AgentDefinition, AgentCategory
|
|
|
|
|
|
def test_agent_definition_from_file(tmp_path):
|
|
"""Test creating AgentDefinition from a markdown file."""
|
|
agent_content = """---
|
|
name: test-agent
|
|
description: A test agent for demonstration
|
|
model: inherit
|
|
---
|
|
|
|
# Test Agent
|
|
|
|
This is a test agent that demonstrates the functionality.
|
|
|
|
It uses todo-keeper and changelog-keeper agents for dependencies.
|
|
"""
|
|
|
|
agent_file = tmp_path / "agent-test-agent.md"
|
|
agent_file.write_text(agent_content)
|
|
|
|
agent_def = AgentDefinition.from_file(agent_file)
|
|
|
|
assert agent_def.name == "test-agent"
|
|
assert agent_def.description == "A test agent for demonstration"
|
|
assert agent_def.model == "inherit"
|
|
assert agent_def.file_path == agent_file
|
|
|
|
|
|
def test_agent_registry_load_agents(tmp_path):
|
|
"""Test loading agents from directory."""
|
|
# Create test agents
|
|
agent1_content = """---
|
|
name: agent-one
|
|
description: First test agent
|
|
---
|
|
|
|
# Agent One
|
|
"""
|
|
|
|
agent2_content = """---
|
|
name: agent-two
|
|
description: Second test agent
|
|
---
|
|
|
|
# Agent Two
|
|
"""
|
|
|
|
(tmp_path / "agent-agent-one.md").write_text(agent1_content)
|
|
(tmp_path / "agent-agent-two.md").write_text(agent2_content)
|
|
|
|
registry = AgentRegistry(tmp_path)
|
|
|
|
assert registry.agent_names() == ["agent-one", "agent-two"]
|
|
assert registry.get_agent("agent-one") is not None
|
|
assert registry.get_agent("agent-two") is not None
|
|
|
|
|
|
def test_agent_registry_get_agent(tmp_path):
|
|
"""Test getting specific agent."""
|
|
agent_content = """---
|
|
name: test-agent
|
|
description: A test agent
|
|
---
|
|
|
|
# Test Agent
|
|
"""
|
|
|
|
(tmp_path / "agent-test-agent.md").write_text(agent_content)
|
|
registry = AgentRegistry(tmp_path)
|
|
|
|
agent = registry.get_agent("test-agent")
|
|
assert agent is not None
|
|
assert agent.name == "test-agent"
|
|
|
|
missing_agent = registry.get_agent("missing-agent")
|
|
assert missing_agent is None
|
|
|
|
|
|
def test_agent_registry_list_agents(tmp_path):
|
|
"""Test listing agents."""
|
|
# Create test agents with different categories
|
|
todo_agent = """---
|
|
name: todo-keeper
|
|
description: Manages TODO files
|
|
---
|
|
|
|
# TODO Keeper
|
|
"""
|
|
|
|
test_agent = """---
|
|
name: test-runner
|
|
description: Runs tests
|
|
---
|
|
|
|
# Test Runner
|
|
"""
|
|
|
|
(tmp_path / "agent-todo-keeper.md").write_text(todo_agent)
|
|
(tmp_path / "agent-test-runner.md").write_text(test_agent)
|
|
|
|
registry = AgentRegistry(tmp_path)
|
|
|
|
all_agents = registry.list_agents()
|
|
assert len(all_agents) == 2
|
|
|
|
# Test filtering by category
|
|
project_agents = registry.list_agents(AgentCategory.PROJECT_MANAGEMENT)
|
|
assert len(project_agents) == 1
|
|
assert project_agents[0].name == "todo-keeper"
|
|
|
|
|
|
def test_agent_registry_resolve_dependencies(tmp_path):
|
|
"""Test dependency resolution."""
|
|
# Create agents with dependencies
|
|
base_agent = """---
|
|
name: base-agent
|
|
description: Base agent with no dependencies
|
|
---
|
|
|
|
# Base Agent
|
|
"""
|
|
|
|
dependent_agent = """---
|
|
name: dependent-agent
|
|
description: Agent that depends on base-agent
|
|
dependencies: ["base-agent"]
|
|
---
|
|
|
|
# Dependent Agent
|
|
|
|
This agent uses base-agent for functionality.
|
|
"""
|
|
|
|
complex_agent = """---
|
|
name: complex-agent
|
|
description: Agent with multiple dependencies
|
|
dependencies: ["base-agent", "dependent-agent"]
|
|
---
|
|
|
|
# Complex Agent
|
|
|
|
This agent uses both base-agent and dependent-agent.
|
|
"""
|
|
|
|
(tmp_path / "agent-base-agent.md").write_text(base_agent)
|
|
(tmp_path / "agent-dependent-agent.md").write_text(dependent_agent)
|
|
(tmp_path / "agent-complex-agent.md").write_text(complex_agent)
|
|
|
|
registry = AgentRegistry(tmp_path)
|
|
|
|
# Test simple dependency resolution
|
|
resolved = registry.resolve_dependencies(["dependent-agent"])
|
|
assert "base-agent" in resolved
|
|
assert "dependent-agent" in resolved
|
|
|
|
# Test complex dependency resolution
|
|
resolved = registry.resolve_dependencies(["complex-agent"])
|
|
assert all(
|
|
agent in resolved
|
|
for agent in ["base-agent", "dependent-agent", "complex-agent"]
|
|
)
|
|
|
|
|
|
def test_agent_registry_get_templates(tmp_path):
|
|
"""Test getting predefined templates."""
|
|
registry = AgentRegistry(tmp_path)
|
|
templates = registry.get_agent_templates()
|
|
|
|
assert "python-basic" in templates
|
|
assert "python-web" in templates
|
|
assert "python-cli" in templates
|
|
assert "python-data" in templates
|
|
assert "comprehensive" in templates
|
|
|
|
# Check that templates contain expected agents
|
|
assert "setupRepository" in templates["python-basic"]
|
|
assert "keepaTodofile" in templates["python-basic"]
|
|
|
|
|
|
def test_agent_registry_validate_agents(tmp_path):
|
|
"""Test agent validation."""
|
|
# Create valid agent
|
|
valid_agent = """---
|
|
name: valid-agent
|
|
description: A valid agent
|
|
---
|
|
|
|
# Valid Agent
|
|
"""
|
|
|
|
# Create agent with missing dependency
|
|
missing_dep_agent = """---
|
|
name: missing-dep-agent
|
|
description: Agent with missing dependency
|
|
dependencies: ["non-existent-agent"]
|
|
---
|
|
|
|
# Missing Dependency Agent
|
|
"""
|
|
|
|
(tmp_path / "agent-valid-agent.md").write_text(valid_agent)
|
|
(tmp_path / "agent-missing-dep-agent.md").write_text(missing_dep_agent)
|
|
|
|
registry = AgentRegistry(tmp_path)
|
|
|
|
errors = registry.validate_agents()
|
|
# Should have one error for missing dependency
|
|
assert len(errors) == 1
|
|
assert "missing-dep-agent" in errors
|
|
assert "Missing dependency: non-existent-agent" in errors["missing-dep-agent"]
|
|
|
|
|
|
def test_agent_category_determination():
|
|
"""Test automatic category determination."""
|
|
# Test project management category
|
|
result = AgentDefinition._determine_category("todo-keeper", "")
|
|
assert result == AgentCategory.PROJECT_MANAGEMENT
|
|
|
|
result = AgentDefinition._determine_category("changelog-helper", "")
|
|
assert result == AgentCategory.PROJECT_MANAGEMENT
|
|
|
|
# Test testing category
|
|
result = AgentDefinition._determine_category("test-runner", "")
|
|
assert result == AgentCategory.TESTING
|
|
|
|
result = AgentDefinition._determine_category("tdd-workflow", "")
|
|
assert result == AgentCategory.TESTING
|
|
|
|
# Test code quality category
|
|
result = AgentDefinition._determine_category("code-refactoring", "")
|
|
assert result == AgentCategory.CODE_QUALITY
|
|
|
|
result = AgentDefinition._determine_category("optimization-helper", "")
|
|
assert result == AgentCategory.CODE_QUALITY
|
|
|
|
# Test documentation category
|
|
result = AgentDefinition._determine_category("documentation-generator", "")
|
|
assert result == AgentCategory.DOCUMENTATION
|
|
|
|
result = AgentDefinition._determine_category("claude-helper", "")
|
|
assert result == AgentCategory.DOCUMENTATION
|
|
|
|
# Test infrastructure category
|
|
result = AgentDefinition._determine_category("setup-repository", "")
|
|
assert result == AgentCategory.INFRASTRUCTURE
|
|
|
|
result = AgentDefinition._determine_category("tooling-manager", "")
|
|
assert result == AgentCategory.INFRASTRUCTURE
|