Skip to content

Put ACT planning behind a planner trait - #20

Merged
brynary merged 1 commit into
act-fill-checksfrom
act-planner-seam
Oct 5, 2026
Merged

brynary merged 1 commit into
act-fill-checksfrom
act-planner-seam

Conversation

@brynary

@brynary brynary commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Stacked on #19. Step 1 of the ACT planner plan: the seam, with no behavior change.

Why

We want to swap how ACT chooses its action: the LLM by default, and TypeSafe Jev with an LLM fallback as an alternative (a --jev flag, in the next PR). This PR adds the seam only.

What

  • run/act/planner.rs adds the ActPlanner trait. plan(PlanRequest) -> PlanFuture returns the model's answer or a PlanError, and always the usage spent. The future is boxed, so the trait is dyn-compatible without an async-trait dependency, and the runner holds one planner per run as Arc<dyn ActPlanner>.
  • LlmPlanner holds today's planning: Stagehand's prompts and one structured call through ModelClient.
  • run_act asks the planner for the answer and keeps everything else in one place: the snapshot, PageSnapshot::decide, the action, the stale-ref retry, the fill read-back, and the report. Every planner shares that execution.
  • FlowRun.model: Option<&ModelClient> becomes planner: Option<&dyn ActPlanner>.

The trait follows the plan's decision. The Rust style guide defaults to an enum when the crate owns every variant. The trait makes the planner an extension point: the Jev planner will hold its LLM fallback as another ActPlanner, and a later ACT cache (SPEC §18) can wrap a planner the same way.

Tests

No new tests: behavior is unchanged, and all 16 ACT acceptance tests and the unit tests pass as they are. mise run check passes.

🤖 Generated with Claude Code

ACT now asks an ActPlanner for the model's answer instead of calling the
model client directly. LlmPlanner holds today's planning: one structured
call with Stagehand's prompts. The step loop keeps everything else: the
snapshot, the check with PageSnapshot::decide, the action, the stale-ref
retry, the fill read-back, and the report.

The trait returns a boxed future, so the runner can hold one planner as
Arc<dyn ActPlanner> and choose it at run time. This is the seam for a
Jev planner with an LLM fallback. Behavior does not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@brynary
brynary added this pull request to stack #56 October 5, 2026 13:22
@brynary
brynary merged commit fc13a32 into main Oct 5, 2026
3 checks passed
@brynary
brynary deleted the act-planner-seam branch October 5, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant