Skip to main content

Overview

Steps are the building blocks of workflows. Each step represents a discrete unit of work with typed inputs and outputs, error handling, and suspend/resume capabilities.

Creating Steps

createStep (from params)

createStep<TStepId, TStateSchema, TInputSchema, TOutputSchema, TResumeSchema, TSuspendSchema, TRequestContextSchema>(
  params: StepParams
): Step
Creates a step from explicit parameters.
params
StepParams
required
Step configuration
step
Step
A step that can be added to a workflow

createStep (from agent)

createStep<TStepId>(
  agent: Agent<TStepId>,
  agentOptions?: AgentStepOptions
): Step<TStepId, unknown, { prompt: string }, { text: string }>
Creates a step from an agent (defaults to { text: string } output).
agent
Agent
required
The agent to wrap as a step
agentOptions
AgentStepOptions
Agent execution options
step
Step
A step that executes the agent

createStep (from tool)

createStep<TSchemaIn, TSuspend, TResume, TSchemaOut, TContext, TId, TRequestContext>(
  tool: Tool<TSchemaIn, TSchemaOut, TSuspend, TResume, TContext, TId, TRequestContext>,
  toolOptions?: { retries?: number; scorers?: MastraScorers; metadata?: StepMetadata }
): Step<TId, unknown, TSchemaIn, TSchemaOut, TSuspend, TResume>
Creates a step from a tool.
tool
Tool
required
The tool to wrap as a step
toolOptions
object
Tool step options
step
Step
A step that executes the tool

createStep (from processor)

createStep<TProcessorId>(
  processor: Processor<TProcessorId>
): Step<`processor:${TProcessorId}`, unknown, ProcessorStepInput, ProcessorStepOutput>
Creates a step from a processor.
processor
Processor
required
The processor to wrap as a step. Processor must have at least one processor method (processInput, processInputStep, processOutputStream, processOutputResult, or processOutputStep).
step
Step
A step that executes the processor

Step Properties

id
string
Unique identifier for the step
description
string | undefined
Optional description of the step
inputSchema
SchemaWithValidation
Schema for validating input
outputSchema
SchemaWithValidation
Schema for validating output
stateSchema
SchemaWithValidation | undefined
Schema for step state
resumeSchema
SchemaWithValidation | undefined
Schema for resume data
suspendSchema
SchemaWithValidation | undefined
Schema for suspend data
requestContextSchema
SchemaWithValidation | undefined
Schema for request context
retries
number | undefined
Number of retry attempts
scorers
MastraScorers | DynamicArgument<MastraScorers> | undefined
Scorers for evaluating execution
metadata
StepMetadata | undefined
Additional metadata
component
string | undefined
Component type (e.g., ‘AGENT’, ‘TOOL’, ‘PROCESSOR’)

Execute Function

The execute function is the core of a step. It receives typed inputs and context, performs operations, and returns typed outputs.

Parameters

inputData
TInput
required
The input data for the step (validated against inputSchema)
context
ExecuteContext
required
Execution context

Return Value

The execute function should return:
  • The step output (validated against outputSchema)
  • A Promise that resolves to the output

Suspend and Resume

Steps can suspend execution to wait for external events (e.g., user input, webhook, scheduled time).

Suspending

execute: async ({ inputData, suspend }) => {
  // Request user approval
  suspend({ approvalId: '123', timestamp: Date.now() }, {
    label: 'approval',
    resumeLabel: 'approved'
  });
}

Resuming

execute: async ({ inputData, resumeData }) => {
  if (resumeData) {
    // Execution is resuming from suspension
    console.log('Resumed with:', resumeData);
  }
  // Continue execution
}

Example

import { createStep } from '@mastra/core/workflows';
import { z } from 'zod';

// Create a simple step
const validateStep = createStep({
  id: 'validate',
  description: 'Validate user input',
  inputSchema: z.object({
    email: z.string().email(),
    age: z.number().min(18)
  }),
  outputSchema: z.object({
    valid: z.boolean(),
    message: z.string()
  }),
  execute: async ({ inputData }) => {
    return {
      valid: true,
      message: 'Validation passed'
    };
  }
});

// Create a step with state
const counterStep = createStep({
  id: 'counter',
  description: 'Increment counter',
  stateSchema: z.object({ count: z.number() }),
  inputSchema: z.object({}),
  outputSchema: z.object({ newCount: z.number() }),
  execute: async ({ state, setState }) => {
    const newCount = (state?.count || 0) + 1;
    setState({ count: newCount });
    return { newCount };
  }
});

// Create a step that can suspend
const approvalStep = createStep({
  id: 'approval',
  description: 'Wait for approval',
  inputSchema: z.object({ requestId: z.string() }),
  outputSchema: z.object({ approved: z.boolean() }),
  suspendSchema: z.object({ requestId: z.string() }),
  resumeSchema: z.object({ approved: z.boolean() }),
  execute: async ({ inputData, suspend, resumeData }) => {
    if (!resumeData) {
      // First execution - suspend and wait
      suspend({ requestId: inputData.requestId }, {
        label: 'waiting-approval'
      });
      return { approved: false };
    }
    // Resumed after approval
    return { approved: resumeData.approved };
  }
});