b88bc0ec1b
CI / build (push) Successful in 19s
CI / lint (push) Successful in 3m19s
CI / quality (push) Successful in 3m43s
CI / typecheck (push) Successful in 3m55s
CI / security (push) Successful in 4m2s
CI / unit_tests (push) Successful in 6m39s
CI / integration_tests (push) Successful in 6m48s
CI / docker (push) Successful in 1m7s
CI / e2e_tests (push) Successful in 9m7s
CI / benchmark-regression (push) Has been skipped
CI / coverage (push) Failing after 16m36s
CI / benchmark-publish (push) Successful in 25m51s
CI / status-check (push) Failing after 4s
## Summary Add large project scaling benchmarks and tests at production scale (10K–100K files). ### New ASV Benchmarks **IndexingScalingSuite** (`large_project_scaling_bench.py`): - `time_walk_and_index` at 1K/10K/50K/100K files - `time_incremental_refresh` (1% modified files) - `track_indexed_file_count`, `track_tokens_per_second` **ContextAssemblyScalingSuite** (`context_assembly_scaling_bench.py`): - `time_full_pipeline` at 100/1K/5K/10K fragments - `time_tiered_strategy`, `time_recency_strategy` - `track_assembled_tokens`, `track_fragments_per_second` **ExecutionThroughputSuite** (`execution_throughput_bench.py`): - `time_sequential_plans` at 10/50/100 plans - `time_executor_construction`, `time_decision_tree_scaling` ### Scale Fixture Updates - Added `xlarge` (50K files) and `xxlarge` (100K files) profiles to `scale_metadata.json` - Added 50K/100K thresholds to `baseline_thresholds.json` - Added `context_assembly` and `execution_throughput` threshold sections ### Tests & Documentation - 15 Behave scenarios validating profiles, thresholds, monotonicity, memory budgets - 6 Robot integration tests including live 1K-file indexing throughput check - `docs/reference/scaling_baselines.md` documenting all baseline metrics ### Quality Gates | Session | Result | |---|---| | `nox -s lint` | PASS | | `nox -s typecheck` | PASS (0 errors) | | `nox -s unit_tests` | PASS (10,910 scenarios) | | `nox -s integration_tests` | PASS (1,526 tests) | | `nox -s coverage_report` | 97% (>= 97%) | Closes #859 Reviewed-on: #984 Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com> Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
139 lines
4.6 KiB
Python
139 lines
4.6 KiB
Python
"""ASV benchmarks for ACMS context assembly at production scale.
|
|
|
|
Extends the existing 1K-fragment ceiling from :mod:`acms_pipeline_bench`
|
|
to 5K and 10K fragments, exercising the full 10-stage pipeline,
|
|
deduplication + scoring, and knapsack budget packing.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
from typing import ClassVar
|
|
|
|
# Ensure the local *source* tree is importable even when ASV has an
|
|
# older build of the package installed.
|
|
_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,
|
|
)
|
|
|
|
# Default provenance for benchmark fragments.
|
|
_DEFAULT_PROV = FragmentProvenance(resource_uri="bench://scale")
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Helpers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def _make_fragments(count: int) -> list[ContextFragment]:
|
|
"""Build *count* benchmark fragments with varied scores and tiers."""
|
|
tiers = ("hot", "warm", "cold")
|
|
return [
|
|
ContextFragment(
|
|
uko_node=f"bench://scale/{i}",
|
|
content=f"fragment content block {i} " * 5,
|
|
relevance_score=round((i % 10) / 10, 1),
|
|
token_count=50,
|
|
tier=tiers[i % 3],
|
|
provenance=_DEFAULT_PROV,
|
|
)
|
|
for i in range(count)
|
|
]
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Parameterized context assembly suite
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class ContextAssemblyScalingSuite:
|
|
"""Benchmark ACMS context assembly at production fragment counts."""
|
|
|
|
params: ClassVar[list[int]] = [100, 1_000, 5_000, 10_000]
|
|
param_names: ClassVar[list[str]] = ["fragment_count"]
|
|
timeout = 300 # 5 min for 10K fragments
|
|
|
|
_pipeline: ACMSPipeline
|
|
_budget: ContextBudget
|
|
_fragments: list[ContextFragment]
|
|
|
|
def setup(self, fragment_count: int) -> None:
|
|
"""Create *fragment_count* ContextFragment objects."""
|
|
self._pipeline = ACMSPipeline()
|
|
self._budget = ContextBudget(max_tokens=500_000, reserved_tokens=0)
|
|
self._fragments = _make_fragments(fragment_count)
|
|
|
|
# -- timing methods -----------------------------------------------------
|
|
|
|
def time_full_pipeline(self, fragment_count: int) -> None:
|
|
"""Time the full ACMS pipeline with *fragment_count* fragments."""
|
|
self._pipeline.assemble(
|
|
plan_id="01JQBENCHM00000000000000AA",
|
|
fragments=self._fragments,
|
|
budget=self._budget,
|
|
)
|
|
|
|
def time_tiered_strategy(self, fragment_count: int) -> None:
|
|
"""Time tiered strategy assembly."""
|
|
self._pipeline.assemble(
|
|
plan_id="01JQBENCHM00000000000000AA",
|
|
fragments=self._fragments,
|
|
budget=self._budget,
|
|
strategy="tiered",
|
|
)
|
|
|
|
def time_recency_strategy(self, fragment_count: int) -> None:
|
|
"""Time recency strategy assembly."""
|
|
self._pipeline.assemble(
|
|
plan_id="01JQBENCHM00000000000000AA",
|
|
fragments=self._fragments,
|
|
budget=self._budget,
|
|
strategy="recency",
|
|
)
|
|
|
|
# -- tracking methods ---------------------------------------------------
|
|
|
|
def track_assembled_tokens(self, fragment_count: int) -> int:
|
|
"""Track total tokens in assembled context."""
|
|
result = self._pipeline.assemble(
|
|
plan_id="01JQBENCHM00000000000000AA",
|
|
fragments=self._fragments,
|
|
budget=self._budget,
|
|
)
|
|
return result.total_tokens
|
|
|
|
def track_fragments_per_second(self, fragment_count: int) -> float:
|
|
"""Track assembly throughput in fragments / second."""
|
|
t0 = time.perf_counter()
|
|
self._pipeline.assemble(
|
|
plan_id="01JQBENCHM00000000000000AA",
|
|
fragments=self._fragments,
|
|
budget=self._budget,
|
|
)
|
|
elapsed = time.perf_counter() - t0
|
|
if elapsed <= 0:
|
|
return float(fragment_count)
|
|
return fragment_count / elapsed
|
|
|
|
|
|
# Attach ASV unit metadata without ``# type: ignore``.
|
|
setattr( # noqa: B010
|
|
ContextAssemblyScalingSuite.track_assembled_tokens, "unit", "tokens"
|
|
)
|
|
setattr( # noqa: B010
|
|
ContextAssemblyScalingSuite.track_fragments_per_second, "unit", "frags/s"
|
|
)
|