"""ASV benchmarks for ACMS v1 context assembly pipeline. Measures the performance of: - ContextFragment creation (with and without metadata) - ACMSPipeline.assemble with varying fragment counts - Tiered fusion strategy ranking - Recency strategy ranking """ from __future__ import annotations import importlib import sys from datetime import UTC, datetime from pathlib import Path _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.acms_service import ACMSPipeline # noqa: E402 from cleveragents.domain.models.core.context_fragment import ( # noqa: E402 ContextBudget, ContextFragment, FragmentProvenance, compute_context_hash, ) # Default provenance for benchmark fragments. _DEFAULT_PROV = FragmentProvenance(resource_uri="bench://default") class ContextFragmentSuite: """Benchmark ContextFragment creation throughput.""" def time_fragment_creation(self) -> None: """Benchmark creating a ContextFragment with defaults.""" ContextFragment( uko_node="bench://file", content="benchmark content", token_count=10, provenance=_DEFAULT_PROV, ) def time_fragment_with_metadata(self) -> None: """Benchmark creating a ContextFragment with metadata.""" ContextFragment( uko_node="bench://decision", content="benchmark with metadata", relevance_score=0.85, token_count=150, tier="hot", metadata={"author": "bench", "priority": "high"}, provenance=_DEFAULT_PROV, ) class ACMSPipelineSuite: """Benchmark ACMSPipeline.assemble throughput.""" def setup(self) -> None: """Set up pipeline and fragment lists for assembly benchmarks.""" self._pipeline = ACMSPipeline() self._budget = ContextBudget(max_tokens=100_000, reserved_tokens=0) self._frags_10 = [ ContextFragment( uko_node=f"bench://file/{i}", content=f"fragment {i}", relevance_score=round(i / 10, 1), token_count=50, provenance=_DEFAULT_PROV, ) for i in range(10) ] self._frags_100 = [ ContextFragment( uko_node=f"bench://file/{i}", content=f"fragment {i}", relevance_score=round((i % 10) / 10, 1), token_count=50, provenance=_DEFAULT_PROV, ) for i in range(100) ] self._frags_1000 = [ ContextFragment( uko_node=f"bench://file/{i}", content=f"fragment {i}", relevance_score=round((i % 10) / 10, 1), token_count=50, provenance=_DEFAULT_PROV, ) for i in range(1000) ] tiers = ("hot", "warm", "cold") self._tiered_frags = [ ContextFragment( uko_node=f"bench://file/{i}", content=f"fragment {i}", relevance_score=round((i % 10) / 10, 1), token_count=50, tier=tiers[i % 3], provenance=_DEFAULT_PROV, ) for i in range(100) ] # Recency benchmark fragments with distinct timestamps self._recency_frags = [ ContextFragment( uko_node=f"bench://file/{i}", content=f"fragment {i}", token_count=50, created_at=datetime(2024, 1, 1 + (i % 28), tzinfo=UTC), provenance=_DEFAULT_PROV, ) for i in range(100) ] def time_assemble_10_fragments(self) -> None: """Benchmark assembling 10 fragments with relevance strategy.""" self._pipeline.assemble( plan_id="01JQBENCHM00000000000000AA", fragments=self._frags_10, budget=self._budget, ) def time_assemble_100_fragments(self) -> None: """Benchmark assembling 100 fragments with relevance strategy.""" self._pipeline.assemble( plan_id="01JQBENCHM00000000000000AA", fragments=self._frags_100, budget=self._budget, ) def time_assemble_1000_fragments(self) -> None: """Benchmark assembling 1000 fragments with relevance strategy.""" self._pipeline.assemble( plan_id="01JQBENCHM00000000000000AA", fragments=self._frags_1000, budget=self._budget, ) def time_tiered_strategy(self) -> None: """Benchmark assembling with tiered strategy.""" self._pipeline.assemble( plan_id="01JQBENCHM00000000000000AA", fragments=self._tiered_frags, budget=self._budget, strategy="tiered", ) def time_recency_strategy(self) -> None: """Benchmark assembling with recency strategy.""" self._pipeline.assemble( plan_id="01JQBENCHM00000000000000AA", fragments=self._recency_frags, budget=self._budget, strategy="recency", ) class ContextHashSuite: """Benchmark compute_context_hash in isolation. Measures the length-prefixed SHA-256 hash function at various fragment counts to detect performance regressions. """ def setup(self) -> None: """Build fragment tuples of varying sizes.""" self._frags_10 = tuple( ContextFragment( uko_node=f"bench://hash/{i}", content=f"fragment content {i}" * 10, token_count=50, provenance=_DEFAULT_PROV, ) for i in range(10) ) self._frags_100 = tuple( ContextFragment( uko_node=f"bench://hash/{i}", content=f"fragment content {i}" * 10, token_count=50, provenance=_DEFAULT_PROV, ) for i in range(100) ) self._frags_1000 = tuple( ContextFragment( uko_node=f"bench://hash/{i}", content=f"fragment content {i}" * 10, token_count=50, provenance=_DEFAULT_PROV, ) for i in range(1000) ) def time_hash_10_fragments(self) -> None: """Benchmark hashing 10 fragments.""" compute_context_hash(self._frags_10) def time_hash_100_fragments(self) -> None: """Benchmark hashing 100 fragments.""" compute_context_hash(self._frags_100) def time_hash_1000_fragments(self) -> None: """Benchmark hashing 1000 fragments.""" compute_context_hash(self._frags_1000)