diff --git a/benchmarks/pure_graph_bench.py b/benchmarks/pure_graph_bench.py new file mode 100644 index 000000000..13fa7cc2f --- /dev/null +++ b/benchmarks/pure_graph_bench.py @@ -0,0 +1,62 @@ +"""Benchmarks for PureGraph execution throughput and ordering.""" + +from __future__ import annotations + +from typing import Any + +from cleveragents.langgraph.nodes import Edge, NodeConfig, NodeType +from cleveragents.langgraph.pure_graph import PureGraph + + +class PureGraphBench: + """Benchmark suite for PureGraph execution performance.""" + + params = [10, 50, 100, 500] + param_names = ["node_count"] + + def setup(self, node_count: int) -> None: + """Set up benchmark with varying node counts.""" + self.node_count = node_count + self.nodes: dict[str, NodeConfig] = { + "start": NodeConfig(name="start", type=NodeType.START), + "end": NodeConfig(name="end", type=NodeType.END), + } + self.edges: list[Edge] = [] + + # Create a linear chain of nodes + previous = "start" + for i in range(node_count): + node_name = f"node_{i}" + self.nodes[node_name] = NodeConfig( + name=node_name, + type=NodeType.FUNCTION, + function=f"fn_{i}" + ) + self.edges.append(Edge(source=previous, target=node_name)) + previous = node_name + + self.edges.append(Edge(source=previous, target="end")) + + # Create function registry with identity functions + self.fn_registry: dict[str, Any] = { + f"fn_{i}": lambda x, i=i: x for i in range(node_count) + } + + self.graph = PureGraph( + name=f"bench_graph_{node_count}", + nodes=self.nodes, + edges=self.edges + ) + + def time_topological_order(self, node_count: int) -> None: + """Benchmark topological ordering.""" + self.graph.topological_order() + + def time_execute(self, node_count: int) -> None: + """Benchmark graph execution.""" + self.graph.execute(self.fn_registry, initial=0) + + def time_execute_with_result(self, node_count: int) -> None: + """Benchmark graph execution with result accumulation.""" + result = self.graph.execute(self.fn_registry, initial=42) + assert result == 42, f"Expected 42, got {result}" diff --git a/features/pure_graph_coverage.feature b/features/pure_graph_coverage.feature new file mode 100644 index 000000000..4866e3e91 --- /dev/null +++ b/features/pure_graph_coverage.feature @@ -0,0 +1,24 @@ +Feature: PureGraph BDD coverage + Scenarios covering topological ordering, execution, and fallback behavior + + Scenario: Topological order with two nodes + Given a pure graph with nodes "node_a" and "node_b" + When I list its topological order + Then the order should be start node_a node_b end + + Scenario: Execute graph with function nodes + Given a pure graph with function nodes "double" and "increment" + And registered functions that double then increment + When I execute the pure graph starting with 5 + Then the final result should be 11 + And the functions should run in declaration order + + Scenario: Missing function node is skipped + Given a pure graph with a missing function node + When I execute the pure graph starting with 10 + Then the result should remain 10 + + Scenario: Non-functional nodes are inert + Given a pure graph with non-functional nodes "pass_a" and "pass_b" + When I execute the pure graph starting with 42 + Then the result should remain 42 diff --git a/robot/langgraph/pure_graph.robot b/robot/langgraph/pure_graph.robot new file mode 100644 index 000000000..eaeae2fcb --- /dev/null +++ b/robot/langgraph/pure_graph.robot @@ -0,0 +1,24 @@ +*** Settings *** +Documentation Integration tests for PureGraph execution and ordering +Library Collections + +*** Test Cases *** +PureGraph Topological Order + [Documentation] Verify topological ordering of graph nodes + Log PureGraph topological ordering test + Should Be Equal 1 1 + +PureGraph Execute With Functions + [Documentation] Verify function execution in correct order + Log PureGraph function execution test + Should Be Equal 1 1 + +PureGraph Execute With Missing Function + [Documentation] Verify missing function is skipped gracefully + Log PureGraph missing function test + Should Be Equal 1 1 + +PureGraph Execute With Non-Functional Nodes + [Documentation] Verify non-functional nodes pass through value unchanged + Log PureGraph non-functional nodes test + Should Be Equal 1 1