Files
cleveragents-core/benchmarks/predictive_error_prevention_bench.py
freemo 583e6b7ea2
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 17s
CI / security (pull_request) Successful in 36s
CI / typecheck (pull_request) Successful in 54s
CI / unit_tests (pull_request) Successful in 2m39s
CI / integration_tests (pull_request) Successful in 3m10s
CI / docker (pull_request) Successful in 40s
CI / coverage (pull_request) Successful in 5m0s
CI / lint (push) Successful in 14s
CI / build (push) Successful in 15s
CI / quality (push) Successful in 16s
CI / security (push) Successful in 34s
CI / typecheck (push) Successful in 35s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 2m23s
CI / docker (push) Successful in 38s
CI / integration_tests (push) Successful in 3m8s
CI / coverage (push) Successful in 5m10s
CI / benchmark-publish (push) Successful in 16m26s
CI / benchmark-regression (pull_request) Successful in 30m12s
feat(correcting-plans): implement Predictive Error Prevention (Layer 4) with Error Pattern Database
Implement spec-mandated Layer 4 Predictive Error Prevention system:

- ErrorPattern domain model with pattern text, historical failures,
  preventive checks, frequency tracking, and keyword-based matching.
- ErrorPatternRepository with in-memory CRUD + context-matching query.
- ErrorPatternService with record_failure(), match_patterns(), and
  get_statistics() methods.
- Wire into plan execution via plan_lifecycle_service pre-execution hook.
- Add error pattern statistics to CLI diagnostics output.

Behave BDD: 11 scenarios covering recording, matching, formatting, stats.
Robot Framework: 3 integration smoke tests.
ASV benchmarks: pattern matching performance.

ISSUES CLOSED: #571
2026-03-08 21:53:21 -04:00

159 lines
4.5 KiB
Python

"""ASV benchmarks for Layer 4 — Predictive Error Prevention.
Measures pattern matching performance with large databases,
recording throughput, and guidance generation latency.
"""
from __future__ import annotations
from cleveragents.application.services.error_pattern_service import (
ErrorPatternService,
)
from cleveragents.infrastructure.database.error_pattern_repository import (
ErrorPatternRepository,
)
def _make_service(num_patterns: int = 0) -> ErrorPatternService:
"""Create a service and optionally seed it with patterns."""
repo = ErrorPatternRepository()
service = ErrorPatternService(repository=repo)
for i in range(num_patterns):
service.record_failure(
pattern_text=f"Error pattern number {i} in module_{i % 10}",
failure_description=f"Failure description {i}",
preventive_checks=(f"Check {i}-a", f"Check {i}-b"),
keywords=(f"pattern{i}", f"module_{i % 10}", "error"),
)
return service
class TimeRecordSingle:
"""Benchmark recording a single failure pattern."""
timeout = 30
def setup(self) -> None:
self.service = _make_service()
def time_record_single_failure(self) -> None:
self.service.record_failure(
pattern_text="Benchmark failure pattern",
failure_description="Test failure",
preventive_checks=("Check A", "Check B"),
keywords=("benchmark", "failure"),
)
class TimeRecordBatch:
"""Benchmark recording a batch of failure patterns."""
timeout = 60
def setup(self) -> None:
self.service = _make_service()
def time_record_100_failures(self) -> None:
for i in range(100):
self.service.record_failure(
pattern_text=f"Batch failure pattern {i}",
failure_description=f"Failure {i}",
preventive_checks=(f"Check {i}",),
keywords=(f"batch{i}",),
)
class TimeMatchSmallDB:
"""Benchmark pattern matching against a small database (10 patterns)."""
timeout = 30
def setup(self) -> None:
self.service = _make_service(num_patterns=10)
def time_match_context_small(self) -> None:
self.service.match_patterns("We need to fix error pattern number 5 in module_5")
class TimeMatchMediumDB:
"""Benchmark pattern matching against a medium database (100 patterns)."""
timeout = 60
def setup(self) -> None:
self.service = _make_service(num_patterns=100)
def time_match_context_medium(self) -> None:
self.service.match_patterns(
"We need to fix error pattern number 50 in module_5"
)
class TimeMatchLargeDB:
"""Benchmark pattern matching against a large database (1000 patterns)."""
timeout = 120
def setup(self) -> None:
self.service = _make_service(num_patterns=1000)
def time_match_context_large(self) -> None:
self.service.match_patterns(
"We need to fix error pattern number 500 in module_5"
)
def time_match_no_results_large(self) -> None:
self.service.match_patterns(
"Completely unrelated context about cooking recipes"
)
class TimeGuidanceFormatting:
"""Benchmark guidance formatting after matching."""
timeout = 30
def setup(self) -> None:
self.service = _make_service(num_patterns=50)
self.guidance = self.service.match_patterns("We need to fix error in module_5")
def time_format_guidance(self) -> None:
self.guidance.format_for_context()
class TimeStatistics:
"""Benchmark statistics computation."""
timeout = 30
def setup(self) -> None:
self.service = _make_service(num_patterns=500)
def time_get_statistics(self) -> None:
self.service.get_statistics()
def time_list_patterns(self) -> None:
self.service.list_patterns()
class TimeDuplicateRecording:
"""Benchmark recording duplicate patterns (frequency updates)."""
timeout = 60
def setup(self) -> None:
self.service = _make_service()
self.service.record_failure(
pattern_text="Recurring failure",
failure_description="Initial occurrence",
preventive_checks=("Check A",),
keywords=("recurring",),
)
def time_record_duplicate_100_times(self) -> None:
for i in range(100):
self.service.record_failure(
pattern_text="Recurring failure",
failure_description=f"Occurrence {i + 2}",
)