Skip to main content

submitPlanTool

A built-in, agent-agnostic tool that submits an implementation plan for user review. The agent writes a plan to a markdown file and passes the file path to this tool. The tool suspends the run until the user approves or rejects the plan.

The tool pauses through the native tool suspension primitive: it calls suspend({ path }), which makes the agent emit a tool-call-suspended event. The host reads the plan file, presents it to the user, and resumes with an approval or rejection.

When executed outside an agent run (no suspend available), the tool returns a readable fallback string containing the file path.

Usage example
Direct link to Usage example

Add submitPlanTool to an agent's toolset:

src/mastra/agents/index.ts
import { Agent } from '@mastra/core/agent'
import { submitPlanTool } from '@mastra/core/tools'

const agent = new Agent({
id: 'planner',
name: 'Planner',
instructions: 'Write a plan to a file before starting work, then submit it for approval.',
model,
tools: { submitPlanTool },
})

Handle the suspension and resume:

src/run.ts
import fs from 'node:fs'

const stream = await agent.stream('Refactor the auth module')

for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-suspended' && chunk.payload.toolName === 'submit_plan') {
const { path } = chunk.payload.suspendPayload
const plan = fs.readFileSync(path, 'utf-8')
console.log(plan)

// Approve:
const resumed = await agent.resumeStream({ action: 'approved' }, { runId: stream.runId })
for await (const c of resumed.textStream) process.stdout.write(c)
}
}

To reject with feedback:

await agent.resumeStream(
{ action: 'rejected', feedback: 'Add error handling steps' },
{ runId: stream.runId },
)

Input schema
Direct link to Input schema

The model calls this tool with the following parameters:

path:

string
Path to the plan markdown file on disk (e.g. '.mastracode/plans/add-dark-mode.md').

Suspend payload
Direct link to Suspend payload

The tool-call-suspended event carries a suspendPayload:

path:

string
Path to the plan file the agent wrote.

title?:

string
Plan title, filled by the host after reading the file.

plan?:

string
Plan body, filled by the host after reading the file.

Resume data
Direct link to Resume data

Pass an object to agent.resumeStream():

action:

'approved' | 'rejected'
Whether the user approved or rejected the plan.

feedback?:

string
Revision instructions when the plan is rejected. Surfaced to the model so it can revise and resubmit.

path?:

string
The plan file path, echoed back for history replay.

title?:

string
The plan title, echoed back for history replay.

plan?:

string
The plan body, echoed back for history replay.

Approval behavior
Direct link to Approval behavior

  • Approved: The tool returns "Plan approved. Proceed with implementation following the approved plan." to the model.
  • Rejected with feedback: The tool returns the feedback and asks the model to revise the plan and submit again.
  • Rejected without feedback: The tool tells the model to wait for the user's next message before revising.

When used inside an AgentController, plan approval triggers an automatic mode switch from the planning mode to the default execution mode. See Modes for details.

On this page