Highlights
Observability Capabilities Negotiation (Storage ↔ Server ↔ Client)
Servers now expose observabilityStorageCapabilities (via GET /system/packages and the new GET /observability/capabilities) so Studio/clients can detect which observability APIs a configured store actually supports—covering per-endpoint discovery flags plus traceQuery, threadQuery, deltaPolling, and more—without forcing storage upgrades.
Discovery-Backed Observability Filters & Feature Declarations
Observability stores can now declare supported features via getFeatures() (including entity/service/environment/tag/metric discovery), letting Studio only call compatible endpoints; VNext stores and Oracle now report discovery support, and discovery routes return empty results (not 500s) when unsupported.
Trace Aggregation Planning API for Backends
planTraceAggregate() validates and converts an aggregateTraces() request into a TrustedTraceAggregatePlan that any storage backend can execute without re-validating, enabling consistent query behavior and clearer validation errors across storage implementations.
Eager Tool Execution for Faster Streaming Runs
Tool calls now start as soon as their own arguments are complete (instead of waiting for the model to finish streaming the whole step), cutting idle time in multi-tool steps; can be disabled per run (and is now supported in stored agent default options).
New Integrations: Discord Channel + Sandbox Credential Materialization
Added @mastra/discord to connect agents to Discord (slash commands, DMs, mentions, encrypted token-at-rest), and @mastra/connect environment() to materialize Platform connection credentials into { env, onStart } for authenticated tooling inside sandbox providers (e2b/Modal/Daytona/Docker/subprocess).
MongoDB Vector “Automated Embeddings” (Server-Side Embedding Generation)
MongoDBVector now supports Automated Embeddings: create an autoEmbed index (e.g. Voyage) and then write plain text + search with queryText, with MongoDB generating embeddings server-side (no embedding provider wiring or dimension bookkeeping in your app).
Breaking Changes
@mastra/playground-uiTaskListAPI:title,TaskListHeader, andhideWhenEmptyare removed.
Changelog
@mastra/core@1.71.0
Minor Changes
-
Added per-endpoint discovery features that observability storage can declare from
getFeatures():entity-type-discovery,entity-name-discovery,service-name-discovery,environment-discovery,tag-discoveryandmetric-discovery. The in-memory observability store now declaresmetrics,logsand discovery support. (#25008)Custom observability stores can declare what they support so Studio only calls those APIs:
import { ObservabilityStorage } from '@mastra/core/storage'; class MyObservabilityStore extends ObservabilityStorage { override getFeatures() { return ['logs', 'entity-name-discovery', 'tag-discovery'] as const; } }
-
Added
planTraceAggregate(). It checks a parsedaggregateTraces()request and returns aTrustedTraceAggregatePlanthat any storage backend can execute without re-validating the request. (#24868)import { parseTraceAggregateRequest, planTraceAggregate } from '@mastra/core/storage'; const plan = planTraceAggregate(parseTraceAggregateRequest(request), { scope: { organizationId: 'org_123' }, }); // plan.dimensions, plan.measures, plan.having, plan.orderBy, plan.limit, plan.where
Validation rules
timeRangeandwhereare validated exactly likequeryTraces().groupByaccepts only supported dimensions.countDistinctacceptstraceIdor any field thatgroupByaccepts.havingcan reference a requested measure orcount.orderBycan reference a requested measure, a requested dimension, orcount.bucketis not an ordering target.- The time range can be at most 365 days.
- An
intervalcan touch at most 1000 UTC-aligned buckets, andlimit × bucketscan be at most 10,000 rows.
having,orderBy, andlimitapply to groups using measures computed over the whole time range; with aninterval, each returned group is a complete series in bucket order. The plan's JSDoc spells this out for backends.Invalid requests throw
TraceQueryValidationErrorwith the same issue codes and JSON paths asplanTraceQuery(). The newtoo_many_bucketscode names the smallest permitted interval;too_many_rowsasks the caller to lowerlimitor wideninterval.
Patch Changes
-
Update provider registry and model documentation with latest models and providers (
fc7d2c1) -
Tools now start as soon as their own arguments are complete, instead of waiting for the model to finish streaming the whole step. This is on by default and removes seconds of idle time from steps that call several tools. (#25005)
// Default: each tool starts as soon as its call is complete. const eager = await agent.stream('Compare the weather in Paris and Rome'); // Opt out to restore the previous scheduling. const deferred = await agent.stream('Compare the weather in Paris and Rome', { eagerToolExecution: false, });
These calls still wait for the model to finish: tools that need approval, declare a suspend schema, run on the provider or client, or run in the background, and runs that use the
calledconcurrency strategy or output processors that run after the stream. A tool that already finished is never run again and its result is always kept, including on retry, fallback, and abort.A tool still running when an attempt is retried, falls back, or is aborted finishes first, and its result is kept.
A tool that calls
suspend()at runtime also runs once: the run suspends instead of retrying the model. See thestream()reference for the full rules. -
Added a
feedbackobservability storage feature so clients can identify whether a store supports the feedback APIs. Storage adapters that implement the feedback methods declare the feature to advertise support. (#25020)import { ObservabilityStorage } from '@mastra/core/storage'; class MyObservabilityStore extends ObservabilityStorage { public getFeatures() { return ['feedback'] as const; } }
-
Fixed the Workspace example to use current providers and distinguish local paths from cloud mount paths. (#24988)
-
Fixed a denial-of-service risk in dataset schema validation. Regex
patternandpatternPropertiesin dataset input and ground truth schemas now run on a linear-time (RE2) engine, so a crafted pattern can no longer freeze the server. Fixes #24981. (#25044)Behavior changes
- Patterns using syntax RE2 cannot run, such as lookarounds (
(?=...),(?<!...)) and backreferences (\1), are rejected with aDATASET_SCHEMA_PATTERN_UNSUPPORTEDerror when the dataset is created or its schema is updated. Escapes such as\uXXXXand\cXkeep working. - Matching is Unicode-aware:
.matches a whole code point (so^.$matches😀), and\p{L}is a Unicode class even without theuflag.
To migrate, rewrite affected patterns without lookarounds or backreferences, for example replace
pattern: '^(?=.*\\d).+$'withpattern: '\\d', then update the dataset schema. - Patterns using syntax RE2 cannot run, such as lookarounds (
@mastra/ai-sdk@1.10.5
Patch Changes
- Fixed v7 helpers (
handleChatStream,chatRoute,toAISdkStream,toAISdkMessageswithversion: 'v7') rejectingUIMessagevalues fromai@7.0.103and later. These versions typeproviderMetadatawith readonly JSON values, which the bundled v7 types did not accept. You no longer need to stay onai@7.0.102or cast messages. (#24931)
@mastra/auth-google@0.1.5
Patch Changes
- Fixed Google SSO users being signed out after about an hour. Sessions now last for the configured
session.cookieMaxAge(24 hours by default) instead of expiring with the short-lived Google ID token. (#25043)
@mastra/clickhouse@1.21.1
Patch Changes
-
Fixed slow feedback review-status updates on ClickHouse. Since 1.21.0, each update ran a ClickHouse mutation that scanned every part of the feedback table, taking several seconds on tables with months of daily partitions and timing out on larger ones. Review updates now write a new row again, which takes milliseconds regardless of table size. (#25000)
Upgrade note: the runtime database user no longer needs
ALTER UPDATE(reviewStatus)onmastra_feedback_eventsorINSERTonmastra_feedback_events_deltafor review updates. Grants you added for 1.21.0 are harmless. KeepALTER UPDATEif you run ClickHouse 26.6 or earlier, because lightweight deletes still need it there.Deleted feedback still can't reappear through a review update: an update that lands during a delete of the same feedback retries the delete and reports the feedback as not found. A failed delete no longer blocks review updates: the next update saves the new status, then retries the delete and reports its error if it fails again. If a network error or a lagging replica lets a review row outlive a successful delete, the next review update of that feedback removes it.
-
Declared feedback support in the observability store so servers report the
feedbackcapability as available to clients. (#25020)// With one of these stores configured as the observability storage: const { capabilities } = await client.getObservabilityCapabilities(); console.log(capabilities.feedback); // true
Also in: @mastra/duckdb@1.11.1, @mastra/pg@1.27.1
-
The observability stores used by
PostgresStoreVNext,ClickhouseStoreVNextandDuckDBStorenow declare their filter discovery support, so Studio can show discovery-backed filters based on what the store reports. (#25008)const { capabilities } = await client.getObservabilityCapabilities(); capabilities.discovery; // { entityTypes: true, entityNames: true, serviceNames: true, environments: true, tags: true, metrics: true }
Also in: @mastra/duckdb@1.11.1, @mastra/pg@1.27.1
@mastra/client-js@1.50.0
Minor Changes
-
Added
getObservabilityCapabilities(), which returns the optional observability features the server's configured storage supports. (#25008)const { observabilityStorageType, capabilities } = await client.getObservabilityCapabilities(); if (!capabilities.traceQuery) { // List traces with the legacy endpoint instead const traces = await client.listTracesLight({ pagination: { page: 0, perPage: 25 } }); }
Patch Changes
-
Stopped retrying requests that fail with 501 Not Implemented. The server returns 501 when the configured storage does not support an API, so retrying only added repeated failed requests and server error logs. (#25008)
-
Added a
feedbackflag to the observability capabilities response so you can check whether the configured store supports the feedback endpoints before calling them. (#25020)const { capabilities } = await client.getObservabilityCapabilities(); if (capabilities.feedback) { const feedback = await client.listFeedback({ traceId }); }
@mastra/code-sdk@1.8.3
Patch Changes
-
Stagehand model selection now follows your chat setup instead of a hardcoded fallback. (#25028)
- Added
resolveStagehandModel()to report which model Stagehand will use and why. It resolves, in order:browser.stagehand.model(settings), the chat model captured at browser launch when Stagehand can route it (chat-model), the OpenAI Codex default model when you are signed in with Codex (codex-oauth), then Stagehand's own default (stagehand-default). - Any
openai/*model, configured or inferred, now goes through the Codex endpoint when your OpenAI login is Codex OAuth, with the same-codexmodel-id remaps the chat agents apply. Codex-only users no longer need a separateOPENAI_API_KEYfor browser automation. - Dotted Anthropic ids such as
anthropic/claude-opus-4.6are normalized before being handed to Stagehand, matching the chat agents. - Fixed the Browserbase API key being saved in session state; the active-browser snapshot is now credential-free and records which model the browser launched with.
import { resolveStagehandModel } from '@mastra/code-sdk/onboarding/settings'; const { modelName, source, viaCodexOAuth } = resolveStagehandModel(settings.browser, { chatModelId: session.model.get(), }); // e.g. { modelName: 'anthropic/claude-sonnet-4-5', source: 'chat-model', viaCodexOAuth: false }
- Added
@mastra/connect@0.4.0
Minor Changes
-
Add
environment()for sandboxed agents. Materialize provider credentials from your project's Platform connections into a{ env, onStart }pair that any sandbox provider (e2b, Modal, Daytona, Docker, subprocess) can consume — so CLI tooling inside the sandbox is authenticated without hand-wiring tokens per agent. (#24912)import { environment } from '@mastra/connect'; const env = environment({ projectId: process.env.MASTRA_PROJECT_ID, client: { accessToken: process.env.MASTRA_PLATFORM_ACCESS_TOKEN }, }); const { env: envVars, onStart } = await env(); await sandbox.start({ env: envVars, onStart });
environment()shares its resolution model withconnect(): sameprojectId,client, and per-providerintegrationsoverrides (connectionIdto pin,disabled: trueto exclude). GitHub is the first provider with an env contributor — its OAuth token is exported asGH_TOKEN/GITHUB_TOKENso bothghandgitHTTPS authenticate as the connected user, andonStartinstalls a git credential helper that reads the token from the environment rather than baking it into git config.
@mastra/discord@1.1.0
Minor Changes
-
Added
@mastra/discordfor connecting Mastra agents to Discord. One Discord app serves many servers, and agents respond to slash commands, DMs, and @mentions. SetencryptionKeyorMASTRA_ENCRYPTION_KEYto encrypt the stored bot token at rest. (#25002)import { Mastra } from '@mastra/core'; import { DiscordProvider } from '@mastra/discord'; // App credentials from the Discord Developer Portal (or the DISCORD_BOT_TOKEN / // DISCORD_PUBLIC_KEY / DISCORD_APPLICATION_ID env vars): const discord = new DiscordProvider({ app: { botToken: process.env.DISCORD_BOT_TOKEN!, publicKey: process.env.DISCORD_PUBLIC_KEY!, applicationId: process.env.DISCORD_APPLICATION_ID!, }, }); export const mastra = new Mastra({ agents: { support }, channels: { discord }, }); // Bind an agent. If the bot is already in DISCORD_GUILD_ID, this binds the // agent to that guild and registers its slash commands immediately. Otherwise // it returns an OAuth2 bot-invite URL and the install stays pending until the // bot joins a guild — the first interaction from that guild activates it. const result = await discord.connect('support', { guildId: process.env.DISCORD_GUILD_ID }); // → { type: 'immediate' } OR { type: 'oauth', authorizationUrl, installationId }
@mastra/duckdb@1.11.1
Patch Changes
-
Fixed completed event spans appearing to still be running, including event spans stored before this fix. Event spans now report an end time equal to their start time, matching the ClickHouse and PostgreSQL stores. (#24970)
-
Fixed
listTraces,listTracesLightandlistBrancheson@mastra/duckdbso each trace and branch is counted once. Every ended span is stored with two start rows, and the fast path and delta polling counted both.pagination.totalwas double the real number, each page returned about half ofperPage, a trace could show on two pages, and delta polls returned every trace twice. Fixes #24919 (#24932)
@mastra/elysia@0.1.11
Patch Changes
-
Handler errors with status 501 Not Implemented are now logged as warnings instead of errors. A 501 means the configured storage does not support an optional feature, not a server failure. (#25008)
Also in: @mastra/express@1.5.15, @mastra/fastify@1.5.15, @mastra/hono@1.7.13, @mastra/koa@1.7.15
@mastra/evals@1.10.3
Patch Changes
- Fixed faithfulness and hallucination scorers returning inflated scores when the judge model returned fewer verdicts than extracted claims. Scores are now divided by the number of claims, so claims without a verdict are no longer silently dropped. Verdicts are also matched case-insensitively, so
"Yes"is counted the same as"yes". (#25039)
@mastra/express@1.5.15
Patch Changes
-
Fixed refreshed session cookies being lost in the standalone
createAuthMiddlewarefor Express, Fastify, Hono, and Koa. Browsers now receive the refreshedSet-Cookieon both allowed and denied requests. Fixes #24963. (#25024)Also in: @mastra/fastify@1.5.15, @mastra/hono@1.7.13, @mastra/koa@1.7.15
@mastra/factory@0.17.2
Patch Changes
-
Check missing external issues again after 24 hours to reduce repeated requests (#24973)
-
Keep integration arrivals in Intake until someone starts them. (#24983)
Before: trusted issue and pull request arrivals could create triage or review proposals, and unbound Linear, Jira, and incident.io cards landed in Triage. After: integrations stay in the routed board's initial phase without starting or suggesting a run (except explicit trusted review requests, which land directly in Reviewing). To restore automatic arrival triage, configure a custom board's initial-phase handler:
import { MastraFactory } from '@mastra/factory'; import type { MastraFactoryConfig } from '@mastra/factory'; import { defineBoard } from '@mastra/factory/boards'; const customWorkBoard = defineBoard({ id: 'custom-work', title: 'Custom Work', initialPhase: 'intake', phases: { intake: { title: 'Intake', kind: 'resting', onEnter: { issue: context => context.cause === 'linked_item_materialized' && context.item.metadata?.autoStartCandidate === true ? { type: 'invokeSkill', idempotencyKey: `${context.ingress.id}:factory-triage`, role: 'triage', skillName: 'factory-triage', } : undefined, }, }, triage: { title: 'Triage', kind: 'working', role: 'triage' }, }, }); export function createFactory(storage: MastraFactoryConfig['storage']) { return new MastraFactory({ storage, boards: [customWorkBoard] }); }
@mastra/fastembed@1.3.2
Patch Changes
- Built-in FastEmbed models now download from Hugging Face (Qdrant organization) instead of the legacy Qdrant Google Cloud Storage bucket, which is being shut down. Existing local model caches keep working. (#25026)
@mastra/koa@1.7.15
Patch Changes
- Fixed duplicate
console.erroroutput for handler errors with status 501 Not Implemented on Koa. Customapp.on('error')listeners still receive these errors. (#25015)
@mastra/libsql@1.23.3
Patch Changes
- Fixed
createin LibSQL skills storage to includevisibilityin the returned skill. (#25031)
@mastra/mcp-docs-server@1.3.1
Patch Changes
- Fixed embedded documentation tools to reject empty and relative project paths with clear validation errors. (#24969)
@mastra/memory@1.32.1
Patch Changes
- Fixed Observational Memory saving working memory that does not match your configured
workingMemory.schema. Whenobservation.manageWorkingMemoryis enabled, the observer now checks each working memory update against the schema before saving it. An update with values outside an allowed list, wrong types, missing required fields, or disallowed extra fields is skipped, and the previous working memory is kept. Anullin a field the schema marks optional is treated as not provided, the same as with the working memory tool. Returningnullstill leaves working memory unchanged. Fixes #24240. (#24926)
@mastra/mongodb@1.19.0
Minor Changes
-
Added Automated Embedding support to
MongoDBVector. Create an index withautoEmbedand a Voyage AI model such asvoyage-4, then write plain text throughdocumentsand search withqueryText. MongoDB generates the embeddings server-side, so your application needs no embedding provider, no model wiring, and no dimension bookkeeping. (#24383)await store.createIndex({ indexName: 'movies', autoEmbed: { model: 'voyage-4' } }); await store.upsert({ indexName: 'movies', documents: ['A lonely astronaut adrift near Saturn.'] }); const results = await store.query({ indexName: 'movies', queryText: 'space opera', topK: 5 });
hybridQueryacceptsqueryTextfor its vector branch, and both query methods take an optionalmodelto override the index's model for a single search. Indexes that supply their own vectors keep working exactly as before.Automated Embedding is a MongoDB Preview feature. It requires an Atlas cluster with Automated Embedding enabled, or the
mongodb/mongodb-atlas-local:previewimage locally.
@mastra/mysql@0.10.2
Patch Changes
- Fixed skill
visibilitynot being persisted by MySQL storage, so skills markedpublicare now readable by other users and returned bylist({ visibility: 'public' }). (#25031)
@mastra/nestjs@0.2.30
Patch Changes
- Fixed
@mastra/nestjsto run the same auth pipeline as the other server adapters. Cookie-based sessions now authenticate, custom routes registered withregisterApiRoute()are served (honoringrequiresAuth), andmapUserToResourceIdis applied to the request context. Fixes #24964. (#25027)
@mastra/observability@1.18.1
Patch Changes
- Fixed event spans (such as
model_chunkspans fortool-resultandtool-call-approvalchunks) being stored and exported withendedAt: nullin completed runs, which made them look like they were still running. Event spans are point-in-time, so they now end at the instant they start:endTimeequalsstartTimeand their duration is zero. Event spans no longer emit duration metrics. Fixes #24233. (#24970)
@mastra/oracledb@0.4.1
Patch Changes
-
The Oracle observability store now declares its logs and filter discovery support (entity types, entity names, service names, environments and tags), so Studio can show the matching filters. (#25008)
const { capabilities } = await client.getObservabilityCapabilities(); capabilities.logs; // true capabilities.discovery.entityNames; // true
@mastra/otel-bridge@1.5.11
Patch Changes
- Fixed
OtelBridgesilently exporting nothing when no OpenTelemetry tracer provider is available. The bridge now logs one clear warning that explains how to register a tracer provider or pass one withnew OtelBridge({ tracerProvider }), and links to the setup docs. It no longer logs a warning for every span. Mastra spans also no longer reuse an outer span's ID when that outer span comes from a tracer provider that isn't registered. Fixes #24950. (#24986)
@mastra/pg@1.27.1
Patch Changes
- Fixed
PostgresStoreandPgVectorrejecting schema names that are only valid when quoted, such asmy-tenant. Any schema name up to 63 bytes is now accepted, as long as it has no quotes, backslashes,$, or control characters. Index and constraint names built from the schema use a sanitized prefix (my-tenantbecomesmy_tenant_...), so existing schemas keep their current index and constraint names. (#25045)
@mastra/playground-ui@59.0.0
Minor Changes
-
Added
InlineCodefor code inside a sentence, and documented when to use monospace text. (#25012)Code is always marked as code:
InlineCodein running text, and a highlightedCodeBlockfor anything longer.Txt font="mono"is for machine identifiers such as model IDs, hashes, and log lines, and for timestamps and durations. Other numbers, such as counts and costs, stay in the body face withtabular-nums. It keeps the role's size, line height, and weight and changes only the typeface.DataList.NumberCelltakesfont="mono"for duration columns, and trace and workflow durations now render in mono. KPI values and chart axes stay in the body face.import { InlineCode } from '@mastra/playground-ui/components/InlineCode'; import { Txt } from '@mastra/playground-ui/components/Txt'; <Txt variant="body-sm" tone="muted"> Set <InlineCode>OPENAI_API_KEY</InlineCode> to use this model. </Txt> <Txt variant="caption" font="mono" tone="muted"> run_01JQX8K2M4 </Txt>
Txtnow acceptsfont="body", the default, alongsidefont="mono". Set--font-monoin your own CSS to use a different monospace typeface. Set--font-mono-size-adjustto the body face's x-height ratio, such asex-height 0.508, so mono text looks the same size as the text around it. -
Added
requiredanderrorMsgtoSettingsRow. A required row shows the same asterisk as a form field label, and an error message appears under the label as an alert the control can reference. (#24980)<SettingsRow label="Model" htmlFor="model" required errorMsg="Choose the model this agent runs on."> <Input id="model" error aria-describedby={fieldErrorId('model')} /> </SettingsRow>
-
Added
RelativeTimestamp, which shows a compact relative time such as3m agoorin 2hin monospace. Hover or focus shows a card with the time since, counting up live, and the date and time in your timezone and in UTC. Studio schedules, trigger history, and workflow run headers now use it. (#25001)import { RelativeTimestamp } from '@mastra/playground-ui/components/RelativeTimestamp'; <RelativeTimestamp value={run.createdAt} />;
-
Added
CompactNumber, which shows a compact metric such as12.3Kor$1.2Kand reveals the full value (12,310) in a tooltip on hover or focus. The compact value can hide digits ($123.45shows as$123), and the full value in the tooltip keeps the currency's precision. An amount smaller than the currency's smallest unit shows as<$0.01, and a unit that isn't a currency, such ascredits, shows as a plain number. (#24979)import { CompactNumber } from '@mastra/playground-ui/components/CompactNumber'; <CompactNumber value={12310} /> <CompactNumber value={12345.67} currency="USD" />
The number and cost formatters now live in one place,
@mastra/playground-ui/utils/cost.formatCompactis renamed toformatCompactNumber, andformatCompactandformatCostare no longer exported from the metrics components.// Before import { formatCompact, formatCost } from '@mastra/playground-ui/domains/metrics/components'; // After import { formatCompactNumber, formatCost, formatFullNumber } from '@mastra/playground-ui/utils/cost';
-
Status dots use one circular shape.
StatusDotandStatusnow draw every state as a circle. Meaning comes from color plus a filled or ring treatment. Thesquareanddashedglyphs and the blueidletone are removed. (#24960)Canonical deploy states.
deployStatesexports the six deploy and server states: Ready, Building, Idle, Queued, Stopped, and Error. Idle and Queued are gray rings, Stopped is a gray filled dot.// Before { label: 'Stopped', tone: 'neutral', glyph: 'square', description } { label: 'Idle', tone: 'idle', description } // After { ...deployStates.stopped, description } { ...deployStates.idle, description } // { tone: 'neutral', glyph: 'ring' }
Status labels inherit text style. The label now always takes the size and color of its container, so it matches the other cells in a
DataListwithout a wrapper. Thechildrenslot is removed; style the container instead.// Before <Status presentation={presentation}> <Txt as="span" variant="body-sm">{presentation.label}</Txt> </Status> // After <Status presentation={presentation} />
-
TaskListno longer shows a spinner for the task in progress, which read as something loading. The active task now steps out onto its own lane of a small graph drawn beside the list, and its label fades into a warm gradient. A completed task's strike draws in from the left and erases cleanly if the task reopens. Every change between states is animated, and nothing moves when reduced motion is on. (#24947)Collapsed, the list is a one-row window on the current task, with the progress bars beside it. Expanding grows that window: the current task slides into place while the tasks around it come into view, and the progress bars fold away. The whole collapsed card expands on click.
When the active task changes, the list scrolls itself smoothly to keep that task visible, instead of also scrolling the page or chat around it.
Breaking
-
titleis removed, since the list no longer has a header. Drop the prop. -
TaskListHeaderis removed.TaskListnow renders its own toggle. -
hideWhenEmptyis removed. An emptyTaskListalways renders nothing. Drop the prop:- <TaskList tasks={tasks} hideWhenEmpty={false} /> + <TaskList tasks={tasks} />
-
Patch Changes
-
Field error messages now show an alert icon before the text, so an invalid field no longer relies on red alone. This applies to every field block,
Combobox, and anything that rendersFieldBlock.ErrorMsg. (#24987) -
Fixed Studio timestamps losing their time on historical dates. Date-only cells now stay date-only even today, while trace tooltips and unnamed chat threads preserve seconds. Timeline timestamps use the browser locale while keeping UTC. Calendar labels respect the requested timezone at year boundaries. (#24955)
Added shared date, duration, and elapsed-time helpers for custom Studio interfaces.
formatDaterequires an explicit preset:date,date-time,date-time-seconds,time,time-seconds, orrelative-time. Trace list dates, table timestamps, and tool-call timestamps preserve visible seconds without requiring a hover. Relative labels fall back to thedatepreset after seven days.formatTimestampPreciseretains milliseconds for debugging.import { formatDate } from '@mastra/playground-ui/utils/date-format'; import { formatDuration } from '@mastra/playground-ui/utils/duration'; import { formatRelativeTime } from '@mastra/playground-ui/utils/relative-time'; import { useElapsedTime } from '@mastra/playground-ui/hooks/use-elapsed-time'; formatDate('2026-09-24T10:00:00Z', 'date-time-seconds', { timeZone: 'UTC' }); formatRelativeTime('2026-09-24T10:00:00Z'); formatDuration(1234); // "1.23s" function Elapsed({ isRunning }: { isRunning: boolean }) { const elapsed = useElapsedTime(isRunning); return <span>{formatDuration(elapsed)}</span>; }
-
Added a
useObservabilityCapabilitieshook (@mastra/playground-ui/domains/capabilities) that reads which observability features the server supports. Studio's traces page now uses it to list traces through the lightweight endpoint when the server doesn't support trace queries. Older servers that don't report capabilities keep the current behavior. (#25014)Also added
useTraceQueryAvailable, which returns{ isLoading, enabled }.enabledis false while capabilities load and when the server doesn't support trace queries. Studio uses it to pick the traces list endpoint and to hide feedback on servers without trace query support.Also exported
useTracesListSourcefrom@mastra/playground-ui/domains/traces, so other apps can rebuild the traces list (auto-refresh, rolling time window, list rows). It takeswithQueryTraceandenabledas inputs and does not read capabilities itself; callers decide which endpoint to use. -
PageHeader.Metanow renders plain text as muted meta text, so metadata next to a page title no longer competes with the title. Badges and other components that set their own text style are unchanged. The mediumBadgenow sets its own letter spacing, so it looks the same inside styled text as anywhere else. (#24985) -
Added a
defaultOpenoption to the reasoning block (ReasoningandReasoningPartRenderer), so apps can start reasoning collapsed. It defaults totrue, so existing views are unchanged. While reasoning streams, the "Reasoning" label now shimmers, so a collapsed block still shows the model is thinking. (#25036)<ReasoningPartRenderer part={part} defaultOpen={false} />
-
Added a
withQueryTraceoption for servers that do not support the trace query API. Set it tofalseto list traces through the older light trace list endpoint: (#25007)useTraceQueryacceptswithQueryTraceandlegacyFilters(built withbuildTraceListFilters).createTraceFilterBarFieldsonly offers fields the light endpoint can filter on, with theisoperator.TraceColumnsMenuhides the "Add metadata column" action.
-
Studio hides the trace/span Feedback tab when the observability store does not support feedback. (#25020)
@mastra/server@1.71.0
Minor Changes
-
Studio and other clients can now tell which observability features the configured storage supports, without upgrading older storage packages.
GET /system/packagesnow always returnsobservabilityStorageCapabilitieswhen observability storage is configured. It adds per-endpointdiscoveryflags plustraceQuery,threadQuery,deltaPolling,traceQueryRootDurationandtraceQueryTenantScope. (#25008)Stores that declare their features with
getFeatures()are reported exactly as declared. Stores that predate feature declarations are detected by the methods they implement.On legacy stores such as LibSQL or the default
PostgresStore,traceQueryisfalse. Clients should list traces withGET /observability/traces/lightinstead ofPOST /observability/traces/queryon those stores (#24990).The same capabilities are also available from the new
GET /observability/capabilitiesendpoint, which works on any@mastra/coreversion and reports every flag asfalsewhen no observability storage is configured.const { capabilities } = await client.getObservabilityCapabilities(); if (capabilities.discovery.entityNames) { const { names } = await client.getEntityNames({}); }
Discovery routes (
/observability/discovery/*) now return empty results instead of a 500 error when the storage does not support them. This stops the recurring "does not support entity name discovery" errors when opening Studio (#16304).
Patch Changes
-
Stored agent default options now accept
eagerToolExecution. (#25005)defaultOptions: { eagerToolExecution: false, }
-
Fixed dataset create and update routes returning 500 when a schema uses an unsupported regex pattern; they now return 400 with the offending pattern. (#25044)
-
Added a
feedbackobservability storage capability and clearer errors for unsupported storage APIs. (#25020)GET /observability/capabilitiesandGET /system/packagesnow report afeedbackflag, so clients can check feedback support before calling the feedback endpoints.- Observability routes backed by an optional storage API (feedback, metrics, logs, scores) now return a 501 status instead of a server error when the configured store does not implement it. This also removes the noisy error log Studio triggered when probing feedback on stores without it (for example LibSQL).
const { capabilities } = await client.getObservabilityCapabilities(); if (capabilities.feedback) { const feedback = await client.listFeedback({ traceId }); }
@mastra/spanner@1.8.2
Patch Changes
-
The Spanner observability store now reports metrics and metric discovery as supported only when metrics are enabled with
disableMetrics: false. Previously Studio could treat metrics as available while every metric request failed. (#25008)const { capabilities } = await client.getObservabilityCapabilities(); capabilities.metrics; // true only when the SpannerStore sets disableMetrics: false
@mastra/telegram@0.1.3
Patch Changes
- Fixed Telegram webhook connections so reusing a bot token for another agent is rejected instead of replacing the existing webhook. Clarified how connect() uses a default bot token. (#24912)
Other updated packages
The following packages were updated with dependency changes only:
- @mastra/agent-builder@1.1.22
- @mastra/arize@1.3.19
- @mastra/arthur@0.4.19
- @mastra/braintrust@1.3.16
- @mastra/datadog@1.4.11
- @mastra/deepeval@0.1.13
- @mastra/deployer@1.71.0
- @mastra/deployer-cloud@1.71.0
- @mastra/deployer-cloudflare@1.2.30
- @mastra/deployer-netlify@1.2.30
- @mastra/deployer-sandbox@0.3.15
- @mastra/deployer-vercel@1.2.30
- @mastra/editor@0.15.3
- @mastra/laminar@1.3.21
- @mastra/langfuse@1.5.10
- @mastra/langsmith@1.3.21
- @mastra/longmemeval@1.1.30
- @mastra/next@0.2.29
- @mastra/opencode@0.1.30
- @mastra/otel-exporter@1.4.2
- @mastra/posthog@1.3.13
- @mastra/react@1.6.3
- @mastra/sentry@1.2.21
- @mastra/tanstack-start@0.2.29
- @mastra/temporal@0.4.9
- @mastra/turso@0.1.9