"""ASV benchmarks for context tier runtime logic (issue #821). Measures the overhead of auto-promotion on access, staleness enforcement, and budget-based eviction. """ from __future__ import annotations import importlib import sys from datetime import UTC, datetime, timedelta from pathlib import Path # Ensure source tree is importable _SRC = str(Path(__file__).resolve().parents[1] / "src") if _SRC not in sys.path: sys.path.insert(0, _SRC) import cleveragents # noqa: E402 importlib.reload(cleveragents) from cleveragents.application.services.context_tiers import ( # noqa: E402 ContextTierService, ) from cleveragents.domain.models.acms.tiers import ( # noqa: E402 ContextTier, TierBudget, TieredFragment, ) def _make_frag( fid: str, tier: ContextTier, tokens: int = 50, last_accessed: datetime | None = None, ) -> TieredFragment: frag = TieredFragment( fragment_id=fid, content="bench", tier=tier, token_count=tokens, project_name="bench", ) if last_accessed is not None: frag.last_accessed = last_accessed return frag class AutoPromotionSuite: """Benchmark auto-promotion on repeated ``get()`` calls.""" timeout = 60 def setup(self) -> None: self.service = ContextTierService(settings=None) frag = _make_frag("bench-promote", ContextTier.COLD) self.service.store(frag) def time_auto_promote_5_accesses(self) -> None: for _ in range(5): self.service.get("bench-promote") class StalenessEnforcementSuite: """Benchmark ``enforce_staleness()`` with varying fragment counts.""" timeout = 60 def setup(self) -> None: self.service = ContextTierService(settings=None) stale = datetime.now(tz=UTC) - timedelta(hours=25) for i in range(100): frag = _make_frag(f"stale-{i:04d}", ContextTier.HOT, last_accessed=stale) self.service.store(frag) def time_enforce_staleness_100_fragments(self) -> None: self.service.enforce_staleness() class BudgetEvictionSuite: """Benchmark budget-based eviction on hot-tier overflow.""" timeout = 60 def setup(self) -> None: self.service = ContextTierService(settings=None) self.service._budget = TierBudget(max_tokens_hot=500) old_time = datetime.now(tz=UTC) - timedelta(minutes=100) for i in range(10): ts = old_time + timedelta(minutes=i) frag = _make_frag( f"budget-{i:03d}", ContextTier.HOT, tokens=50, last_accessed=ts, ) self.service.store(frag) self.overflow_frag = _make_frag( "overflow", ContextTier.HOT, tokens=50, ) def time_store_with_budget_eviction(self) -> None: self.service.store(self.overflow_frag) class TierEventEmissionSuite: """Benchmark tier transition event emission overhead.""" timeout = 60 def setup(self) -> None: from collections.abc import Callable from cleveragents.infrastructure.events.models import DomainEvent from cleveragents.infrastructure.events.types import EventType class _NullBus: def emit(self, event: DomainEvent) -> None: pass def subscribe( self, event_type: EventType, handler: Callable[[DomainEvent], None], ) -> None: pass self.service = ContextTierService( settings=None, event_bus=_NullBus(), ) frag = _make_frag("evt-bench", ContextTier.COLD) self.service.store(frag) def time_promote_with_event(self) -> None: self.service.promote("evt-bench")