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