"""Airspeed Velocity benchmarks for v3 Plan domain model. Measures validation, serialization, and as_cli_dict performance for the Plan model across different field configurations. """ from __future__ import annotations from cleveragents.domain.models.core.plan import ( AutomationProfileProvenance, AutomationProfileRef, InvariantSource, NamespacedName, Plan, PlanIdentity, PlanInvariant, PlanPhase, ProcessingState, ProjectLink, SubplanConfig, SubplanStatus, can_transition, ) # Valid ULID constants for benchmarks _ULID_A = "01HGZ6FE0AQDYTR4BXVQZ6EA00" _ULID_B = "01HGZ6FE0AQDYTR4BXVQZ6EB00" def _minimal_plan() -> Plan: """Create a minimal Plan with only required fields.""" return Plan( identity=PlanIdentity(plan_id=_ULID_A), namespaced_name=NamespacedName( server=None, namespace="local", name="bench-plan" ), description="Benchmark plan", action_name="local/bench-action", ) def _rich_plan() -> Plan: """Create a Plan with all optional fields populated.""" return Plan( identity=PlanIdentity( plan_id=_ULID_A, parent_plan_id=_ULID_B, root_plan_id=_ULID_B, ), namespaced_name=NamespacedName( server="prod", namespace="myorg", name="rich-plan" ), description="Fully populated benchmark plan", definition_of_done="All tests pass with >97% coverage", action_name="myorg/code-coverage", phase=PlanPhase.EXECUTE, processing_state=ProcessingState.PROCESSING, automation_profile=AutomationProfileRef( profile_name="trusted", provenance=AutomationProfileProvenance.ACTION, ), project_links=[ ProjectLink(project_name="local/api-svc", alias="api", read_only=False), ProjectLink(project_name="local/docs", read_only=True), ], invariants=[ PlanInvariant(text="No public API changes", source=InvariantSource.ACTION), PlanInvariant(text="Keep backward compat", source=InvariantSource.PROJECT), ], arguments={"target": "src/main.py", "mode": "strict", "verbose": True}, arguments_order=["target", "mode", "verbose"], strategy_actor="local/planner", execution_actor="local/coder", review_actor="local/reviewer", error_message=None, subplan_config=SubplanConfig(max_parallel=3), subplan_statuses=[ SubplanStatus(subplan_id=_ULID_B, action_name="local/sub-action"), ], ) class PlanValidationSuite: """Benchmark Plan model validation (construction).""" def time_minimal_plan_creation(self) -> None: """Time creating a minimal Plan with only required fields.""" _minimal_plan() def time_rich_plan_creation(self) -> None: """Time creating a Plan with all optional fields populated.""" _rich_plan() def time_plan_model_validate_dict(self) -> None: """Time Plan.model_validate from a raw dict.""" Plan.model_validate( { "identity": {"plan_id": _ULID_A}, "namespaced_name": {"namespace": "local", "name": "bench-plan"}, "description": "Benchmark plan", "action_name": "local/bench-action", } ) class PlanSerializationSuite: """Benchmark Plan model serialization.""" def setup(self) -> None: self.minimal = _minimal_plan() self.rich = _rich_plan() def time_minimal_model_dump(self) -> None: """Time model_dump for a minimal Plan.""" self.minimal.model_dump() def time_rich_model_dump(self) -> None: """Time model_dump for a fully populated Plan.""" self.rich.model_dump() def time_minimal_model_dump_json(self) -> None: """Time model_dump_json for a minimal Plan.""" self.minimal.model_dump_json() def time_rich_model_dump_json(self) -> None: """Time model_dump_json for a fully populated Plan.""" self.rich.model_dump_json() class PlanCliDictSuite: """Benchmark Plan.as_cli_dict output generation.""" def setup(self) -> None: self.minimal = _minimal_plan() self.rich = _rich_plan() def time_minimal_as_cli_dict(self) -> None: """Time as_cli_dict for a minimal Plan.""" self.minimal.as_cli_dict() def time_rich_as_cli_dict(self) -> None: """Time as_cli_dict for a Plan with all optional fields.""" self.rich.as_cli_dict() class PhaseTransitionSuite: """Benchmark phase transition validation.""" def time_can_transition_valid(self) -> None: """Time a valid phase transition check.""" can_transition(PlanPhase.STRATEGIZE, PlanPhase.EXECUTE) def time_can_transition_invalid(self) -> None: """Time an invalid phase transition check.""" can_transition(PlanPhase.STRATEGIZE, PlanPhase.APPLY) def time_all_transitions(self) -> None: """Time checking all possible phase transition pairs.""" for from_phase in PlanPhase: for to_phase in PlanPhase: can_transition(from_phase, to_phase) class NamespacedNameSuite: """Benchmark NamespacedName parsing and serialization.""" def time_parse_simple(self) -> None: """Time parsing a simple name.""" NamespacedName.parse("my-action") def time_parse_full(self) -> None: """Time parsing a full server:namespace/name string.""" NamespacedName.parse("prod:myorg/my-action") def time_str_representation(self) -> None: """Time string representation of a NamespacedName.""" name = NamespacedName(server="prod", namespace="myorg", name="my-action") str(name)