Skip to main content

Reasoning Engine

What Is the Reasoning Engine?

The Reasoning Engine takes structured data -- time-series metrics, categorical check-ins, numeric measurements -- and produces actionable, validated insights through a team of specialized AI agents. Each agent handles one analytical discipline (statistics, pattern recognition, correlation, narrative generation, fact-checking), and they work together in a coordinated pipeline.

Who Is This For?

Product teams use the reasoning engine to power data-driven features without building analytical logic from scratch. Feed it user data and a question, and it returns a structured narrative with confidence scores, key findings, and actionable recommendations.

Engineering teams use it as a composable building block. The engine is format-agnostic -- plug in an intake adapter for your data format and an output adapter for your target, and the same analytical pipeline works across different applications.

What Makes It Different?

ApproachLimitationReasoning Engine
Single LLM callOne model does everything; hard to tune individual aspects10 registered agents, with the core workflow using the relevant subset per step
Rule-based analyticsRigid; can't handle nuance or unexpected patternsDual-mode: algorithmic baselines + AI enhancement
Black box analysisNo verification of output accuracyBuilt-in validation agent fact-checks every claim
Hardcoded formatsNew data sources require core changesAdapter pattern: add new formats without touching the engine

The Pipeline at a Glance

The engine runs a 7-step sequential pipeline, where each step builds on the previous:

StepWhat HappensAgent
0. PreflightValidates input, optionally decides which steps to runStep Orchestrator (optional)
1. TemporalComputes statistics and identifies trendsTemporal Agent
2. PatternDetects behavioral patterns and semantic signalsPattern Agent
3. CorrelationComputes and interprets metric relationshipsNormalizer + Analysis
4. DomainRetrieves relevant external knowledgeQuery Generator + Perplexity search when configured
5. ExplanationSynthesizes findings into a user-facing narrativeExplanation Agent
6. ValidationFact-checks every claim against the raw dataValidation Agent

Every step supports dual-mode processing: deterministic algorithms run first (reliable, reproducible), then AI agents layer semantic understanding on top (nuanced, contextual). This means the pipeline always produces a baseline result even if an agent is unavailable.

See detailed agent documentation for what each agent does, why it matters, and how they collaborate.


Format-Agnostic Architecture

The engine doesn't know or care where data comes from or where results go. Adapters handle all format-specific logic at both ends:

Intake Adapters transform source-specific data into a canonical schema:

  • JSON Array Adapter -- nested object arrays
  • API Payload Adapter -- structured API responses
  • CSV Adapter -- tabular data from external systems
  • Auto-Detection -- canHandle() method enables automatic adapter selection

Output Adapters transform canonical results into target formats:

  • Dashboard Formatter -- JSON optimized for UI rendering
  • Report Formatter -- structured data for PDF generation
  • API Response Formatter -- REST-friendly JSON
  • Plain Text Formatter -- human-readable summaries

Key benefit: Multiple applications can share the same analytical pipeline. Only the adapters change.

Design Principles

  1. Source Agnosticism -- the core engine doesn't know where data originates. Intake adapters normalize any format into a canonical schema.

  2. Target Flexibility -- output adapters transform canonical results into any required format (dashboards, reports, API responses).

  3. Composable Intelligence -- ten registered agents are available to the reasoning artifacts, with step selection determining which agents participate in a given run.


System Architecture

High-Level Architecture Diagram

Component Summary

ComponentPurposeLocation
Intake AdaptersTransform source-specific data → canonical inputadapters/intake-adapter.ts (src/mastra/workflows/reasoning-engine/adapters/intake-adapter.ts)
Canonical Input SchemaContract for engine inputschemas/engine-input.schema.ts (src/mastra/workflows/reasoning-engine/schemas/engine-input.schema.ts)
Core Workflow7-step orchestration pipelinereasoning-engine.workflow.ts (src/mastra/workflows/reasoning-engine/reasoning-engine.workflow.ts)
Specialized Agents10 registered agents for orchestration, analysis, retrieval, validation, and optional outer-flow phrasingagents/reasoning-engine/ (src/mastra/agents/reasoning-engine/)
Canonical Output SchemaContract for engine outputschemas/engine-output.schema.ts (src/mastra/workflows/reasoning-engine/schemas/engine-output.schema.ts)
Output AdaptersTransform canonical output → target formatadapters/output-adapter.ts (src/mastra/workflows/reasoning-engine/adapters/output-adapter.ts)
FormattersTemplate-based output transformationformatters/ (src/mastra/tools/reasoning-engine/formatters/)

