c47e6445d0
CI / quality (pull_request) Successful in 19s
CI / lint (pull_request) Successful in 22s
CI / benchmark-publish (pull_request) Has been skipped
CI / security (pull_request) Successful in 33s
CI / build (pull_request) Successful in 26s
CI / typecheck (pull_request) Successful in 1m0s
CI / integration_tests (pull_request) Successful in 4m56s
CI / unit_tests (pull_request) Successful in 15m11s
CI / docker (pull_request) Successful in 1m33s
CI / benchmark-regression (pull_request) Successful in 20m55s
CI / coverage (pull_request) Successful in 33m42s
CI / lint (push) Successful in 13s
CI / build (push) Successful in 15s
CI / quality (push) Successful in 17s
CI / security (push) Successful in 28s
CI / typecheck (push) Successful in 32s
CI / benchmark-regression (push) Has been skipped
CI / integration_tests (push) Successful in 3m3s
CI / benchmark-publish (push) Successful in 10m8s
CI / unit_tests (push) Successful in 12m42s
CI / docker (push) Successful in 39s
CI / coverage (push) Has been cancelled
Add ActorCompiler module that translates GRAPH-type ActorConfigSchema definitions into LangGraph NodeConfig/Edge structures with LSP binding metadata. Includes subgraph resolution with cross-actor cycle detection, entry/exit validation, and CompilationMetadata for diagnostics. New files: - src/cleveragents/actor/compiler.py: Core compiler with compile_actor() - features/actor_compiler.feature: 13 Behave scenarios - features/steps/actor_compiler_steps.py: Step definitions - robot/actor_compiler.robot: 4 Robot smoke tests - benchmarks/actor_compiler_bench.py: ASV performance benchmarks - docs/reference/actor_compiler.md: Compilation pipeline reference Modified: - src/cleveragents/actor/__init__.py: Export compiler types - vulture_whitelist.py: Whitelist new public API ISSUES CLOSED: #158
168 lines
4.4 KiB
Python
168 lines
4.4 KiB
Python
"""ASV benchmarks for actor compiler throughput.
|
|
|
|
Measures the performance of:
|
|
- compile_actor() on a simple two-node graph
|
|
- compile_actor() on a larger multi-node graph
|
|
- Subgraph cycle detection overhead
|
|
- Compilation metadata serialization
|
|
"""
|
|
|
|
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.compiler import compile_actor # noqa: E402
|
|
from cleveragents.actor.schema import ( # noqa: E402
|
|
ActorConfigSchema,
|
|
ActorType,
|
|
EdgeDefinition,
|
|
NodeDefinition,
|
|
NodeType,
|
|
RouteDefinition,
|
|
)
|
|
|
|
|
|
def _make_graph(node_count: int) -> ActorConfigSchema:
|
|
"""Build a linear graph with *node_count* agent nodes."""
|
|
nodes: list[NodeDefinition] = []
|
|
edges: list[EdgeDefinition] = []
|
|
for i in range(node_count):
|
|
nodes.append(
|
|
NodeDefinition(
|
|
id=f"node-{i}",
|
|
type=NodeType.AGENT,
|
|
name=f"Node {i}",
|
|
description=f"Agent node {i}",
|
|
config={"agent": f"agent_{i}"},
|
|
)
|
|
)
|
|
if i > 0:
|
|
edges.append(EdgeDefinition(from_node=f"node-{i - 1}", to_node=f"node-{i}"))
|
|
route = RouteDefinition(
|
|
nodes=nodes,
|
|
edges=edges,
|
|
entry_node="node-0",
|
|
exit_nodes=[f"node-{node_count - 1}"],
|
|
)
|
|
return ActorConfigSchema(
|
|
name="bench/graph",
|
|
type=ActorType.GRAPH,
|
|
description="Benchmark graph",
|
|
model="gpt-4",
|
|
route=route,
|
|
)
|
|
|
|
|
|
class CompileSimpleSuite:
|
|
"""Benchmark compile_actor on a simple 2-node graph."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self) -> None:
|
|
self.config = _make_graph(2)
|
|
|
|
def time_compile_simple(self) -> None:
|
|
compile_actor(self.config)
|
|
|
|
|
|
class CompileLargeSuite:
|
|
"""Benchmark compile_actor on a 20-node linear graph."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self) -> None:
|
|
self.config = _make_graph(20)
|
|
|
|
def time_compile_large(self) -> None:
|
|
compile_actor(self.config)
|
|
|
|
|
|
class MetadataSerializationSuite:
|
|
"""Benchmark compilation metadata serialization."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self) -> None:
|
|
self.config = _make_graph(10)
|
|
self.compiled = compile_actor(self.config)
|
|
|
|
def time_metadata_dump(self) -> None:
|
|
self.compiled.metadata.model_dump(mode="json")
|
|
|
|
|
|
class SubgraphResolutionSuite:
|
|
"""Benchmark compile_actor with subgraph resolution."""
|
|
|
|
timeout = 60
|
|
|
|
def setup(self) -> None:
|
|
inner_nodes = [
|
|
NodeDefinition(
|
|
id="inner",
|
|
type=NodeType.AGENT,
|
|
name="Inner",
|
|
description="Inner agent",
|
|
config={"agent": "inner"},
|
|
),
|
|
]
|
|
inner_route = RouteDefinition(
|
|
nodes=inner_nodes,
|
|
edges=[],
|
|
entry_node="inner",
|
|
exit_nodes=["inner"],
|
|
)
|
|
self.inner_config = ActorConfigSchema(
|
|
name="bench/inner",
|
|
type=ActorType.GRAPH,
|
|
description="Inner graph",
|
|
model="gpt-4",
|
|
route=inner_route,
|
|
)
|
|
|
|
outer_nodes = [
|
|
NodeDefinition(
|
|
id="main",
|
|
type=NodeType.AGENT,
|
|
name="Main",
|
|
description="Main agent",
|
|
config={"agent": "main"},
|
|
),
|
|
NodeDefinition(
|
|
id="sub",
|
|
type=NodeType.SUBGRAPH,
|
|
name="Sub",
|
|
description="Subgraph ref",
|
|
config={"actor_ref": "bench/inner"},
|
|
),
|
|
]
|
|
outer_edges = [EdgeDefinition(from_node="main", to_node="sub")]
|
|
outer_route = RouteDefinition(
|
|
nodes=outer_nodes,
|
|
edges=outer_edges,
|
|
entry_node="main",
|
|
exit_nodes=["sub"],
|
|
)
|
|
self.outer_config = ActorConfigSchema(
|
|
name="bench/outer",
|
|
type=ActorType.GRAPH,
|
|
description="Outer graph",
|
|
model="gpt-4",
|
|
route=outer_route,
|
|
)
|
|
self.resolver = lambda name: (
|
|
self.inner_config if name == "bench/inner" else None
|
|
)
|
|
|
|
def time_compile_with_subgraph(self) -> None:
|
|
compile_actor(self.outer_config, actor_resolver=self.resolver)
|