Highlights
Tool Context Can Read the Full Conversation (agent.getMessages())
Tools now have access to the current conversation state via context.agent.getMessages() in both standard and durable agent loops, including remembered messages and in-run responses—enabling richer, context-aware tool behavior without changing the existing input-only messages field.
Observational Memory History Search (Filtering, Ordering, Record Lookup)
getObservationalMemoryHistory gained group filtering (groupId), explicit ordering (sortDirection), and direct lookup by recordId, with adapter capability signaling via supportsObservationalMemoryHistorySearch (notably affecting multiple DB adapters; Convex requires a server function redeploy for the new filters to apply).
Memory Recall Can Page Through Observation Groups Around Search Hits
Recall now supports paging “before/after” from a matched groupId, including groups condensed by reflection and buffered-but-not-yet-activated groups—improving investigation workflows without requiring re-indexing, alongside clearer, chronologically ordered search results and better first-turn retrieval guidance.
Playground UI: New Accessible Form Field Primitives (Field, Fieldset, Form, SearchInput)
A new set of form-building components standardizes label/description/error wiring without manual id/htmlFor, improving accessibility and consistency; includes new Form and SearchInput, plus deprecations of the older *FieldBlock approach to move toward a single, safer pattern.
Breaking Changes
@mastra/playground-ui:anchorTraceIdremoved fromThreadViewByTrace,TraceThreadPanel, andThreadTrace;ThreadTrace.LoadMoreSentinelremoved. UsepageSizeandonLoadOlderonThreadTraceto control pagination/loading older turns.
Changelog
@mastra/core@1.74.0
Minor Changes
-
Added
agent.getMessages()to tool execution context in standard and durable agent loops. Tools can read the current conversation, including remembered messages and in-run responses, without changing the existing input-onlymessagesfield. (#25525)execute: async (input, context) => { const messages = context?.agent?.getMessages?.() ?? []; return { messageCount: messages.length }; };
The getter reflects message-list removals, but not transient transforms applied only to the provider prompt. Treat returned messages as read-only.
-
Added group filtering and generation ordering to observational memory history. For example,
getObservationalMemoryHistory(threadId, resourceId, 1, { groupId, sortDirection: "ASC" })finds the earliest retained record containing a group in active observations or persisted buffered chunks. Adapters advertise support throughsupportsObservationalMemoryHistorySearch. PassrecordIdto read one record by ID; it only matches records for the requested thread or resource. (#25525)Convex users need to redeploy their Mastra server functions for these filters to apply.
Also in: @mastra/convex@1.7.0, @mastra/libsql@1.25.0, @mastra/mongodb@1.21.0, @mastra/mysql@0.12.0, @mastra/oracledb@0.5.0, @mastra/pg@1.29.0
Patch Changes
-
Update provider registry and model documentation with latest models and providers (
ac54c46) -
Fixed chat channel agents ignoring mentions of their current display name after being renamed. For example, a Slack app renamed from
acme-bottohelpernow responds to@helperin channels, instead of only recognising its original username. The bot's current profile name is looked up once through the adapter and exposed asbotDisplayNameon the channel context. (#25652) -
Raise transitive security dependency floors (dompurify, js-yaml, @ai-sdk/provider-utils) and bump nested/template deps (nodemailer, fastify, hono, ajv) for the 2026-10-01 Vanta remediation pass. (#25694)
@mastra/factory@0.19.1
Patch Changes
-
Repository-backed Slack sessions can now recover from a failed
ghauthentication attempt without restarting the session. Refresh GitHub access, then retry the failed command: (#25545)github_refresh_token({}) -
Fixed Slack-triggered Factory runs failing with "No usable credential" after a server restart. Slack mentions, DMs, and thread replies now load the linked user's model credentials before the run starts, instead of relying on that user having opened the web UI first. (#25653)
@mastra/memory@1.35.0
Minor Changes
-
Page through observation groups. Recall can now read the original observation groups around a search hit, including groups condensed away by reflection and buffered groups that haven't been activated yet. Existing records work without re-indexing. (#25525)
recall({ mode: 'observations', groupId: 'group-id-from-search', direction: 'after', limit: 5 });
Easier-to-read search results. Search results are dated, listed oldest first, and mark where groups may be hidden between hits. Hits already in the agent's context come back as short references, so more new hits fit. When a long group is shortened, its excerpt starts at the line that best matches the query.
Better recall guidance. With retrieval enabled, the agent gets recall guidance from the first turn, including in read-only runs. It explains how to search, page, and confirm details against source messages, treats what the user said as authoritative and what the assistant proposed as a suggestion, and labels reflected groups as lossy summaries.
@mastra/playground-ui@60.2.0
Minor Changes
-
Added
Fieldcomponents for building form fields:Field,FieldLabel,FieldDescription,FieldError,FieldContent,FieldItem,FieldsetandFieldsetLegend, from@mastra/playground-ui/components/Field. They are built on Base UI Field and Fieldset. Put a label and any control inside aField, and the label names the control. The description and error are linked to it too, and the control is marked invalid, with no ids to pass around. The part names follow shadcn/ui, but unlike shadcn,FieldLabelneeds nohtmlForand the control noid. Code copied from shadcn that still passes them keeps working. (#25317)// Before <TextFieldBlock name="email" label="Email" helpText="Used to sign in." errorMsg={errors.email?.message} required /> // After <Field invalid={Boolean(errors.email)}> <FieldLabel required>Email</FieldLabel> <Input {...register('email')} /> <FieldDescription>Used to sign in.</FieldDescription> <FieldError>{errors.email?.message}</FieldError> </Field>
This works for
Input,Textarea,InputGroupInput,InputGroupTextarea,Select,Combobox,Checkbox,Switch,RadioGroupandCodeEditor. For a control that is not built on Base UI, such as a custom popover trigger, spreaduseFieldControlAria()on it to get the same label, description and invalid wiring. To hide a label and keep it for screen readers, use<FieldLabel className="sr-only">. To put the label beside the control, use<Field orientation="horizontal">: the row is centred, and when the label comes first the control sits at the far end, so a settings toggle needs no extra classes. Useorientation="responsive"to stack it on small screens. For a radio group, use<Fieldset render={<RadioGroup />}>with aFieldsetLegend, and wrap each option in aFieldItem.A
Fieldholds one control. When one title covers several controls, use aFieldsetwith aFieldsetLegend(it takesrequiredlikeFieldLabel), and name each control with its ownaria-label. For a settings row, use the newSettingsFieldsetRow:<SettingsFieldsetRow label="Releases" description="Where new issues go."> <SelectTrigger aria-label="Factory for Releases">…</SelectTrigger> <SelectTrigger aria-label="Board for Releases">…</SelectTrigger> </SettingsFieldsetRow>
A control that has its own
aria-labelkeeps that name inside aFieldtoo, the same wayaria-labelwins over a native<label>.Labels are styled by the
Field: a label beside aCheckbox,Switchor radio shows a pointer cursor, so nocursor-*or color classes are needed. To disable a field, putdisabledon theField,FieldItemorFieldsetrather than on the control: the control is disabled through it, and only then does the label show it can't be clicked. For compact rows, use<FieldLabel size="smaller">.Added
Form(@mastra/playground-ui/components/Form), built on Base UI Form, with one standard gap between fields. Put a<FieldError />with no children in a field that usesrequired,type="email",minormax: when a user submits an invalid value, the form stops, focuses that field and shows the browser's message there.Added
SearchInput(@mastra/playground-ui/components/SearchInput), a search box with a hidden label, a search icon and a clear button that puts focus back in the field. It updates on every keystroke. PassonClosefor a search that collapses: the button then reads "Close search", stays visible and callsonCloseafter clearing.ListSearchis now built on it and adds the 300 ms debounce and the Cmd/Ctrl+Shift+F shortcut. Emptying aListSearch, by typing or with the clear button, now callsonSearch('')right away. Both render<input type="search">, so tests find them by rolesearchboxinstead oftextbox.TimePickertakes an optionallabel(default "Time") that names its group, and its hour, minute and AM/PM selects now have names.DateTimeRangePickerlabels its pickers "Start time" and "End time".InputGroupInputnow types in the same text style asInput(text-label, 13px medium) at every size, instead of a lighter body style that shrank to 12px atsm. Search boxes, environment variable rows and comment inputs now match the text fields around them.Why
Before, there were three ways to build a field: the
*FieldBlockcomponents,FieldBlockparts with hand-built ids, andLabelwithhtmlFor. Mistakes in the id wiring left fields without an accessible name, such as hidden labels that were dropped and radio labels pointing at adiv. Now there is one way to build a field, and it links the label, description and error for you.Deprecated
These still work as before, so existing code keeps building. Studio and Factory no longer use them. They stay until no consumer does, then a later release removes them:
TextFieldBlock,TextareaFieldBlock,SelectFieldBlock,SearchFieldBlock,FieldBlock,FieldBlocksLayoutandfieldErrorId(@mastra/playground-ui/components/FormFieldBlocks): build fields with theFieldcomponents. A select without a visible label, such as a toolbar filter, needs noField: name it with<SelectTrigger aria-label="…">. For a search box, useSearchInput, which keepsSearchFieldBlock's immediate updates, orListSearchfor a list filter.ListSearchcallsonSearch300 ms after typing stops, and needsshortcutDisabledon a second search box on the same page.FieldBlock.ErrorMsgfor a message that belongs to no single control, such as a server error under a form:FieldErrorthrows outside aField, so wrap it in<Field invalid>.Label(@mastra/playground-ui/components/Label): useFieldLabelinside aField. For a group title, useFieldsetLegendinside aFieldset.- The
errorprop onInput,Textarea,InputGroupInputandInputGroupTextarea: use<Field invalid>, or setaria-invalidon a control outside aField. - The
errorandnameprops onCombobox, and therootanderrorkeys ofcomboboxStyles: wrap the combobox in<Field invalid>with aFieldError. - The
htmlForprop onSettingsRow: pass the control as a child without anid, and the row's label names it.
Changed
JSONSchemaForm.FieldName,JSONSchemaForm.FieldDescriptionandJSONSchemaForm.FieldTypeno longer accept the oldTextFieldBlockorSelectFieldBlockprops.FieldNameandFieldDescriptiontakelabel,labelIsHiddenand the props of their input.FieldTypetakeslabel,labelIsHidden,placeholder,size,disabledandclassName.
Patch Changes
-
Added a
repeatoption touseKeydown. Set it tofalseso holding a key runs the handler once instead of on every key repeat, which suits toggles: (#25438)useKeydown({ '[': toggleSidebar }, { repeat: false });
-
Fixed
SelectTriggerandComboboxtriggers shrinking to their content instead of filling their field. Pickers in settings rows and forms line up with the container edge again. Combobox triggers withiconOnlyValuestay compact. (#25591) -
Made
SettingsRowgive select and combobox controls one shared width (16rem) beside the label, so pickers line up across rows without each call site sizing them. A width class on the trigger still overrides it, and stacked rows on small screens keep full-width controls. Added aSettingsRowStorybook story. (#25635) -
Fixed the thread view firing repeated scores requests for every trace. Scores now load only when a trace's Scores tab is open, and the tab no longer shows a count. (#25683)
-
The trace thread view now reads like a chat. It opens on the latest turns, stays on the newest turn while messages and spans load, and loads older turns as you scroll up without moving what you are reading. It now searches the last 31 days of traces, up from 30 (no limit when trace query is unavailable), and the new
pageSizeprop sets how many turns load at a time (default 10). (#25693)Breaking:
anchorTraceIdwas removed fromThreadViewByTrace,TraceThreadPanelandThreadTrace, andThreadTrace.LoadMoreSentinelwas removed. PassonLoadOldertoThreadTraceto load older turns.// Before <ThreadViewByTrace threadId={threadId} anchorTraceId={traceId} /> // After <ThreadViewByTrace threadId={threadId} pageSize={20} />
-
Reduce observability polling in Studio: (#25705)
- Thread view: stop fetching and polling feedback for every trace row just to show a count on the Feedback tab. Feedback is now only loaded while a row's Feedback tab is open, matching the Messages and Scores tabs.
- Slow down the default refetch intervals: feedback polls every 30s (was 3s), scores and trace span scores every 15s (was 5s / 3s).
Other updated packages
The following packages were updated with dependency changes only:
- @mastra/agent-builder@1.1.25
- @mastra/client-js@1.51.2
- @mastra/code-sdk@1.10.1
- @mastra/deployer@1.74.0
- @mastra/deployer-cloud@1.74.0
- @mastra/deployer-cloudflare@1.2.33
- @mastra/deployer-netlify@1.2.33
- @mastra/deployer-sandbox@0.3.18
- @mastra/deployer-vercel@1.2.33
- @mastra/editor@0.15.6
- @mastra/elysia@0.1.14
- @mastra/express@1.5.18
- @mastra/fastify@1.5.18
- @mastra/hono@1.7.16
- @mastra/koa@1.7.18
- @mastra/longmemeval@1.1.33
- @mastra/mcp-docs-server@1.3.4
- @mastra/nestjs@0.2.33
- @mastra/next@0.2.32
- @mastra/opencode@0.1.33
- @mastra/react@1.7.2
- @mastra/server@1.74.0
- @mastra/tanstack-start@0.2.32
- @mastra/temporal@0.4.12
- @mastra/turso@0.1.12