dfa05a6909
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 26s
CI / quality (pull_request) Successful in 32s
CI / build (pull_request) Successful in 35s
CI / security (pull_request) Successful in 52s
CI / typecheck (pull_request) Successful in 56s
CI / e2e_tests (pull_request) Successful in 1m36s
CI / unit_tests (pull_request) Successful in 3m25s
CI / integration_tests (pull_request) Successful in 3m55s
CI / docker (pull_request) Successful in 57s
CI / coverage (pull_request) Successful in 6m54s
CI / lint (push) Successful in 14s
CI / quality (push) Successful in 35s
CI / typecheck (push) Successful in 39s
CI / security (push) Successful in 51s
CI / benchmark-regression (push) Has been skipped
CI / build (push) Successful in 21s
CI / e2e_tests (push) Successful in 2m14s
CI / unit_tests (push) Successful in 5m9s
CI / integration_tests (push) Successful in 5m29s
CI / docker (push) Successful in 1m6s
CI / coverage (push) Successful in 6m12s
CI / benchmark-publish (push) Successful in 20m51s
CI / benchmark-regression (pull_request) Successful in 37m16s
The `plan execute` CLI command only performed phase transitions (Strategize → Execute) without ever invoking the `PlanExecutor` to drive the strategize or execute actors. `PlanExecutor.__init__` unconditionally created `StrategizeStubActor()` and `ExecuteStubActor()` which parse text locally and return empty changesets — no real LLM call was made. Added `_get_plan_executor()` helper that resolves `ProviderRegistry` from the DI container and constructs `LLMStrategizeActor` / `LLMExecuteActor` for real LLM invocations via LangChain. Updated `execute_plan` CLI command to detect plan phase/state and automatically run the appropriate actor: - Strategize/queued → run strategize actor → transition to Execute - Strategize/complete → phase transition only (backward compat) - Execute/queued → run execute actor → mark complete New `llm_actors.py` module provides `LLMStrategizeActor` (task decomposition into numbered steps) and `LLMExecuteActor` (code generation with FILE: blocks). Both resolve `provider/model` actor names (e.g. `openai/gpt-4`) to live LangChain LLM instances. `PlanExecutor.__init__` now accepts optional `strategize_actor` and `execute_actor` parameters, falling back to stubs when None. Existing mock-based BDD tests remain backward-compatible via duck- typing fallback (MagicMock.phase is not a PlanPhase, so the legacy `service.execute_plan()` path is taken). Includes Behave BDD scenarios testing custom actor injection into PlanExecutor. ISSUES CLOSED: #960
174 lines
7.2 KiB
Gherkin
174 lines
7.2 KiB
Gherkin
Feature: Plan Actor Integration
|
|
As a developer
|
|
I want strategize and execute stub actors to drive plan phases
|
|
So that plans can be processed through the full lifecycle with ChangeSet capture
|
|
|
|
Background:
|
|
Given I have a plan executor service
|
|
|
|
# Strategize stub actor tests
|
|
|
|
Scenario: Strategize stub produces decisions from definition of done
|
|
Given I have a plan in strategize queued state with definition "Tests pass\nCoverage >= 90%"
|
|
When I run the strategize phase
|
|
Then strategize should produce 2 decisions
|
|
And the decision root id should be set on the plan
|
|
And the plan should be in strategize complete state
|
|
|
|
Scenario: Strategize stub handles single-line definition of done
|
|
Given I have a plan in strategize queued state with definition "All tests pass"
|
|
When I run the strategize phase
|
|
Then strategize should produce 1 decisions
|
|
And the decision root id should be set on the plan
|
|
|
|
Scenario: Strategize stub handles empty definition of done
|
|
Given I have a plan in strategize queued state with empty definition
|
|
When I run the strategize phase
|
|
Then strategize should produce 1 decisions
|
|
And the first decision should be "Complete the plan objectives"
|
|
|
|
Scenario: Strategize stub handles bullet list definition of done
|
|
Given I have a plan in strategize queued state with definition "- Unit tests pass\n- Integration tests pass\n- Coverage above threshold"
|
|
When I run the strategize phase
|
|
Then strategize should produce 3 decisions
|
|
|
|
Scenario: Strategize stub records invariant enforcement
|
|
Given I have a plan with invariants in strategize queued state
|
|
When I run the strategize phase
|
|
Then the strategize result should include invariant records
|
|
And each invariant record should have enforcement status
|
|
|
|
Scenario: Strategize is read-only and does not modify resources
|
|
Given I have a plan in strategize queued state with definition "Tests pass"
|
|
When I run the strategize phase
|
|
Then no changeset should be produced during strategize
|
|
And the plan sandbox refs should be empty
|
|
|
|
# Execute stub actor tests
|
|
|
|
Scenario: Execute stub captures tool calls through ChangeSet
|
|
Given I have a plan that completed strategize
|
|
When I run the execute phase
|
|
Then the changeset id should be set on the plan
|
|
And the plan should be in execute complete state
|
|
|
|
Scenario: Execute stub records execution metadata
|
|
Given I have a plan that completed strategize
|
|
When I run the execute phase
|
|
Then the plan should have execution metadata
|
|
And the tool calls count should be recorded
|
|
|
|
Scenario: Execute stub uses sandbox when provided
|
|
Given I have a plan executor with sandbox root
|
|
And I have a plan that completed strategize
|
|
When I run the execute phase
|
|
Then the plan sandbox refs should not be empty
|
|
|
|
# Phase transition guards
|
|
|
|
Scenario: Execute is prevented when plan is not in Strategize COMPLETE state
|
|
Given I have a plan in strategize queued state with definition "Tests pass"
|
|
When I try to run the execute phase
|
|
Then a plan error should be raised about phase mismatch
|
|
|
|
Scenario: Execute is prevented when plan has no decision tree
|
|
Given I have a plan in execute queued state without decisions
|
|
When I try to run the execute phase on the executor
|
|
Then a plan error should be raised about missing decisions
|
|
|
|
Scenario: Strategize fails when plan is not in strategize phase
|
|
Given I have a plan in execute phase for executor
|
|
When I try to run the strategize phase
|
|
Then a plan error should be raised about phase mismatch
|
|
|
|
# Error handling and status updates
|
|
|
|
Scenario: Strategize failure captures error details
|
|
Given I have a plan in strategize queued state with definition "Tests pass"
|
|
And the strategize actor is configured to fail
|
|
When I try to run the strategize phase expecting failure
|
|
Then the plan should be in errored state
|
|
And the plan should have error details
|
|
|
|
Scenario: Execute failure captures error details
|
|
Given I have a plan that completed strategize
|
|
And the execute actor is configured to fail
|
|
When I try to run the execute phase expecting failure
|
|
Then the plan should be in errored state
|
|
And the plan should have error details
|
|
|
|
# Streaming hooks
|
|
|
|
Scenario: Strategize emits streaming events
|
|
Given I have a plan in strategize queued state with definition "Tests pass"
|
|
And I have a stream callback registered
|
|
When I run the strategize phase with streaming
|
|
Then the stream callback should have received strategize events
|
|
And the stream events should include strategize_started
|
|
And the stream events should include strategize_complete
|
|
|
|
Scenario: Execute emits streaming events
|
|
Given I have a plan that completed strategize
|
|
And I have a stream callback registered
|
|
When I run the execute phase with streaming
|
|
Then the stream callback should have received execute events
|
|
And the stream events should include execute_started
|
|
And the stream events should include execute_complete
|
|
|
|
# Validation
|
|
|
|
Scenario: Strategize rejects empty plan id
|
|
When I try to run strategize with empty plan id
|
|
Then a validation error should be raised for empty plan id
|
|
|
|
Scenario: Execute rejects empty plan id
|
|
When I try to run execute with empty plan id
|
|
Then a validation error should be raised for empty plan id
|
|
|
|
Scenario: PlanExecutor rejects None lifecycle service
|
|
When I try to create a PlanExecutor with None lifecycle service
|
|
Then a validation error should be raised for None lifecycle service
|
|
|
|
# Strategy decision model
|
|
|
|
Scenario: StrategyDecision model validates fields
|
|
When I create a strategy decision with valid fields
|
|
Then the strategy decision should have the correct attributes
|
|
|
|
Scenario: StrategizeResult model stores decisions
|
|
When I create a strategize result with 3 decisions
|
|
Then the result should contain 3 decisions
|
|
And the result should have a root id
|
|
|
|
Scenario: ExecuteResult model stores changeset
|
|
When I create an execute result with changeset
|
|
Then the result should have a changeset id
|
|
And the result should have a changeset object
|
|
|
|
# Full lifecycle integration
|
|
|
|
Scenario: Full strategize then execute lifecycle
|
|
Given I have a plan in strategize queued state with definition "Write tests\nRun linter\nVerify coverage"
|
|
When I run the strategize phase
|
|
And I transition the plan to execute
|
|
And I run the execute phase
|
|
Then the plan should be in execute complete state
|
|
And the changeset id should be set on the plan
|
|
And the decision root id should be set on the plan
|
|
|
|
# PlanExecutor with injected actors
|
|
|
|
Scenario: PlanExecutor accepts custom strategize actor
|
|
Given I have a plan executor with a custom strategize actor
|
|
And I have a plan in strategize queued state with definition "Custom task"
|
|
When I run the strategize phase
|
|
Then the custom strategize actor should have been called
|
|
And the plan should be in strategize complete state
|
|
|
|
Scenario: PlanExecutor accepts custom execute actor
|
|
Given I have a plan executor with a custom execute actor
|
|
And I have a plan that completed strategize
|
|
When I run the execute phase
|
|
Then the custom execute actor should have been called
|
|
And the plan should be in execute complete state
|