forked from HAL9000/cleveragents-core
c47e6445d0
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
169 lines
8.9 KiB
Gherkin
169 lines
8.9 KiB
Gherkin
@phase1 @domain @skill_flatten
|
|
Feature: Skill Registry Flattening and Capability Summaries
|
|
As a developer using skill composition
|
|
I want skills to be flattened with deterministic ordering and capability summaries
|
|
So that actors receive a predictable, well-documented tool set
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Flattening with named tool refs (deterministic ordering)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_tool_refs
|
|
Scenario: Flattening a skill with named tool refs produces deterministic order
|
|
Given a flatten registry skill "local/basic" with tool refs "local/alpha,local/beta,local/gamma"
|
|
When I flatten the skill "local/basic"
|
|
Then the flatten result should have 3 entries
|
|
And the flatten entry at index 0 should be "local/alpha"
|
|
And the flatten entry at index 1 should be "local/beta"
|
|
And the flatten entry at index 2 should be "local/gamma"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Flattening with includes (depth-first ordering)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_includes
|
|
Scenario: Flattening a skill with includes uses depth-first ordering
|
|
Given a flatten registry skill "local/base" with tool refs "local/base-tool"
|
|
And a flatten registry skill "local/mid" including "local/base" with refs "local/mid-tool"
|
|
And a flatten registry skill "local/top" including "local/mid" with refs "local/top-tool"
|
|
When I flatten the skill "local/top"
|
|
Then the flatten result should have 3 entries
|
|
And the flatten entry at index 0 should be "local/base-tool"
|
|
And the flatten entry at index 1 should be "local/mid-tool"
|
|
And the flatten entry at index 2 should be "local/top-tool"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Flattening with inline tools
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_inline
|
|
Scenario: Flattening a skill with inline tools includes anonymous entries
|
|
Given a flatten registry skill "local/inline-skill" with 2 inline tools
|
|
When I flatten the skill "local/inline-skill"
|
|
Then the flatten result should have 2 entries
|
|
And the flatten entry at index 0 should be "local/inline-skill/_anon_0"
|
|
And the flatten entry at index 1 should be "local/inline-skill/_anon_1"
|
|
And the flatten entry at index 0 should be marked inline
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Cycle detection with clear error path
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_cycle
|
|
Scenario: Flattening detects cycles and reports a clear path
|
|
Given a flatten registry skill "local/cycle-a" including "local/cycle-b" with no refs
|
|
And a flatten registry skill "local/cycle-b" including "local/cycle-a" with no refs
|
|
When I try to flatten the skill "local/cycle-a"
|
|
Then a flatten cycle error should be raised
|
|
And the flatten error should mention "local/cycle-a"
|
|
And the flatten error should mention "local/cycle-b"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Per-include override application
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_include_overrides
|
|
Scenario: Per-include overrides are applied to included tool entries
|
|
Given a flatten registry skill "local/child" with tool refs "local/tool-x"
|
|
And a flatten registry skill "local/parent" including "local/child" with overrides timeout 600
|
|
When I flatten the skill "local/parent"
|
|
Then the flatten result should have 1 entries
|
|
And the flatten entry "local/tool-x" should have override "timeout" equal to 600
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Non-overridable field rejection
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_non_overridable
|
|
Scenario: Non-overridable fields are rejected with clear error
|
|
Given a flatten registry skill "local/child-nr" with tool refs "local/tool-y"
|
|
And a flatten registry skill "local/parent-nr" including "local/child-nr" with overrides on non-overridable field "name"
|
|
When I try to flatten the skill "local/parent-nr"
|
|
Then a flatten override error should be raised
|
|
And the flatten error should mention "name"
|
|
And the flatten error should mention "Non-overridable"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Capability summary computation
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_capability_summary
|
|
Scenario: Capability summary aggregates read/write/checkpoint/side-effect flags
|
|
Given a flatten registry skill "local/cap-skill" with mixed capability inline tools
|
|
When I flatten the skill "local/cap-skill" and compute summary
|
|
Then the flatten summary total_tools should be 3
|
|
And the flatten summary read_only_tools should be 1
|
|
And the flatten summary write_tools should be 1
|
|
And the flatten summary has_side_effects should be true
|
|
And the flatten summary checkpointable_tools should be 1
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# tools() method returns both entries and summary
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_tools_method
|
|
Scenario: The tools() method returns entries and capability summary
|
|
Given a flatten skill registry with skill "local/tools-test" having 3 refs
|
|
When I call the flatten tools method for "local/tools-test"
|
|
Then the flatten tools result should contain 3 entries
|
|
And the flatten tools result should include a capability summary
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# validate_plan() with valid plan
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_validate_plan
|
|
Scenario: validate_plan with a valid plan returns no errors
|
|
Given a flatten skill registry with skill "local/plan-skill" having 2 refs
|
|
When I call flatten validate_plan with skills "local/plan-skill"
|
|
Then the flatten validation result should have 0 errors
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# validate_plan() with missing skill
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_validate_plan_missing
|
|
Scenario: validate_plan with a missing skill reports error
|
|
Given an empty flatten skill registry
|
|
When I call flatten validate_plan with skills "local/nonexistent"
|
|
Then the flatten validation result should have 1 errors
|
|
And the flatten validation error should mention "local/nonexistent"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# validate_plan() with cycle in includes
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_validate_plan_cycle
|
|
Scenario: validate_plan detects cycle in includes
|
|
Given a flatten registry skill "local/loop-a" including "local/loop-b" with no refs
|
|
And a flatten registry skill "local/loop-b" including "local/loop-a" with no refs
|
|
And the flatten registry skills are registered in the skill registry
|
|
When I call flatten validate_plan with skills "local/loop-a"
|
|
Then the flatten validation result should have 1 errors
|
|
And the flatten validation error should mention "ycle"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# De-duplication semantics (last-wins)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_dedup
|
|
Scenario: De-duplication uses last-wins for entry metadata
|
|
Given a flatten registry skill "local/dup-a" with tool refs "local/shared"
|
|
And a flatten registry skill "local/dup-b" with tool refs "local/shared"
|
|
And a flatten registry skill "local/dup-top" including "local/dup-a,local/dup-b" with no refs
|
|
When I flatten the skill "local/dup-top"
|
|
Then the flatten result should have 1 entries
|
|
And the flatten entry "local/shared" source_skill should be "local/dup-b"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Override merging (shallow merge)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@flatten_override_merge
|
|
Scenario: Override merging uses shallow merge semantics
|
|
Given a flatten registry skill "local/merge-child" with tool refs "local/merge-tool" and overrides priority 1
|
|
And a flatten registry skill "local/merge-parent" including "local/merge-child" with overrides priority 2 and extra key
|
|
When I flatten the skill "local/merge-parent"
|
|
Then the flatten entry "local/merge-tool" should have override "priority" equal to 2
|
|
And the flatten entry "local/merge-tool" should have override "extra" equal to "yes"
|