"""ASV benchmarks for hierarchical actor YAML parsing performance. Measures the performance of: - Parsing actors with per-node LSP bindings - Parsing actors with tool-source references - Parsing actors with subgraph actor_ref - Parsing actors with full hierarchical features combined """ from __future__ import annotations import importlib import sys 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.actor.schema import ActorConfigSchema # noqa: E402 def _graph_data(nodes: list[dict], *, skills: list[str] | None = None) -> dict: node_ids = [n["id"] for n in nodes] edges = [] for i in range(len(node_ids) - 1): edges.append({"from_node": node_ids[i], "to_node": node_ids[i + 1]}) data: dict = { "name": "bench/hierarchy", "type": "graph", "description": "Benchmark hierarchical actor", "model": "gpt-4", "route": { "nodes": nodes, "edges": edges, "entry_node": node_ids[0], "exit_nodes": [node_ids[-1]], }, } if skills: data["skills"] = skills return data _AGENT_NODE = { "id": "agent", "type": "agent", "name": "Agent", "description": "Agent node", "config": {"model": "gpt-4"}, } _LSP_NODE = { "id": "lsp_agent", "type": "agent", "name": "LSP Agent", "description": "Agent with LSP binding", "config": {"model": "gpt-4"}, "lsp_binding": { "server": "local/pyright", "languages": ["python"], "capabilities": ["diagnostics", "hover"], }, } _TS_NODE = { "id": "ts_agent", "type": "agent", "name": "Tool Source Agent", "description": "Agent with tool sources", "config": {}, "tool_sources": [ {"type": "skill", "name": "local/file-ops"}, {"type": "mcp", "name": "local/filesystem"}, {"type": "builtin", "group": "git_operations"}, ], } _SUBGRAPH_NODE = { "id": "sub", "type": "subgraph", "name": "Sub", "description": "Subgraph node", "actor_ref": "local/code-reviewer", } class TimeLspBindingParse: """Benchmark parsing actors with LSP bindings.""" def setup(self) -> None: self.data = _graph_data([_LSP_NODE]) def time_parse_lsp_binding(self) -> None: ActorConfigSchema.model_validate(self.data) class TimeToolSourcesParse: """Benchmark parsing actors with tool-source references.""" def setup(self) -> None: self.data = _graph_data([_TS_NODE]) def time_parse_tool_sources(self) -> None: ActorConfigSchema.model_validate(self.data) class TimeSubgraphRefParse: """Benchmark parsing actors with subgraph actor_ref.""" def setup(self) -> None: self.data = _graph_data( [_AGENT_NODE, _SUBGRAPH_NODE], ) def time_parse_subgraph_ref(self) -> None: ActorConfigSchema.model_validate(self.data) class TimeFullHierarchyParse: """Benchmark parsing a full hierarchical actor with all features.""" def setup(self) -> None: self.data = _graph_data( [_LSP_NODE, _TS_NODE, _SUBGRAPH_NODE], skills=["local/file-ops", "local/git-ops"], ) self.data["lsp"] = ["local/pyright"] self.data["lsp_capabilities"] = ["diagnostics"] def time_parse_full_hierarchy(self) -> None: ActorConfigSchema.model_validate(self.data) time_lsp = TimeLspBindingParse() time_ts = TimeToolSourcesParse() time_sg = TimeSubgraphRefParse() time_full = TimeFullHierarchyParse()