Skip to Content
DocsAgentsInput Processors

Input Processors

Input Processors allow you to intercept, modify, validate, or filter messages before they are sent to the language model. This is useful for implementing guardrails, content moderation, message transformation, and security controls.

Processors operate on the messages in your conversation thread. They can modify, filter, or validate content, and even abort the request entirely if certain conditions are met.

Built-in Processors

Mastra provides several built-in processors for common use cases:

UnicodeNormalizer

This processor normalizes Unicode text to ensure consistent formatting and remove potentially problematic characters.

import { Agent } from "@mastra/core/agent"; import { UnicodeNormalizer } from "@mastra/core/agent/input-processor/processors"; import { openai } from "@ai-sdk/openai"; const agent = new Agent({ name: 'normalized-agent', instructions: 'You are a helpful assistant', model: openai("gpt-4o"), inputProcessors: [ new UnicodeNormalizer({ stripControlChars: true, collapseWhitespace: true, }), ], });

Available options:

  • stripControlChars: Remove control characters (default: false)
  • preserveEmojis: Keep emojis intact (default: true)
  • collapseWhitespace: Collapse multiple spaces/newlines (default: true)
  • trim: Remove leading/trailing whitespace (default: true)

ModerationInputProcessor

This processor provides content moderation using an LLM to detect inappropriate content across multiple categories.

