We’ve been busy tightening up the foundations around observability, storage, and type safety, plus a nice cost-saving improvement for long-running conversations. There are also a few targeted fixes that should smooth out real-world deployments.
Release: @mastra/core@1.13.0
We prepared automated codemods for most breaking changes. Run all v1 codemods at once:
1npx @mastra/codemod@latest v1See the migration guide for detailed instructions.
Let’s dive in:
Observability Storage Domain (schemas + in-memory implementations)
Mastra now ships a full “storage domain” for observability signals, including zod-based schemas with strong type inference and in-memory storage implementations for scores, logs, feedback, metrics, and discovery. There’s also a base ObservabilityStorage class that includes default method implementations, so you can implement only what you need and still get a usable storage layer.
This makes observability storage feel like a first-class system rather than a loose set of event types. You get consistent validation at boundaries, predictable shapes across packages, and fewer “stringly typed” integrations when you’re wiring exporters, query layers, or persistence.
If you’re building your own storage backend (Postgres, ClickHouse, etc.), the big win is having a canonical schema and a base class to extend, which reduces drift across signals over time.
New persistent Workspace filesystem: @mastra/agentfs
Workspaces are often where agents do real work: reading inputs, writing intermediate artifacts, and persisting outputs. The new AgentFSFilesystem provider gives you database-persistent file storage backed by Turso/SQLite via agentfs-sdk, so files can survive across sessions.
That persistence matters when you want agents that behave more like long-lived workers, for example:
- an agent that accumulates notes across multiple runs,
- tools that write cached results for later,
- multi-step workflows that resume after a restart.
Basic usage looks like this:
1import { Workspace } from "@mastra/core/workspace";
2import { AgentFSFilesystem } from "@mastra/agentfs";
3
4const workspace = new Workspace({
5 filesystem: new AgentFSFilesystem({
6 agentId: "my-agent"
7 })
8});Observability pipeline upgrades: renamed types + EventBuffer batching
The observability packages were updated to align with renamed observability types from @mastra/core, and the event pipeline gained an EventBuffer for batching non-tracing signals with a configurable flush interval.
If you emit lots of logs, feedback events, scores, or metrics-like signals, sending them one-by-one can add overhead and increase the chances of backpressure. Batching lets you trade a small amount of latency for fewer network calls and smoother throughput, which is especially helpful in high-volume agent systems.
These changes also reduce confusion when moving between core and exporters, because the types now match across packages rather than requiring mental (or type-level) translation.
Type-safe server route inference via @mastra/server/schemas
@mastra/server now exports @mastra/server/schemas, a set of utility types that infer path params, query params, request bodies, and response types directly from SERVER_ROUTES. Routes added via createRoute() automatically show up in the type map, so you don’t need to manually maintain a separate contract file.
This is a big quality-of-life upgrade for anyone building clients, typed fetch wrappers, SDKs, or internal tooling that needs to stay in sync with server routes. You can refactor server routes and have your TypeScript consumers fail loudly and correctly, instead of silently drifting.
Example:
1import type { RouteMap, InferPathParams, InferBody, InferResponse } from "@mastra/server/schemas";
2
3type GetAgentParams = InferPathParams<RouteMap["GET /agents/:agentId"]>;
4// => { agentId: string }
5
6type GenerateBody = InferBody<RouteMap["POST /agents/:agentId/generate"]>;
7// => { messages: CoreMessage[], ... }
8
9type AgentResponse = InferResponse<RouteMap["GET /agents/:agentId"]>;
10// => { name: string, tools: ..., ... }Lower token costs for long-running Observational Memory
Observational Memory now supports observation.previousObserverTokens, which lets you cap the token budget used for the “Previous Observations” context shown to the Observer.
In long-running threads, the Observer context can grow steadily and start dominating your prompt size. By truncating to a budget (keeping the most recent observations and swapping already-reflected lines with the buffered reflection summary), you can keep the Observer effective without paying escalating token costs.
Configuration example:
1const memory = new Memory({
2 options: {
3 observationalMemory: {
4 model: "google/gemini-2.5-flash",
5 observation: {
6 previousObserverTokens: 10_000
7 }
8 }
9 }
10});Behavior details:
previousObserverTokensdefaults to2000- set to
0to omit previous observations entirely - set to
falseto disable truncation and keep full history
Breaking Changes
MetricType deprecated (metrics are now raw events) (PR #14214): MetricType values like counter/gauge/histogram are deprecated. Metrics should be treated as raw events, and aggregation happens at query time. To migrate, stop relying on MetricType to define aggregation semantics at write time, and update any downstream code to aggregate when reading/querying instead.
Score schemas use scorerId instead of scorerName (PR #14214): scoring identifiers now use scorerId. If you were persisting or matching on scorerName, rename that field and update any filters, joins, or UI labels accordingly.
1// Before
2const score = {
3 scorerName: "toxicity-v1"
4 // ...
5};
6
7// After
8const score = {
9 scorerId: "toxicity-v1"
10 // ...
11};ObservabilityBus constructor now takes a config object (PR #14214): ObservabilityBus now takes { cardinalityFilter, autoExtractMetrics } in its constructor. The instance methods .setCardinalityFilter() and .enableAutoExtractedMetrics() were removed. To migrate, pass the configuration at creation time instead of mutating after.
1// Before (conceptual)
2const bus = new ObservabilityBus();
3bus.setCardinalityFilter(myFilter);
4bus.enableAutoExtractedMetrics();
5
6// After (conceptual)
7const bus = new ObservabilityBus({
8 cardinalityFilter: myFilter,
9 autoExtractMetrics: true
10});Other Notable Updates
- Provider registry and docs refreshed: Updated provider registry and model documentation with the latest models and providers (PR ea86967)
- Provider tools through custom gateways: Fixed provider tools (for example
openai.tools.webSearch()) being dropped when routing through a custom gateway that returns AI SDK v6 (V3) models, tool types are now remapped so provider tools continue to work correctly (fixes #13667) (PR #13895) - AI SDK compatibility type fixes: Resolved TypeScript errors in
onStepFinishandonFinish, plus compatibility issues withcreateOpenRouter()across AI SDK versions (PR #14229) - Thread metadata preservation: Fixed a bug where thread metadata passed via
options.memory.threadwas discarded whenMASTRA_THREAD_ID_KEYwas present in request context, thread ID from context still wins, but other metadata is preserved (PR #13146) - Workspace tools reliability: Fixed
mastra_workspace_list_filesandmastra_workspace_read_filefailing withWorkspaceNotAvailableErrorin some execution paths (PR #14228) - Server OpenAPI correctness for custom routes: Fixed OpenAPI spec so routes registered via
registerApiRouteappear at the correct root path (for example/health, not under/api) (PR #13930) - Smaller @mastra/server install footprint: Removed an unnecessary runtime dependency by moving
@mastra/schema-compatto devDependencies (PR #14223) - Deployer security update: Bumped esbuild to address Go stdlib CVEs flagged by npm audit (CVE-2025-22871, CVE-2025-61729) (PR #13124)
- Bundler dynamicPackages config: Added
bundler.dynamicPackagesfor runtime-loaded packages and auto-detection for pino transports (fixes #10893) (PR #11779) - MCP pnpm workspace TS fix: Fixed TypeScript compilation errors when using MCP resource methods in pnpm workspaces (PR #14229)
That’s all for @mastra/core@1.13.0!
Happy building! 🚀
