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 throughfilter
: 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 agentincludeScores
: Whether to include confidence scores in logs (default: false)
Strategies available:
block
: Reject the request (default)warn
: Log warning but allow throughfilter
: Remove flagged messagesrewrite
: 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 throughfilter
: Remove messages containing PIIredact
: 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 languageblock
: Reject content not in target languagewarn
: 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.