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
| ID | nexus.agent.planexec |
| Dependencies | A planner plugin (e.g. nexus.planner.dynamic) must be active |
Configuration
| Key | Type | Default | Description |
|---|---|---|---|
execution_model_role | string | balanced | Model role used for step execution and synthesis |
replan_on_failure | bool | true | Request a fresh plan if a step fails (up to 2 replans per turn) |
approval | string | never | When planexec requires approval after the planner returns a plan: always, never |
system_prompt | string | (none) | Inline system prompt for execution/synthesis |
system_prompt_file | string | (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 producesplan.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:
- Planner-side — e.g.
nexus.planner.dynamicsupportsalways/auto/never. When the planner denies or the user rejects, the planner emitsplan.resultwithApproved: falseand planexec will end the turn. - planexec-side — even when the planner returns an approved plan,
setting planexec’s own
approval: alwayswill emit a secondplan.approval.requestbefore execution begins.
To avoid double-prompting, pick one side to own approval and set the other
to never.
Events
Subscribes To
| Event | Priority | Purpose |
|---|---|---|
io.input | 50 | Receives user messages |
tool.result | 50 | Tool execution results |
llm.response | 50 | Step execution and synthesis responses |
llm.stream.chunk / llm.stream.end | 50 | Streaming synthesis output |
skill.loaded | 50 | Skill content |
tool.register | — | Tool discovery |
plan.result | 50 | Receives generated plans from the active planner |
plan.approval.response | 50 | User response to planexec-side approval |
memory.compacted | 50 | History compaction |
Emits
| Event | When |
|---|---|
plan.request | Start of a turn, or when re-planning after a step failure |
plan.approval.request | When planexec’s own approval: always is set |
llm.request | Step execution and final synthesis |
before:tool.invoke / tool.invoke | Tool invocation |
before:tool.result | Before tool result propagation (vetoable) |
agent.plan | After each step status change |
io.status | Phase transitions |
thinking.step | Reasoning steps |
agent.turn.start / agent.turn.end | Turn 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 --> [*]
- Planning — Emits
plan.request; waits forplan.resultfrom the active planner. - Awaiting Approval — Only entered if planexec’s own
approval: always. - Executing — Runs each step sequentially, with its own message history and iteration budget.
- Synthesizing — After all steps complete, generates a summary of results.
Replanning
When replan_on_failure: true and a step fails, the agent:
- Collects the status and results of completed/failed/pending steps.
- Emits a fresh
plan.requestwhoseInputcontains the original request plus a structured summary of what happened. - Waits for the new
plan.resultand 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.