"""ASV benchmarks for DecisionService DI resolution and operations. Measures: - Container resolution of DecisionService - Decision recording through the service layer - Decision tree retrieval through the service layer """ from __future__ import annotations import sys from datetime import UTC, datetime from pathlib import Path from unittest.mock import create_autospec try: from cleveragents.application.services.decision_service import DecisionService from cleveragents.config.settings import Settings from cleveragents.domain.models.core.action import Action, ActionState from cleveragents.domain.models.core.decision import DecisionType from cleveragents.domain.models.core.plan import ( NamespacedName, Plan, PlanIdentity, PlanPhase, PlanTimestamps, ProcessingState, ) from cleveragents.infrastructure.database.unit_of_work import UnitOfWork except ModuleNotFoundError: sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from cleveragents.application.services.decision_service import DecisionService from cleveragents.config.settings import Settings from cleveragents.domain.models.core.action import Action, ActionState from cleveragents.domain.models.core.decision import DecisionType from cleveragents.domain.models.core.plan import ( NamespacedName, Plan, PlanIdentity, PlanPhase, PlanTimestamps, ProcessingState, ) from cleveragents.infrastructure.database.unit_of_work import UnitOfWork _PLAN_ID = "01HV00000000000000DJBENCH1" def _make_uow() -> UnitOfWork: """Create a UoW backed by an in-memory SQLite database.""" uow = UnitOfWork("sqlite:///:memory:") uow.init_database() return uow def _seed_prerequisites(uow: UnitOfWork) -> None: """Create the action + plan needed to satisfy FK constraints.""" with uow.transaction() as ctx: action_repo = ctx.actions action = Action( namespaced_name=NamespacedName.parse("local/bench-di-action"), description="Benchmark action", definition_of_done="Done", strategy_actor="local/s", execution_actor="local/e", state=ActionState.AVAILABLE, created_at=datetime(2026, 1, 1, tzinfo=UTC), updated_at=datetime(2026, 1, 1, tzinfo=UTC), ) action_repo.create(action) with uow.transaction() as ctx: plan_repo = ctx.lifecycle_plans now = datetime(2026, 3, 1, tzinfo=UTC) plan = Plan( identity=PlanIdentity(plan_id=_PLAN_ID, attempt=1), namespaced_name=NamespacedName(namespace="local", name="bench-di-plan"), action_name="local/bench-di-action", description="Benchmark DI plan", definition_of_done="Done", phase=PlanPhase.STRATEGIZE, processing_state=ProcessingState.PROCESSING, strategy_actor="local/s", execution_actor="local/e", timestamps=PlanTimestamps(created_at=now, updated_at=now), created_by="bench", tags=[], reusable=True, read_only=False, ) plan_repo.create(plan) class TimeDecisionServiceResolution: """Benchmark DecisionService resolution from the DI container.""" timeout = 60 def setup(self) -> None: import os os.environ["CLEVERAGENTS_DATABASE_URL"] = "sqlite:///:memory:" from cleveragents.application.container import get_container, reset_container reset_container() self.container = get_container() def time_decision_service_resolution(self) -> None: self.container.decision_service() def teardown(self) -> None: import os from cleveragents.application.container import reset_container reset_container() os.environ.pop("CLEVERAGENTS_DATABASE_URL", None) class TimeDecisionRecord: """Benchmark decision recording through DecisionService.""" timeout = 60 def setup(self) -> None: self.uow = _make_uow() _seed_prerequisites(self.uow) mock_settings = create_autospec(Settings, instance=True) mock_settings.database_url = "sqlite:///:memory:" self.svc = DecisionService(settings=mock_settings, unit_of_work=self.uow) self._seq = 100 def time_decision_record(self) -> None: self._seq += 1 self.svc.record_decision( plan_id=_PLAN_ID, decision_type=DecisionType.STRATEGY_CHOICE, question="Benchmark question?", chosen_option="Benchmark option", ) class TimeDecisionTreeRetrieval: """Benchmark decision tree retrieval through DecisionService.""" timeout = 60 def setup(self) -> None: self.uow = _make_uow() _seed_prerequisites(self.uow) mock_settings = create_autospec(Settings, instance=True) mock_settings.database_url = "sqlite:///:memory:" self.svc = DecisionService(settings=mock_settings, unit_of_work=self.uow) # Build a small tree root = self.svc.record_decision( plan_id=_PLAN_ID, decision_type=DecisionType.PROMPT_DEFINITION, question="Benchmark question?", chosen_option="Benchmark option", ) for _ in range(3): child = self.svc.record_decision( plan_id=_PLAN_ID, decision_type=DecisionType.STRATEGY_CHOICE, question="Benchmark question?", chosen_option="Benchmark option", parent_decision_id=root.decision_id, ) for _ in range(2): self.svc.record_decision( plan_id=_PLAN_ID, decision_type=DecisionType.IMPLEMENTATION_CHOICE, question="Benchmark question?", chosen_option="Benchmark option", parent_decision_id=child.decision_id, ) def time_decision_tree_retrieval(self) -> None: self.svc.get_tree(_PLAN_ID)