Implemented the next missing parity slice around agent configurations.

This commit is contained in:
Abdelrahman Abdallah
2026-04-17 05:15:17 +02:00
parent 02674ba594
commit 872f4f89b5
11 changed files with 770 additions and 6 deletions
+52 -1
View File
@@ -6,7 +6,14 @@ import unittest
from pathlib import Path
from unittest.mock import patch
from src.agent_registry import load_agent_registry, render_agent_detail, render_agents_report
from src.agent_registry import (
create_agent_definition,
delete_agent_definition,
load_agent_registry,
render_agent_detail,
render_agents_report,
update_agent_definition,
)
def _write_agent(path: Path, *, name: str, description: str, body: str, extra: str = '') -> None:
@@ -22,6 +29,50 @@ def _write_agent(path: Path, *, name: str, description: str, body: str, extra: s
class AgentRegistryTests(unittest.TestCase):
def test_create_update_delete_agent_definition_roundtrip(self) -> None:
with tempfile.TemporaryDirectory() as home_dir, tempfile.TemporaryDirectory() as tmp_dir:
workspace = Path(tmp_dir)
with patch.dict(os.environ, {'HOME': home_dir}):
created = create_agent_definition(
workspace,
agent_type='reviewer',
description='Review implementation changes.',
system_prompt='Inspect diffs and summarize risks.',
source='project',
tools=('read_file', 'grep_search'),
model='demo-model',
initial_prompt='Start with changed files.',
)
self.assertEqual(created.action, 'created')
self.assertTrue(Path(created.file_path).exists())
snapshot = load_agent_registry(workspace)
detail = render_agent_detail(snapshot, 'reviewer')
self.assertIn('demo-model', detail)
self.assertIn('Start with changed files.', detail)
updated = update_agent_definition(
workspace,
agent_type='reviewer',
description='Review code and tests carefully.',
system_prompt='Focus on regressions and missing coverage.',
source='project',
)
self.assertEqual(updated.action, 'updated')
snapshot = load_agent_registry(workspace)
detail = render_agent_detail(snapshot, 'reviewer')
self.assertIn('Review code and tests carefully.', detail)
self.assertIn('Focus on regressions and missing coverage.', detail)
deleted = delete_agent_definition(
workspace,
agent_type='reviewer',
source='project',
)
self.assertEqual(deleted.action, 'deleted')
self.assertFalse(Path(deleted.file_path).exists())
def test_project_agent_overrides_built_in_agent(self) -> None:
with tempfile.TemporaryDirectory() as home_dir, tempfile.TemporaryDirectory() as tmp_dir:
workspace = Path(tmp_dir)
+27
View File
@@ -149,6 +149,33 @@ class AgentSlashCommandTests(unittest.TestCase):
self.assertIn('# Agent: reviewer', detail_result.final_output)
self.assertIn('Inspect code changes and summarize risks.', detail_result.final_output)
def test_agents_command_can_create_update_and_delete_project_agent(self) -> None:
with tempfile.TemporaryDirectory() as home_dir, tempfile.TemporaryDirectory() as tmp_dir:
workspace = Path(tmp_dir)
with patch.dict(os.environ, {'HOME': home_dir}):
agent = LocalCodingAgent(
model_config=ModelConfig(model='test-model'),
runtime_config=AgentRuntimeConfig(cwd=workspace),
)
create_result = agent.run(
'/agents create reviewer :: Review code changes carefully. :: Inspect code changes and summarize risks.'
)
self.assertIn('action=created', create_result.final_output)
self.assertTrue((workspace / '.claude' / 'agents' / 'reviewer.md').exists())
update_result = agent.run(
'/agents update reviewer Updated review description :: Focus on regressions and missing tests.'
)
self.assertIn('action=updated', update_result.final_output)
detail_result = agent.run('/agents reviewer')
self.assertIn('Updated review description', detail_result.final_output)
self.assertIn('Focus on regressions and missing tests.', detail_result.final_output)
delete_result = agent.run('/agents delete reviewer')
self.assertIn('action=deleted', delete_result.final_output)
self.assertFalse((workspace / '.claude' / 'agents' / 'reviewer.md').exists())
def test_mcp_and_resource_commands_render_local_reports(self) -> None:
with tempfile.TemporaryDirectory() as tmp_dir:
workspace = Path(tmp_dir)
+50 -1
View File
@@ -7,7 +7,7 @@ from dataclasses import replace
from pathlib import Path
from unittest.mock import patch
from src.main import _build_runtime_config, _build_agent, _run_agent_chat_loop, build_parser
from src.main import _build_runtime_config, _build_agent, _run_agent_chat_loop, build_parser, main
class FakeHTTPResponse:
@@ -221,6 +221,55 @@ class MainCliTests(unittest.TestCase):
self.assertTrue(args.all)
self.assertEqual(args.cwd, '.')
def test_parser_accepts_agent_management_commands(self) -> None:
parser = build_parser()
create_args = parser.parse_args(
['agents-create', 'reviewer', '--cwd', '.', '--description', 'Review code', '--prompt', 'Inspect diffs']
)
self.assertEqual(create_args.command, 'agents-create')
self.assertEqual(create_args.agent_type, 'reviewer')
self.assertEqual(create_args.description, 'Review code')
update_args = parser.parse_args(['agents-update', 'reviewer', '--cwd', '.', '--source', 'auto'])
self.assertEqual(update_args.command, 'agents-update')
self.assertEqual(update_args.source, 'auto')
delete_args = parser.parse_args(['agents-delete', 'reviewer', '--cwd', '.', '--source', 'project'])
self.assertEqual(delete_args.command, 'agents-delete')
self.assertEqual(delete_args.source, 'project')
def test_main_can_create_and_delete_agent_definition(self) -> None:
with tempfile.TemporaryDirectory() as home_dir, tempfile.TemporaryDirectory() as tmp_dir:
workspace = Path(tmp_dir)
with patch.dict('os.environ', {'HOME': home_dir}):
exit_code = main(
[
'agents-create',
'reviewer',
'--cwd',
str(workspace),
'--description',
'Review code carefully',
'--prompt',
'Inspect code and summarize risks.',
]
)
self.assertEqual(exit_code, 0)
self.assertTrue((workspace / '.claude' / 'agents' / 'reviewer.md').exists())
exit_code = main(
[
'agents-delete',
'reviewer',
'--cwd',
str(workspace),
'--source',
'project',
]
)
self.assertEqual(exit_code, 0)
self.assertFalse((workspace / '.claude' / 'agents' / 'reviewer.md').exists())
def test_parser_accepts_team_runtime_commands(self) -> None:
parser = build_parser()
args = parser.parse_args(['team-create', 'reviewers', '--member', 'alice', '--cwd', '.'])