Files
cleveragents-core/docs/reference/plan_execute.md
freemo a2da043cbd
CI / lint (pull_request) Successful in 25s
CI / benchmark-publish (pull_request) Has been skipped
CI / quality (pull_request) Successful in 21s
CI / typecheck (pull_request) Successful in 39s
CI / security (pull_request) Successful in 37s
CI / build (pull_request) Successful in 26s
CI / integration_tests (pull_request) Successful in 4m43s
CI / unit_tests (pull_request) Successful in 11m2s
CI / docker (pull_request) Successful in 58s
CI / benchmark-regression (pull_request) Successful in 18m58s
CI / coverage (pull_request) Successful in 24m24s
feat(M1.2): PlanExecutionContext, RuntimeExecuteActor, and runtime mode
Adds PlanExecutionContext carrying plan metadata and delegating
changeset ops to ChangeSetStore.  RuntimeExecuteResult captures
execution output (changeset_id, tool_call_count, sandbox_refs,
decision_ids_processed, execution_duration_ms).

RuntimeExecuteActor dispatches StrategyDecision lists through
ToolRunner with full changeset capture and optional streaming
callbacks.  PlanExecutor gains execution_context param with
has_runtime / changeset_store / execution_context properties
and _run_execute_with_runtime / _run_execute_with_stub split.

31 Behave scenarios, 5 Robot smoke tests, ASV benchmark suite,
and reference documentation.

Ref: Day-14 Rebaseline – M1.2 Plan-execute runtime wiring [Jeff]
2026-02-22 15:13:43 +00:00

7.8 KiB

Plan Execute: Strategize & Execute Integration

Overview

The plan executor connects the PlanLifecycleService to stub actors that drive plans through the Strategize and Execute phases. In M1, these actors are local-only stubs (no LLM calls); future milestones will integrate real AI providers.

When a PlanExecutionContext is provided, the execute phase delegates to RuntimeExecuteActor for full tool-calling runtime integration with changeset capture through ChangeSetStore.

Architecture

PlanExecutor
├── StrategizeStubActor     (read-only, produces decision tree)
├── ExecuteStubActor         (legacy stub: sandbox + ChangeSetCapture)
├── RuntimeExecuteActor      (runtime: ToolRunner + ChangeSetStore)
├── PlanExecutionContext      (plan metadata + resource bindings)
└── PlanLifecycleService      (phase transitions, persistence)

Execution Modes

Mode Actor Trigger Output
Stub ExecuteStubActor No execution_context ExecuteResult
Runtime RuntimeExecuteActor execution_context is provided RuntimeExecuteResult

PlanExecutionContext

The PlanExecutionContext bridges plan metadata into the tool runtime:

from cleveragents.application.services.plan_execution_context import (
    PlanExecutionContext,
)
from cleveragents.domain.models.core.change import InMemoryChangeSetStore

ctx = PlanExecutionContext(
    plan_id="01HGZ...",
    decision_root_id="01HGZ...",
    sandbox_root="/tmp/sandbox",
    automation_profile="trusted",
    project_resources={"repo": {"path": "/code"}},
    changeset_store=InMemoryChangeSetStore(),
)

# Start a changeset for tracking mutations
changeset_id = ctx.start_changeset()

# Record changes during execution
ctx.record_change(entry)

# Retrieve changeset
cs = ctx.get_changeset(changeset_id)

# Summarize context state
summary = ctx.summarize()

Fields

Field Type Required Description
plan_id str Yes ULID of the plan
decision_root_id str | None No Root decision from strategize
sandbox_root str | None No Sandbox filesystem path
automation_profile str | None No Automation profile name
project_resources dict[str, Any] No Project resource metadata
resource_bindings dict[str, BoundResource] No Resolved resource bindings
changeset_store ChangeSetStore No Defaults to InMemoryChangeSetStore

RuntimeExecuteActor

Wraps ToolRunner to execute strategy decisions with changeset capture:

from cleveragents.application.services.plan_execution_context import (
    RuntimeExecuteActor,
    RuntimeExecuteResult,
)

actor = RuntimeExecuteActor(
    tool_runner=runner,
    execution_context=ctx,
)
result: RuntimeExecuteResult = actor.execute(decisions)

RuntimeExecuteResult Fields

Field Type Description
changeset_id str ULID of the produced changeset
tool_call_count int Number of tool calls made
sandbox_refs list[str] Sandbox reference paths
decision_ids_processed list[str] Processed decision node IDs
execution_duration_ms float Wall-clock execution time (ms)

PlanExecutor Runtime Mode

The PlanExecutor auto-selects runtime vs stub mode:

from cleveragents.application.services.plan_executor import PlanExecutor

# Stub mode (no execution_context)
executor = PlanExecutor(lifecycle_service=lifecycle, tool_runner=runner)
assert not executor.has_runtime

# Runtime mode (with execution_context)
executor = PlanExecutor(
    lifecycle_service=lifecycle,
    tool_runner=runner,
    execution_context=ctx,
)
assert executor.has_runtime
assert executor.changeset_store is not None

# Execute auto-dispatches to RuntimeExecuteActor
result = executor.run_execute(plan_id)

Properties

Property Type Description
has_runtime bool True if execution_context is set
changeset_store ChangeSetStore | None Store from execution context
execution_context PlanExecutionContext | None The execution context

ChangeSetStore Wiring

The ChangeSetStore protocol defines the interface for changeset persistence:

class ChangeSetStore(Protocol):
    def start(self, plan_id: str) -> str: ...
    def record(self, changeset_id: str, entry: ChangeEntry) -> None: ...
    def get(self, changeset_id: str) -> SpecChangeSet | None: ...
    def get_for_plan(self, plan_id: str) -> list[SpecChangeSet]: ...
    def summarize(self, changeset_id: str) -> dict[str, Any]: ...

InMemoryChangeSetStore is the default for M1. Database-backed implementations will be added in D1 milestone.

Phase Lifecycle

Phase Actor Mode Output
Strategize StrategizeStubActor Read-only Decision tree, invariant records
Execute RuntimeExecuteActor Runtime ChangeSet via ChangeSetStore
Execute ExecuteStubActor Stub ChangeSet via ChangeSetCapture

Error Handling

Failures in either phase are captured with full error context:

  • error_message: The exception message string
  • error_details: Dict with exception_type, traceback, and mode
  • The plan transitions to ERRORED processing state

Streaming Hooks

Both phases accept an optional stream_callback:

Event Types

Event Phase Actor Description
strategize_started Strat. Stub Phase processing began
strategize_decisions Strat. Stub Decisions produced
strategize_complete Strat. Stub Phase completed
execute_started Execute Stub Stub execute began
execute_step Execute Stub Stub decision step
execute_complete Execute Stub Stub execute completed
runtime_execute_started Execute Runtime Runtime execute began
runtime_execute_step Execute Runtime Runtime decision step
runtime_execute_complete Execute Runtime Runtime execute completed

Module Reference

  • cleveragents.application.services.plan_execution_context
    • PlanExecutionContext: Execution context bridging plan to runtime
    • RuntimeExecuteActor: Tool-calling execute actor
    • RuntimeExecuteResult: Runtime execution output model
  • cleveragents.application.services.plan_executor
    • PlanExecutor: Orchestrator with runtime/stub mode selection
    • StrategizeStubActor: Local-only strategize actor
    • ExecuteStubActor: Local-only execute actor
    • StrategyDecision, StrategizeResult, ExecuteResult: Data models