Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Plan & Execute Agent

The Plan & Execute agent separates planning from execution. It delegates plan generation to whichever planner plugin is active on the bus (e.g. nexus.planner.dynamic or nexus.planner.static) while retaining full control of the surrounding flow: phase transitions, approval, step execution, re-planning on failure, and final synthesis.

This means you can change how plans are produced — LLM-driven, static, role-specialized, or a custom planner you build — without modifying the agent.

Details

IDnexus.agent.planexec
DependenciesA planner plugin (e.g. nexus.planner.dynamic) must be active

Configuration

KeyTypeDefaultDescription
execution_model_rolestringbalancedModel role used for step execution and synthesis
replan_on_failurebooltrueRequest a fresh plan if a step fails (up to 2 replans per turn)
approvalstringneverWhen planexec requires approval after the planner returns a plan: always, never
system_promptstring(none)Inline system prompt for execution/synthesis
system_prompt_filestring(none)Path to system prompt file

Per-step iteration limits are enforced by nexus.gate.endless_loop, not by planexec itself. Plan-step counts are managed by the planner that produces plan.result.

Plan-generation options (model, prompt, max steps, planner-side approval) now live on the planner plugin itself. See the planner docs.

Approval layers

Two independent approval gates may apply:

  1. Planner-side — e.g. nexus.planner.dynamic supports always / auto / never. When the planner denies or the user rejects, the planner emits plan.result with Approved: false and planexec will end the turn.
  2. planexec-side — even when the planner returns an approved plan, setting planexec’s own approval: always will emit a second plan.approval.request before execution begins.

To avoid double-prompting, pick one side to own approval and set the other to never.

Events

Subscribes To

EventPriorityPurpose
io.input50Receives user messages
tool.result50Tool execution results
llm.response50Step execution and synthesis responses
llm.stream.chunk / llm.stream.end50Streaming synthesis output
skill.loaded50Skill content
tool.registerTool discovery
plan.result50Receives generated plans from the active planner
plan.approval.response50User response to planexec-side approval
memory.compacted50History compaction

Emits

EventWhen
plan.requestStart of a turn, or when re-planning after a step failure
plan.approval.requestWhen planexec’s own approval: always is set
llm.requestStep execution and final synthesis
before:tool.invoke / tool.invokeTool invocation
before:tool.resultBefore tool result propagation (vetoable)
agent.planAfter each step status change
io.statusPhase transitions
thinking.stepReasoning steps
agent.turn.start / agent.turn.endTurn boundaries

Phases

The agent transitions through these phases:

stateDiagram-v2
    direction LR
    [*] --> idle
    idle --> planning: agent.turn.start
    planning --> awaiting_approval: approval == always
    planning --> executing: approval skipped
    awaiting_approval --> executing: user approves
    awaiting_approval --> idle: user rejects
    executing --> executing: next step
    executing --> planning: step failed + replan_on_failure
    executing --> synthesizing: all steps complete
    synthesizing --> idle: agent.turn.end
    idle --> [*]
  1. Planning — Emits plan.request; waits for plan.result from the active planner.
  2. Awaiting Approval — Only entered if planexec’s own approval: always.
  3. Executing — Runs each step sequentially, with its own message history and iteration budget.
  4. Synthesizing — After all steps complete, generates a summary of results.

Replanning

When replan_on_failure: true and a step fails, the agent:

  1. Collects the status and results of completed/failed/pending steps.
  2. Emits a fresh plan.request whose Input contains the original request plus a structured summary of what happened.
  3. Waits for the new plan.result and resumes execution with the revised plan.

Because re-planning is just another plan.request, any planner implementation automatically participates.

Example Configuration

plugins:
  active:
    - nexus.agent.planexec
    - nexus.planner.dynamic    # any planner plugin works
    # ...

  nexus.agent.planexec:
    execution_model_role: balanced
    replan_on_failure: true
    approval: never
    system_prompt: |
      You are a coding assistant powered by Nexus. You help users write, debug, refactor, and understand code.

      ## Guidelines

      1. Always explain your reasoning before making changes
      2. Run tests after modifications to verify correctness
      3. Prefer minimal, targeted changes over broad refactors
      4. Ask for clarification when requirements are ambiguous
      5. Read files in chunks 16kb or less
      6. Follow the existing code style and conventions of the project

  nexus.planner.dynamic:
    model_role: reasoning
    max_steps: 8
    approval: auto

When to Use

Choose Plan & Execute over ReAct when:

  • Tasks are complex and benefit from upfront decomposition.
  • You want explicit step tracking and progress visibility.
  • You want to swap planning strategies (LLM, static, domain-specific) without touching the agent.
  • You need a different model tier for planning vs. execution.