Compatibility Layers: The Adapter Pattern

Why Adapters?

The Reasoning Engine serves multiple applications with vastly different data formats:

  • Large JSON arrays with nested object structures
  • Structured API payloads with defined schemas
  • CSV/XML files from external systems
  • Custom formats with application-specific structures

Rather than embedding format-specific logic in the core engine, we use adapters at both ends of the pipeline:

Intake Adapter Interface

Intake adapters implement a simple contract:

interface IntakeAdapter {
id: string; // Unique identifier
name: string; // Human-readable name
description: string; // What formats it handles

// Auto-detection: Can this adapter handle the data?
canHandle(rawData: unknown): boolean;

// Transform raw data → canonical input
transform(intake: RawIntake): Promise<IntakeResult>;

// Optional: Validate before transformation
validate?(rawData: unknown): { valid: boolean; errors?: string[] };
}

Key Design Decisions:

  1. Auto-Detection — The canHandle() method enables automatic adapter selection. When multiple adapters are registered, the system tries each until one matches.

  2. Metadata Preservation — Adapters return IntakeMetadata alongside the canonical input, preserving context like date ranges, record counts, and detected formats for downstream use.

  3. Validation First — Optional validate() method provides detailed error messages before attempting transformation.

Canonical Input Schema

The canonical input is the "contract" between intake adapters and the core engine:

const reasoningEngineInputSchema = z.object({
// Required: What should the analysis accomplish?
objective: z.string().min(1),

// Data inputs (at least one required)
series: z.array(seriesSchema).optional(), // Time-series data
datasets: z.array(numericDatasetSchema).optional(), // Numeric arrays
compactedRows: z.array(z.record(z.any())).optional(), // Raw context

// Analysis guidance
hints: z.array(z.string()).optional(),
selectedNotes: z.array(selectedNoteSchema).optional(),
weeklySummaries: z.array(z.record(z.any())).optional(),

// Output configuration
outputProfile: z.string().optional().default('default'),

// Workflow metadata
taskId: z.string().optional(),
workflowRunId: z.string().optional(),
});

Output Adapter Interface

Output adapters transform canonical results into application-specific formats:

interface OutputAdapter<TOutput> {
id: string;
name: string;
description: string;
outputSchema: z.ZodType<TOutput>; // Zod schema for validation

// Transform canonical output → app format
transform(
output: ReasoningEngineOutput,
context?: OutputAdapterContext
): Promise<OutputResult<TOutput>>;

// Optional: Execute side effects (API calls, notifications)
execute?(result: OutputResult<TOutput>, context?: OutputAdapterContext): Promise<void>;
}

Rationale: Why This Architecture?

ConcernWithout AdaptersWith Adapters
Adding new data sourceModify core engineAdd new intake adapter
Adding new output formatModify core engineAdd new output adapter
Testing core logicNeed all format handlingTest with canonical mocks
Format-specific bugsDebug entire pipelineDebug isolated adapter
Business logic changesRisk format regressionsCore isolated from formats

The adapter pattern ensures the Reasoning Engine remains stable while applications can evolve independently.


Orchestration Pipeline

Step-by-Step Flow

The Reasoning Engine executes 7 sequential steps, each building on previous results:

Step Definitions

