Download tests/test_auto_dev/test_reflection_engine.py from techprotrade/annator-command-center: direct link, hf CLI and curl.
- Browser
- Download file 6.99 kB
-
https://huggingface.co/spaces/techprotrade/annator-command-center/resolve/main/tests/test_auto_dev/test_reflection_engine.py
- Command line
-
hf download hf://spaces/techprotrade/annator-command-center/tests/test_auto_dev/test_reflection_engine.py
-
curl -L -o test_reflection_engine.py https://huggingface.co/spaces/techprotrade/annator-command-center/resolve/main/tests/test_auto_dev/test_reflection_engine.py
6.99 kB
| """ | |
| Test ReflectionEngine pattern detection. | |
| Tests cover: | |
| - Event listening | |
| - Repeated failure pattern detection | |
| - Triggering MementoEngine after threshold | |
| - Pattern frequency tracking | |
| - Resetting patterns after successful promotion | |
| """ | |
| import pytest | |
| from unittest.mock import AsyncMock, MagicMock | |
| from core.auto_dev.reflection_engine import ReflectionEngine | |
| from core.auto_dev.event_hooks import TaskEvent | |
| class TestReflectionEngineEventListening: | |
| """Test ReflectionEngine listens to events.""" | |
| def test_subscribes_to_task_fail_events(self, auto_dev_db_session): | |
| """Test subscribes to task_fail events.""" | |
| engine = ReflectionEngine(db=auto_dev_db_session) | |
| engine.register() | |
| # Should have registered handler | |
| assert len(engine._failure_buffer) == 0 | |
| def test_tracks_event_metadata(self, auto_dev_db_session, sample_task_event): | |
| """Test tracks event metadata.""" | |
| engine = ReflectionEngine(db=auto_dev_db_session) | |
| # Mock capability gate to allow processing | |
| engine._should_process_agent = lambda agent_id, tenant_id: True | |
| import asyncio | |
| asyncio.run(engine.process_failure(sample_task_event)) | |
| assert len(engine._failure_buffer[sample_task_event.agent_id]) == 1 | |
| class TestReflectionEnginePatternDetection: | |
| """Test detects repeated failure patterns.""" | |
| async def test_identifies_repeated_failure_patterns(self, auto_dev_db_session, sample_task_event): | |
| """Test identifies repeated failure patterns.""" | |
| from unittest.mock import AsyncMock | |
| engine = ReflectionEngine(db=auto_dev_db_session, failure_threshold=2) | |
| # Mock capability gate to allow processing | |
| engine._should_process_agent = lambda agent_id, tenant_id: True | |
| # Mock _trigger_memento to avoid database query | |
| engine._trigger_memento = AsyncMock() | |
| # Process first failure | |
| await engine.process_failure(sample_task_event) | |
| # Check buffer has 1 failure | |
| assert len(engine._failure_buffer[sample_task_event.agent_id]) == 1 | |
| # Process second failure (should trigger) | |
| await engine.process_failure(sample_task_event) | |
| # Verify _trigger_memento was called (pattern detected) | |
| engine._trigger_memento.assert_called_once() | |
| # Note: Buffer is cleared after triggering, so we check the call happened | |
| async def test_groups_by_error_type(self, auto_dev_db_session): | |
| """Test groups by error type.""" | |
| from unittest.mock import AsyncMock | |
| engine = ReflectionEngine(db=auto_dev_db_session, failure_threshold=3) | |
| # Mock capability gate to allow processing | |
| engine._should_process_agent = lambda agent_id, tenant_id: True | |
| # Mock _trigger_memento to avoid database query | |
| engine._trigger_memento = AsyncMock() | |
| event1 = TaskEvent( | |
| episode_id="ep-001", | |
| agent_id="agent-001", | |
| tenant_id="tenant-001", | |
| task_description="Process sales data", | |
| error_trace="ValueError: Invalid format", | |
| outcome="failure", | |
| ) | |
| event2 = TaskEvent( | |
| episode_id="ep-002", | |
| agent_id="agent-001", | |
| tenant_id="tenant-001", | |
| task_description="Process sales data again", | |
| error_trace="ValueError: Invalid format", | |
| outcome="failure", | |
| ) | |
| await engine.process_failure(event1) | |
| await engine.process_failure(event2) | |
| # Should find similar failures | |
| similar = engine._find_similar_failures("agent-001", "Process sales data") | |
| assert len(similar) >= 1 | |
| class TestReflectionEngineTriggerThreshold: | |
| """Test triggers MementoEngine after threshold.""" | |
| async def test_triggers_after_n_failures(self, auto_dev_db_session, sample_task_event, monkeypatch): | |
| """Test triggers MementoEngine after N failures.""" | |
| engine = ReflectionEngine(db=auto_dev_db_session, failure_threshold=2) | |
| # Mock capability gate to allow processing | |
| engine._should_process_agent = lambda agent_id, tenant_id: True | |
| # Mock MementoEngine to avoid database requirements | |
| mock_memento = MagicMock() | |
| mock_candidate = MagicMock() | |
| mock_candidate.skill_name = "test_skill" | |
| mock_memento.generate_skill_candidate = AsyncMock(return_value=mock_candidate) | |
| import sys | |
| original_module = sys.modules.get("core.auto_dev.memento_engine") | |
| class MockMementoEngine: | |
| def __init__(self, db): | |
| pass | |
| sys.modules["core.auto_dev.memento_engine"] = MockMementoEngine | |
| sys.modules["core.auto_dev.memento_engine"].MementoEngine = lambda db: mock_memento | |
| try: | |
| # Process two failures | |
| await engine.process_failure(sample_task_event) | |
| await engine.process_failure(sample_task_event) | |
| # Should have triggered | |
| mock_memento.generate_skill_candidate.assert_called_once() | |
| finally: | |
| if original_module: | |
| sys.modules["core.auto_dev.memento_engine"] = original_module | |
| else: | |
| sys.modules.pop("core.auto_dev.memento_engine", None) | |
| async def test_prevents_duplicate_triggers(self, auto_dev_db_session, sample_task_event): | |
| """Test prevents duplicate triggers.""" | |
| engine = ReflectionEngine(db=auto_dev_db_session, failure_threshold=2) | |
| # Process same event multiple times | |
| for _ in range(5): | |
| await engine.process_failure(sample_task_event) | |
| # Buffer should be cleared after trigger | |
| assert len(engine._failure_buffer[sample_task_event.agent_id]) < 5 | |
| class TestReflectionEnginePatternTracking: | |
| """Test pattern frequency tracking.""" | |
| async def test_stores_pattern_metadata(self, auto_dev_db_session, sample_task_event): | |
| """Test stores pattern metadata.""" | |
| engine = ReflectionEngine(db=auto_dev_db_session) | |
| # Mock capability gate to allow processing | |
| engine._should_process_agent = lambda agent_id, tenant_id: True | |
| await engine.process_failure(sample_task_event) | |
| buffer = engine._failure_buffer[sample_task_event.agent_id] | |
| assert len(buffer) == 1 | |
| assert buffer[0]["episode_id"] == sample_task_event.episode_id | |
| assert buffer[0]["task_description"] == sample_task_event.task_description | |
| class TestReflectionEngineIntegration: | |
| """Test ReflectionEngine integration.""" | |
| def test_reflection_engine_initialization(self, auto_dev_db_session): | |
| """Test ReflectionEngine initializes correctly.""" | |
| engine = ReflectionEngine(db=auto_dev_db_session) | |
| assert engine.db == auto_dev_db_session | |
| assert engine.failure_threshold == 2 # Default | |
| assert len(engine._failure_buffer) == 0 | |