forked from HAL9000/cleveragents-core
8608584e99
Implemented optional SubplanService and SubplanExecutionService wiring in PlanExecutor.__init__() (None = no-op). - Added _spawn_subplans() helper: - Queries spawn decisions via SubplanService.get_spawn_decisions() and calls SubplanService.spawn() for each decision. - No-ops when there are no spawn decisions. - Added _execute_subplans() helper: - Delegates to SubplanExecutionService.execute_all() to run spawned subplans, handling both sequential and parallel groups as dictated by decisions. - Added _apply_subplan_results_to_plan() helper: - Updates parent plan status tracking when child subplans fail. - Annotates error_details with failed_subplan_ids when appropriate. - Integrated spawning and execution into existing flow: - Called _spawn_subplans() and _execute_subplans() from both _run_execute_with_runtime() and _run_execute_with_stub() after actor completion. - Introduced PlanExecutor properties: - subplan_service and subplan_execution_service for external wiring and testability. - Added tests and scenarios: - Behave feature file with 6 scenarios covering subplan_spawn, subplan_parallel_spawn, no-op, and failure tracking. - Robot Framework integration test suite with 6 end-to-end subplan spawning test cases. Key design decisions - Optional services (None = no-op) to maintain backward compatibility with existing deployments. - Subplan spawning is a no-op when no spawn decisions exist, avoiding unnecessary work. - Parent plan error_details is annotated with failed_subplan_ids when a child subplan fails to aid debugging and traceability. - Both runtime and stub execute paths share the same spawning logic to ensure consistent behavior across execution modes. ISSUES CLOSED: #3561
74 lines
4.0 KiB
Gherkin
74 lines
4.0 KiB
Gherkin
@mock_only @subplan @plan_executor
|
|
Feature: PlanExecutor subplan spawning integration
|
|
As a system executing hierarchical plans
|
|
I want PlanExecutor to realise subplan_spawn and subplan_parallel_spawn decisions
|
|
So that child plans are actually spawned and executed during the Execute phase
|
|
|
|
# ------------------------------------------------------------------
|
|
# subplan_spawn decision realisation
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: subplan_spawn decisions are realised as child plan executions (stub mode)
|
|
Given a PlanExecutor configured with SubplanService and SubplanExecutionService
|
|
And a parent plan in Execute phase with a subplan_spawn decision
|
|
When I call run_execute on the parent plan
|
|
Then SubplanService.get_spawn_decisions should have been called
|
|
And SubplanService.spawn should have been called with the spawn entries
|
|
And SubplanExecutionService.execute_all should have been called
|
|
And the parent plan subplan_statuses should be updated
|
|
|
|
Scenario: subplan_spawn decisions are realised in runtime mode
|
|
Given a PlanExecutor configured with SubplanService and SubplanExecutionService in runtime mode
|
|
And a parent plan in Execute phase with a subplan_spawn decision
|
|
When I call run_execute on the parent plan in runtime mode
|
|
Then SubplanService.get_spawn_decisions should have been called
|
|
And SubplanService.spawn should have been called with the spawn entries
|
|
And SubplanExecutionService.execute_all should have been called
|
|
|
|
# ------------------------------------------------------------------
|
|
# subplan_parallel_spawn concurrent execution
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: subplan_parallel_spawn decisions trigger parallel execution
|
|
Given a PlanExecutor configured with SubplanService and SubplanExecutionService
|
|
And a parent plan in Execute phase with a subplan_parallel_spawn decision
|
|
When I call run_execute on the parent plan
|
|
Then SubplanService.get_spawn_decisions should have been called
|
|
And SubplanService.spawn should have been called with the spawn entries
|
|
And SubplanExecutionService.execute_all should have been called
|
|
|
|
# ------------------------------------------------------------------
|
|
# No-op when no spawn decisions are recorded
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: No-op when no spawn decisions are recorded
|
|
Given a PlanExecutor configured with SubplanService and SubplanExecutionService
|
|
And a parent plan in Execute phase with no spawn decisions
|
|
When I call run_execute on the parent plan
|
|
Then SubplanService.get_spawn_decisions should have been called
|
|
And SubplanService.spawn should NOT have been called
|
|
And SubplanExecutionService.execute_all should NOT have been called
|
|
|
|
# ------------------------------------------------------------------
|
|
# No-op when SubplanService is not configured
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: No-op when SubplanService is not injected
|
|
Given a PlanExecutor with no SubplanService configured
|
|
And a parent plan in Execute phase with a subplan_spawn decision
|
|
When I call run_execute on the parent plan
|
|
Then the execute phase completes without error
|
|
And no subplan spawning occurs
|
|
|
|
# ------------------------------------------------------------------
|
|
# Parent plan status tracking for child subplan failures
|
|
# ------------------------------------------------------------------
|
|
|
|
Scenario: Parent plan error_details records failed subplan IDs
|
|
Given a PlanExecutor configured with SubplanService and SubplanExecutionService
|
|
And a parent plan in Execute phase with a subplan_spawn decision
|
|
And the SubplanExecutionService will report a failed subplan
|
|
When I call run_execute on the parent plan
|
|
Then the parent plan error_details should contain failed_subplan_ids
|
|
And the parent plan error_details should contain subplan_execution_failed true
|