Step OrderStep IDPurposeAgent
0preflight-intakeValidate input and choose the step planStep Orchestrator Agent (optional)
1temporal-analysisAnalyze time-series trends and statisticsTemporal Agent
2pattern-recognitionDetect patterns in time-series dataPattern Agent
3correlation-analysisCompute pairwise correlationsAnalysis Agent
4domain-retrievalRetrieve domain knowledge through the domain retrieval toolQuery Generator Agent + Perplexity search when configured
5explanation-agentGenerate narrative from analysisExplanation Agent
6validation-agentVerify claims match data, assemble resultValidation Agent
note

Phrasing/tone adjustment is handled by the outer workflow (business logic layer), not by the reasoning engine. The reasoning engine produces structured analytical output; the outer workflow applies domain-specific phrasing.

State Management

The workflow uses a minimal state pattern to prevent JSON payload growth:

Key Behaviors:

  1. Each step reads prior outputs from the database — Not from the passed state object
  2. Each step returns only essential fields — TaskId, workflowRunId, objective, errors, and its own output
  3. Large payloads are stored separately — Via data_ReasoningEnginePayloads with reference IDs

This prevents the workflow state from ballooning as it passes through the workflow with potentially large datasets.


Agent Architecture

Agent Registry

Ten registered agents are available to the reasoning engine artifacts:

Agent Specifications

AgentRegistry IDResponsibility
Orchestratorreasoning-engine-orchestrator-agentLegacy/planning agent available in the artifact loader
Step Orchestratorreasoning-engine-step-orchestrator-agentChooses enabled workflow steps during preflight when orchestration is enabled
Temporalreasoning-engine-temporal-summary-agentAnalyzes time-series patterns and trends
Patternreasoning-engine-pattern-recognition-agentIdentifies behavioral patterns, trends, and volatility
Normalizerreasoning-engine-correlation-normalizer-agentPrepares data for correlation analysis
Analysisreasoning-engine-correlation-analysis-agentInterprets correlation findings
Query Generatorreasoning-engine-query-generator-agentGenerates focused Perplexity search queries from reasoning context
Domain Retrievalreasoning-engine-domain-retrieval-agentAvailable domain-knowledge agent; the committed domain step currently calls the domain retrieval tool
Explanationreasoning-engine-explanation-agentGenerates narratives from analysis
Validationreasoning-engine-validation-agentEnsures narrative consistency
Phrasing Helperreasoning-engine-phrasing-agentHelper agent for outer workflows; not a committed reasoningEngineWorkflow step

Agent-Enhanced vs Algorithmic Processing

Each step supports dual-mode processing:

  1. Algorithmic processing — Deterministic computation for reliable, reproducible results
  2. Agent enhancement — AI-powered insights layered on top of algorithmic results

Example from pattern recognition:

// Algorithmic detection always runs first
const detectedPatterns = [];
for (const stat of stats) {
if (stat.trend === 'increasing') {
detectedPatterns.push({
name: 'upward_trend',
series: stat.id,
detail: `${stat.id} is increasing...`
});
}
// ... more algorithmic patterns
}

// Agent enhancement (if available)
const agent = await getPatternAgent(mastra);
if (agent) {
const agentResponse = await callAgent(agent, {
features: stats,
detectedPatterns,
patternHints: hints,
objective,
});
// Merge agent insights with algorithmic results
}

Operational Configuration

Runtime inclusion

The Reasoning Engine is source-owned and optional. It joins the all target only when MASTRA_INCLUDE_REASONING_ENGINE=true; it is not a separate accepted MASTRA_TARGET value. Its loader returns 10 agents, the committed workflow, eight MCP-exposed tools, and the reasoning-engine MCP server with per-agent build resilience.

Environment Variables

VariablePurposeDefault
AZURE_SQL_SERVERSQL Server hostname(required for DB features)
AZURE_SQL_DATABASEDatabase name(required for DB features)
REASONING_SQL_LOGGINGEnable/disable SQL loggingAuto (enabled if SQL configured)
REASONING_ASSUME_TABLES_EXISTSkip table-existence fallback behavior in the step data service unless set to falsetrue
MASTRA_INCLUDE_REASONING_ENGINEInclude Reasoning Engine artifacts when the build target is allfalse

