Docs / Integrations / Mastra
Mastra
Mesedi ships as a first-class Mastra observability exporter. Wire a MesediExporter into your Observability config and every agent run, workflow run, LLM call, and tool call flows into Mesedi. No changes to your agent code; no wrap() call required.
Install
npm install mesedi@^0.6 @mastra/core @mastra/observabilityMesedi's adapter treats @mastra/core and @mastra/observability as optional peer dependencies. If you never import mesedi/integrations/mastra, neither library is loaded and there is no install cost for non-Mastra customers.
Wire it up
import { configure } from "mesedi";
import { MesediExporter } from "mesedi/integrations/mastra";
import { Mastra } from "@mastra/core";
import { Observability } from "@mastra/observability";
// Configure Mesedi once (usually at app startup).
configure({ apiKey: process.env.MESEDI_API_KEY });
// Attach the exporter to Mastra's Observability instance.
// Mastra 1.x requires the `configs` shape below; the pre-1.x
// `exporters: {...}` root shape is silently ignored.
const mastra = new Mastra({
observability: new Observability({
configs: {
mesedi: {
serviceName: "my-app",
exporters: [new MesediExporter()],
sampling: { type: "always" },
},
},
}),
// ...your agents / workflows
});That's the whole surface. Every subsequent agent.generate(...) or workflow execution opens a Mesedi failure_group scope on the root span and forwards child spans as events. Cross-cutting Mesedi features (per- project detector thresholds, custom security patterns, hard-halt budgets) all keep working through Mastra runs without any additional wiring.
Optional: tenant attribution
new MesediExporter({ tenantId: "acme-corp" });Attach a tenant identifier to every execution the exporter opens. Surfaces on the dashboard's cost-by-tenant report and enables provider_incident's cross-tenant clustering. Absent means "unattributed."
Span-to-event mapping
Mastra emits an OTel-shaped span for every operation. The exporter translates each span type into the corresponding Mesedi event on span-end.
| Mastra span | Mesedi event | Notes |
|---|---|---|
AGENT_RUN | Opens execution + checkpoint enter/exit | Root span. Also emits execution end with status. |
WORKFLOW_RUN | Opens execution + checkpoint enter/exit | Same treatment as AGENT_RUN. |
MODEL_GENERATION | llm_call | Extracts model, provider, and token counts from attributes. |
TOOL_CALL / CLIENT_TOOL_CALL | tool_call | Tool name, input, output. Errors → status = "error". |
MCP_TOOL_CALL | mcp_call | Separate event type to keep MCP failure attribution clean. |
WORKFLOW_STEP | checkpoint | Step name lands on the checkpoint payload. |
Detector coverage
All 20 Mesedi failure-class detectors fire when driven through this adapter. Nine are native: the exporter's span-to-event mapping above feeds them directly, no changes to your Mastra code. Eleven are hybrid: you call an SDK emit helper inside the same code path where Mastra runs, and the detector picks up the shape it needs. The Mastra integration harness exercises all 20 end-to-end against a real backend.
| Detector | Mode | Fires via |
|---|---|---|
loops | Native | MODEL_GENERATION + WORKFLOW_STEP spans (identical_call, similar_call, step_count) |
tool_failures | Native | TOOL_CALL span with errorInfo |
drift | Native | MODEL_GENERATION user_message divergence |
cost_velocity | Native | MODEL_GENERATIONtoken counts + provider pricing (wrap the loop in a workflow so it's one execution) |
prompt_injection | Native | MODEL_GENERATION user_message pattern match |
data_leakage | Native | MODEL_GENERATION user_message DLP match |
semantic_loop | Native | WORKFLOW_STEP metadata equality across 3+ steps in one workflow_run |
context_overflow | Native | MODEL_GENERATION prompt-size vs model window |
token_waste | Native | MODEL_GENERATION shared prefix across 3+ user_messages |
crashes | Hybrid | throw inside wrap() — same pattern every SDK language uses |
validator_failures | Hybrid | Call validatorResult() after your schema check |
infrastructure_throttled | Hybrid | Call emitInfrastructureEvent() when you observe a rate-limit / retry |
tool_schema_drift | Hybrid | Wrap the tool with tool() — structured return_value fingerprints the shape |
sandbox_escape | Hybrid | Wrap the tool with tool() — arguments match the dangerous-call regex directly |
grounding_failure | Hybrid | Call emitEvalScore() with your RAG / faithfulness score |
cascading_failure | Hybrid | Call emitAgentHandoff() to a child execution |
coordination_deadlock | Hybrid | Call emitAgentHandoff()— Tarjan's SCC catches the cycle |
provider_incident | Hybrid | Emit a failed llm_call event with error_class="timeout" / "rate_limited" when your provider client throws |
hitl_timeout | Hybrid | requestHumanIntervention() + completeHumanIntervention() with timeout kind |
hitl_rejection_spike | Hybrid | Repeated validatorResult() with human_verdict=rejected over a window |
Hybrid rows use exactly the same SDK helpers you'd call from any Mesedi integration (or from plain wrap()-only code). The Mastra exporter and the helpers coexist in one execution — no double-counting, no setup order dependency.
Execution status
errorattribute set on the root span → execution statuscrashed.tripwireAbortattribute set (Mastra processor tripwire fired) → execution statushalted.- Otherwise → execution status
completed.
Current limitations
- RAG spans (
RAG_INGESTION,RAG_EMBEDDING,RAG_VECTOR_OPERATION,RAG_ACTION) are not currently mapped. They flow through the exporter as no-ops. - Memory + workspace spans (
MEMORY_OPERATION,WORKSPACE_ACTION) are not currently mapped. - Scorer spans (
SCORER_RUN,SCORER_STEP) are not consumed — Mesedi runs its own AI root-cause analysis downstream. - Finer-grained model spans (
MODEL_STEP,MODEL_INFERENCE,MODEL_CHUNK) are intentionally ignored.MODEL_GENERATIONis the aggregating span for a full model call; the finer spans would duplicate the same event to Mesedi's detectors. - Multi-agent handoff detection emits
checkpointevents rather than dedicatedagent_handoffevents. Mastra's workflow step topology doesn't map cleanly onto Mesedi's handoff shape without ambiguity.
Related
- TypeScript SDK reference —
configure(),wrap(),tool(), and the other framework adapters. - provider_incident — set
tenantIdon the exporter to feed cross-tenant clustering. - Mastra AI tracing docs — how Mastra's
Observabilityconfig works.