import { ModerationInputProcessor } from "@mastra/core/agent/input-processor/processors"; const agent = new Agent({ inputProcessors: [ new ModerationInputProcessor({ model: openai("gpt-4.1-nano"), // Use a fast, cost-effective model threshold: 0.7, // Confidence threshold for flagging strategy: 'block', // Block flagged content categories: ['hate', 'harassment', 'violence'], // Custom categories }), ], });

Available options:

  • model: Language model for moderation analysis (required)
  • categories: Array of categories to check (default: [‘hate’,‘hate/threatening’,‘harassment’,‘harassment/threatening’,‘self-harm’,‘self-harm/intent’,‘self-harm/instructions’,‘sexual’,‘sexual/minors’,‘violence’,‘violence/graphic’])
  • threshold: Confidence threshold for flagging (0-1, default: 0.5)
  • strategy: Action when content is flagged (default: ‘block’)
  • customInstructions: Custom instructions for the moderation agent

Strategies available:

  • block: Reject the request with an error (default)
  • warn: Log warning but allow content through
  • filter: Remove flagged messages but continue processing

PromptInjectionDetector

This processor detects and prevents prompt injection attacks, jailbreaks, and system manipulation attempts.

import { PromptInjectionDetector } from "@mastra/core/agent/input-processor/processors"; const agent = new Agent({ inputProcessors: [ new PromptInjectionDetector({ model: openai("gpt-4.1-nano"), threshold: 0.8, // Higher threshold for fewer false positives strategy: 'rewrite', // Attempt to neutralize while preserving intent detectionTypes: ['injection', 'jailbreak', 'system-override'], }), ], });

Available options:

  • model: Language model for injection detection (required)
  • detectionTypes: Array of injection types to detect (default: [‘injection’, ‘jailbreak’, ‘system-override’])
  • threshold: Confidence threshold for flagging (0-1, default: 0.7)
  • strategy: Action when injection is detected (default: ‘block’)
  • instructions: Custom detection instructions for the agent
  • includeScores: Whether to include confidence scores in logs (default: false)

Strategies available:

  • block: Reject the request (default)
  • warn: Log warning but allow through
  • filter: Remove flagged messages
  • rewrite: Attempt to neutralize the injection while preserving legitimate intent

PIIDetector

This processor detects and optionally redacts personally identifiable information (PII) from messages.

import { PIIDetector } from "@mastra/core/agent/input-processor/processors"; const agent = new Agent({ inputProcessors: [ new PIIDetector({ model: openai("gpt-4.1-nano"), threshold: 0.6, strategy: 'redact', // Automatically redact detected PII detectionTypes: ['email', 'phone', 'credit-card', 'ssn', 'api-key', 'crypto-wallet', 'iban'], redactionMethod: 'mask', // Preserve format while masking preserveFormat: true, // Keep original structure in redacted values includeDetections: true, // Log details for compliance auditing }), ], });

Available options:

  • model: Language model for PII detection (required)
  • detectionTypes: Array of PII types to detect (default: [‘email’, ‘phone’, ‘credit-card’, ‘ssn’, ‘api-key’, ‘ip-address’, ‘name’, ‘address’, ‘date-of-birth’, ‘url’, ‘uuid’, ‘crypto-wallet’, ‘iban’])
  • threshold: Confidence threshold for flagging (0-1, default: 0.6)
  • strategy: Action when PII is detected (default: ‘block’)
  • redactionMethod: How to redact PII (‘mask’, ‘hash’, ‘remove’, ‘placeholder’, default: ‘mask’)
  • preserveFormat: Maintain PII structure during redaction (default: true)
  • includeDetections: Include detection details in logs for compliance (default: false)
  • instructions: Custom detection instructions for the agent

Strategies available:

  • block: Reject requests containing PII (default)
  • warn: Log warning but allow through
  • filter: Remove messages containing PII
  • redact: Replace PII with placeholder values

LanguageDetector

This processor detects the language of incoming messages and can automatically translate them to a target language.

import { LanguageDetector } from "@mastra/core/agent/input-processor/processors"; const agent = new Agent({ inputProcessors: [ new LanguageDetector({ model: openai("gpt-4o"), targetLanguages: ['English', 'en'], // Accept English content strategy: 'translate', // Auto-translate non-English content threshold: 0.8, // High confidence threshold }), ], });

Available options:

  • model: Language model for detection and translation (required)
  • targetLanguages: Array of target languages (language names or ISO codes)
  • threshold: Confidence threshold for language detection (0-1, default: 0.7)
  • strategy: Action when non-target language is detected (default: ‘detect’)
  • preserveOriginal: Keep original content in metadata (default: true)
  • instructions: Custom detection instructions for the agent

Strategies available:

  • detect: Only detect language, don’t translate (default)
  • translate: Automatically translate to target language
  • block: Reject content not in target language
  • warn: Log warning but allow content through

Applying Multiple Processors

You can chain multiple processors. They execute sequentially in the order they appear in the inputProcessors array. The output of one processor becomes the input for the next.

Order matters! Generally, it’s best practice to place text normalization first, security checks next, and content modification last.

import { Agent } from "@mastra/core/agent"; import { UnicodeNormalizer, ModerationInputProcessor, PromptInjectionDetector, PIIDetector } from "@mastra/core/agent/input-processor/processors"; const secureAgent = new Agent({ inputProcessors: [ // 1. Normalize text first new UnicodeNormalizer({ stripControlChars: true }), // 2. Check for security threats new PromptInjectionDetector({ model: openai("gpt-4.1-nano") }), // 3. Moderate content new ModerationInputProcessor({ model: openai("gpt-4.1-nano") }), // 4. Handle PII last new PIIDetector({ model: openai("gpt-4.1-nano"), strategy: 'redact' }), ], });

Creating Custom Processors

You can create custom processors by implementing the InputProcessor interface.

import type { InputProcessor, MastraMessageV2 } from "@mastra/core/agent"; class MessageLengthLimiter implements InputProcessor { readonly name = 'message-length-limiter'; constructor(private maxLength: number = 1000) {} process({ messages, abort }: { messages: MastraMessageV2[]; abort: (reason?: string) => never }): MastraMessageV2[] { // Check total message length const totalLength = messages.reduce((sum, msg) => { return sum + msg.content.parts .filter(part => part.type === 'text') .reduce((partSum, part) => partSum + (part as any).text.length, 0); }, 0); if (totalLength > this.maxLength) { abort(`Message too long: ${totalLength} characters (max: ${this.maxLength})`); } return messages; } } // Use the custom processor const agent = new Agent({ inputProcessors: [ new MessageLengthLimiter(2000), // Limit to 2000 characters ], });

When creating custom processors:

  • Always return the messages array (potentially modified)
  • Use abort(reason) to terminate processing early
  • Mutate the input messages directly
  • Keep processors focused on a single responsibility

Integration with Agent Methods

Input processors work with both generate() and stream() methods. The entire processor pipeline completes before the agent begins generating or streaming a response.

// Processors run before generate() const result = await agent.generate('Hello'); // Processors also run before stream() const stream = await agent.stream('Hello'); for await (const chunk of stream.textStream) { console.log(chunk); }

If any processor calls abort(), the request terminates immediately and subsequent processors are not executed. The agent returns an error response with details about why the request was blocked.