Feature Flags

// SQL logging control
const SQL_LOGGING_ENABLED = process.env.REASONING_SQL_LOGGING
? process.env.REASONING_SQL_LOGGING !== 'false'
: HAS_SQL_CONFIG;

// Step outputs are written through stepDataService to REASONING.data_WorkflowStepOutputs.
// Set REASONING_ASSUME_TABLES_EXIST=false only when local fallback creation/check behavior is needed.

Output Profiles

Control output formatting via the outputProfile input parameter:

ProfileDescriptionFormatter
defaultPassthrough (canonical format)passthroughOutputAdapter
dashboardDashboard-friendly formatdashboard-formatter
api-v1REST API response formatapi-v1-formatter
textPlain text summarydefaultTextOutputAdapter

Phrasing Control

The phrasing agent is registered for consumers that want a warmer tone in an outer workflow or application layer. The committed reasoningEngineWorkflow does not include a phrasing step; it ends at validation and optional output formatting.


Development & Testing

Code Locations

ComponentPath
Core Workflowreasoning-engine.workflow.ts (src/mastra/workflows/reasoning-engine/reasoning-engine.workflow.ts)
Adaptersadapters/ (src/mastra/workflows/reasoning-engine/adapters/)
Schemasschemas/ (src/mastra/workflows/reasoning-engine/schemas/)
Core Agentsagents/reasoning-engine/core/ (src/mastra/agents/reasoning-engine/core/)
Correlation Agentsagents/reasoning-engine/correlation/ (src/mastra/agents/reasoning-engine/correlation/)
Formattersformatters/ (src/mastra/tools/reasoning-engine/formatters/)
DB DDLMastra.Platform.ReasoningEngineDb/ (db/sqlproj/Mastra.Platform.ReasoningEngineDb/model/Tables/)

Running Locally

# Start the dev server
npm run dev

# Run the full reasoning chain against a sample payload
# (expects a JSON file; Recovered exports are a convenient starting point)
npx tsx scripts/reasoning-engine/run-full-chain.ts scripts/reasoning-engine/run-full-chain.example.json --skip-validation

# Verify database connectivity through the admin health tool
curl -X POST "$MASTRA_BASE_URL/admin/tools/db-health-check" \
-H "Content-Type: application/json" \
-d '{"data":{"schema":"REASONING"}}'

Debugging Tips

  1. Check step-by-step progress:

    SELECT StepName, Status, DurationMs, Message
    FROM REASONING.log_StepReasoningEngineTasks
    WHERE TaskId = @taskId ORDER BY StepOrder;
  2. View full step outputs:

    SELECT StepName, OutputJson
    FROM REASONING.data_WorkflowStepOutputs
    WHERE TaskId = @taskId;
  3. Find errors:

    SELECT StepName, ErrorType, Severity, Message
    FROM REASONING.log_Error
    WHERE TaskId = @taskId ORDER BY StepOrder;
  4. Console log prefixes:

    • [reasoning-engine:preflight] — Preflight step
    • [reasoning-engine:temporal] — Temporal analysis
    • [reasoning-engine:pattern] — Pattern recognition
    • [reasoning-engine:correlation] — Correlation analysis
    • [reasoning-engine:explanation] — Explanation generation
    • [reasoning-engine:validation] — Validation step

Troubleshooting

SymptomLikely CauseResolution
"objective is required"Empty or missing objective in inputEnsure intake adapter sets objective
Correlation step skippedLess than 2 numeric datasetsCheck dataset normalization in preflight
Agent not enhancing outputAgent not registered or unavailableVerify agent registry IDs match
DB logging not workingSQL env vars not setSet AZURE_SQL_SERVER and AZURE_SQL_DATABASE
Large payloads causing timeoutsInput is too large or unnecessary steps are runningPre-aggregate data and use stepPlan or step toggles to skip unnecessary work
Validation failingNarrative claims don't match dataReview explanation agent output

Next Steps