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
193 lines
12 KiB
Gherkin
193 lines
12 KiB
Gherkin
Feature: Actor compiler full coverage for node mapping, edge mapping, LSP bindings, and error paths
|
|
As a CleverAgents developer
|
|
I want every code path in the actor compiler module to be tested
|
|
So that the compiler is reliable and regressions are caught early
|
|
|
|
# ────────────────────────────────────────────────────────────
|
|
# Node type mapping (_map_node and _NODE_TYPE_MAP)
|
|
# ────────────────────────────────────────────────────────────
|
|
|
|
Scenario: Compile a graph with all four node types mapped correctly
|
|
Given a GRAPH actor config containing AGENT, TOOL, CONDITIONAL, and SUBGRAPH nodes
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compiled node "agent_node" should have LangGraph type "agent"
|
|
And the compiled node "tool_node" should have LangGraph type "tool"
|
|
And the compiled node "cond_node" should have LangGraph type "conditional"
|
|
And the compiled node "sub_node" should have LangGraph type "subgraph"
|
|
|
|
Scenario: Agent node config maps agent field to NodeConfig
|
|
Given a GRAPH actor config with an agent node configured as "my_agent"
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compiled node "agent_node" should have agent set to "my_agent"
|
|
|
|
Scenario: Conditional node config maps function field to NodeConfig
|
|
Given a GRAPH actor config with a conditional node configured with function "route_fn"
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compiled node "cond_node" should have function set to "route_fn"
|
|
|
|
Scenario: Tool node config maps tools list to NodeConfig
|
|
Given a GRAPH actor config with a tool node configured with tools "lint,format"
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compiled node "tool_node" should have tools "lint" and "format"
|
|
|
|
Scenario: Subgraph node config maps actor_ref to NodeConfig subgraph field
|
|
Given a GRAPH actor config with a subgraph node referencing actor "workflows/child"
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compiled node "sub_node" should have subgraph set to "workflows/child"
|
|
|
|
# ────────────────────────────────────────────────────────────
|
|
# Edge mapping (_map_edge)
|
|
# ────────────────────────────────────────────────────────────
|
|
|
|
Scenario: Edge without condition compiles to null condition field
|
|
Given a GRAPH actor config with an unconditional edge from "a" to "b"
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compiled edge from "a" to "b" should have a null condition
|
|
|
|
Scenario: Edge with condition compiles to expression dict
|
|
Given a GRAPH actor config with a conditional edge from "a" to "b" with condition "state.get('done')"
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compiled edge from "a" to "b" should have condition expression "state.get('done')"
|
|
|
|
Scenario: Edge priority is recorded in compiled edge metadata
|
|
Given a GRAPH actor config with an edge from "a" to "b" with priority 5
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compiled edge from "a" to "b" should have metadata priority 5
|
|
|
|
# ────────────────────────────────────────────────────────────
|
|
# LSP binding extraction edge cases (_extract_lsp_bindings)
|
|
# ────────────────────────────────────────────────────────────
|
|
|
|
Scenario: Non-list LSP bindings config value is safely ignored
|
|
Given a GRAPH actor config where lsp_bindings is a string instead of a list
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compilation metadata should have 0 LSP bindings
|
|
|
|
Scenario: Non-dict entry in LSP bindings list is skipped
|
|
Given a GRAPH actor config where lsp_bindings contains a non-dict entry
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compilation metadata should have 0 LSP bindings
|
|
|
|
Scenario: LSP binding with empty server name is skipped
|
|
Given a GRAPH actor config where an LSP binding has an empty server name
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compilation metadata should have 0 LSP bindings
|
|
|
|
Scenario: LSP binding with non-string server name is skipped
|
|
Given a GRAPH actor config where an LSP binding has a numeric server name
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compilation metadata should have 0 LSP bindings
|
|
|
|
Scenario: LSP binding with missing server name key is skipped
|
|
Given a GRAPH actor config where an LSP binding is missing the server name key
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compilation metadata should have 0 LSP bindings
|
|
|
|
Scenario: Multiple valid LSP bindings are extracted from a single node
|
|
Given a GRAPH actor config with two valid LSP bindings on one node
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compilation metadata should have 2 LSP bindings
|
|
And the LSP binding servers should include "local/pyright" and "local/ts"
|
|
|
|
# ────────────────────────────────────────────────────────────
|
|
# Subgraph cycle detection edge cases (_detect_subgraph_cycles)
|
|
# ────────────────────────────────────────────────────────────
|
|
|
|
Scenario: Subgraph node with empty actor_ref is skipped during cycle detection
|
|
Given a GRAPH actor config with a subgraph node that has an empty actor_ref
|
|
When I compile the full-coverage actor config with a resolver
|
|
Then the compilation should succeed without errors
|
|
|
|
Scenario: Resolver returning None for a referenced actor skips that node
|
|
Given a GRAPH actor config with a subgraph referencing actor name "workflows/missing"
|
|
And a cycle-detection resolver that returns None for all names
|
|
When I compile the full-coverage actor config with a resolver
|
|
Then the compilation should succeed without errors
|
|
|
|
Scenario: Referenced actor that is not GRAPH type is skipped during cycle detection
|
|
Given a GRAPH actor config with a subgraph referencing actor name "tools/helper"
|
|
And a cycle-detection resolver where "tools/helper" is an LLM type actor
|
|
When I compile the full-coverage actor config with a resolver
|
|
Then the compilation should succeed without errors
|
|
|
|
Scenario: Referenced actor with no route definition is skipped during cycle detection
|
|
Given a GRAPH actor config with a subgraph referencing actor name "workflows/no-route"
|
|
And a cycle-detection resolver where "workflows/no-route" is a GRAPH actor with no route
|
|
When I compile the full-coverage actor config with a resolver
|
|
Then the compilation should succeed without errors
|
|
|
|
Scenario: Deep three-level subgraph cycle is detected
|
|
Given a GRAPH actor config named "workflows/alpha" with subgraph ref to "workflows/beta"
|
|
And a cycle-detection resolver where "workflows/beta" references "workflows/gamma" and "workflows/gamma" references "workflows/alpha"
|
|
When I compile the full-coverage actor config with a resolver
|
|
Then the compilation should fail with a SubgraphCycleError
|
|
And the compilation error message should mention "cycle"
|
|
|
|
# ────────────────────────────────────────────────────────────
|
|
# compile_actor error paths
|
|
# ────────────────────────────────────────────────────────────
|
|
|
|
Scenario: Intra-graph cycle raises SubgraphCycleError during compilation
|
|
Given a GRAPH actor config with a cyclic route that bypasses schema validation
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should fail with a SubgraphCycleError
|
|
And the compilation error message should mention "intra-graph"
|
|
|
|
Scenario: Edge referencing missing from_node raises MissingNodeError
|
|
Given a GRAPH actor config with an edge whose from_node does not exist in the node list
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should fail with a MissingNodeError
|
|
And the compilation error message should mention "from_node"
|
|
|
|
Scenario: Edge referencing missing to_node raises MissingNodeError
|
|
Given a GRAPH actor config with an edge whose to_node does not exist in the node list
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should fail with a MissingNodeError
|
|
And the compilation error message should mention "to_node"
|
|
|
|
Scenario: Invalid entry node raises InvalidEntryExitError
|
|
Given a GRAPH actor config whose entry node does not match any compiled node
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should fail with an InvalidEntryExitError
|
|
And the compilation error message should mention "Entry node"
|
|
|
|
Scenario: Invalid exit node raises InvalidEntryExitError
|
|
Given a GRAPH actor config whose exit node does not match any compiled node
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should fail with an InvalidEntryExitError
|
|
And the compilation error message should mention "Exit node"
|
|
|
|
# ────────────────────────────────────────────────────────────
|
|
# Model defaults and result bundle
|
|
# ────────────────────────────────────────────────────────────
|
|
|
|
Scenario: CompilationMetadata defaults to empty collections
|
|
Given a freshly constructed CompilationMetadata with no arguments
|
|
Then the metadata node_ids should be an empty list
|
|
And the metadata tool_nodes should be an empty list
|
|
And the metadata lsp_bindings should be an empty list
|
|
And the metadata subgraph_refs should be an empty dict
|
|
And the metadata entry_node should be an empty string
|
|
And the metadata exit_nodes should be an empty list
|
|
|
|
Scenario: CompiledActor preserves actor name and entry point from config
|
|
Given a GRAPH actor config named "workflows/test" with entry "start"
|
|
When I compile the full-coverage actor config
|
|
Then the compilation should succeed without errors
|
|
And the compiled actor name should be "workflows/test"
|
|
And the compiled actor entry_point field should be "start"
|