"""Robot Framework helper for context tier runtime integration tests. Each command exercises the runtime logic added by issue #821: auto-promotion, staleness enforcement, and budget enforcement. Usage:: python helper_context_tier_runtime.py Commands: auto-promote -- Verify auto-promotion on repeated access. staleness -- Verify enforce_staleness() demotes stale fragments. budget-evict -- Verify budget enforcement on store. event-emission -- Verify tier transition events are emitted. """ from __future__ import annotations import sys from collections.abc import Callable 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) from cleveragents.application.services.context_tiers import ( # noqa: E402 ContextTierService, ) from cleveragents.domain.models.acms.tiers import ( # noqa: E402 ContextTier, TierBudget, TieredFragment, ) from cleveragents.infrastructure.events.models import DomainEvent # noqa: E402 from cleveragents.infrastructure.events.types import EventType # noqa: E402 class _EventCollector: """Simple event bus replacement that collects emitted events.""" def __init__(self) -> None: self.events: list[DomainEvent] = [] def emit(self, event: DomainEvent) -> None: self.events.append(event) def subscribe( self, event_type: EventType, handler: Callable[[DomainEvent], None], ) -> None: pass def _make_frag( fid: str, tier: ContextTier, tokens: int = 50, last_accessed: datetime | None = None, ) -> TieredFragment: frag = TieredFragment( fragment_id=fid, content="test", tier=tier, token_count=tokens, project_name="test", ) if last_accessed is not None: frag.last_accessed = last_accessed return frag def cmd_auto_promote() -> None: svc = ContextTierService(settings=None) frag = _make_frag("frag-01", ContextTier.COLD) svc.store(frag) for _ in range(5): svc.get("frag-01") result = svc._find_fragment("frag-01") assert result is not None, "Fragment disappeared" assert result.tier == ContextTier.WARM, ( f"Expected WARM (not HOT — counter reset prevents chain promotion)" f" after 5 accesses from cold, got {result.tier}" ) print("context-tier-runtime-auto-promote-ok") def cmd_staleness() -> None: svc = ContextTierService(settings=None) stale = datetime.now(tz=UTC) - timedelta(hours=25) frag = _make_frag("stale-01", ContextTier.HOT, last_accessed=stale) svc.store(frag) demoted = svc.enforce_staleness() assert "stale-01" in demoted, f"Expected stale-01 in demoted list: {demoted}" result = svc._find_fragment("stale-01") assert result is not None, "Fragment disappeared" assert result.tier == ContextTier.WARM, ( f"Expected WARM after staleness demotion, got {result.tier}" ) print("context-tier-runtime-staleness-ok") def cmd_budget_evict() -> None: svc = ContextTierService(settings=None) svc._budget = TierBudget(max_tokens_hot=100) old = datetime.now(tz=UTC) - timedelta(minutes=10) svc.store(_make_frag("old-01", ContextTier.HOT, tokens=50, last_accessed=old)) svc.store(_make_frag("new-01", ContextTier.HOT, tokens=50)) svc.store(_make_frag("overflow-01", ContextTier.HOT, tokens=50)) total = sum(f.token_count for f in svc._hot.values()) assert total <= 100, f"Hot tier over budget: {total} > 100" old_frag = svc._find_fragment("old-01") assert old_frag is None, "old-01 should have been evicted" print("context-tier-runtime-budget-evict-ok") def cmd_event_emission() -> None: collector = _EventCollector() svc = ContextTierService(settings=None, event_bus=collector) svc.store(_make_frag("evt-01", ContextTier.COLD)) svc.promote("evt-01") promoted = [e for e in collector.events if e.event_type == EventType.TIER_PROMOTED] assert len(promoted) >= 1, f"No TIER_PROMOTED events: {collector.events}" assert promoted[0].details["fragment_id"] == "evt-01" print("context-tier-runtime-event-emission-ok") _COMMANDS: dict[str, Callable[[], None]] = { "auto-promote": cmd_auto_promote, "staleness": cmd_staleness, "budget-evict": cmd_budget_evict, "event-emission": cmd_event_emission, } def main() -> None: if len(sys.argv) < 2 or sys.argv[1] not in _COMMANDS: valid = ", ".join(sorted(_COMMANDS.keys())) print(f"Usage: {sys.argv[0]} <{valid}>", file=sys.stderr) sys.exit(1) cmd = _COMMANDS[sys.argv[1]] cmd() if __name__ == "__main__": main()