@mastra/core@1.74.0

hcengineering/platform@mastra/core@1.74.0Oct 5, 2026by PaulieScanlon

Upgrading?

AI Summary

This release adds the ability for tools to read the full conversation via agent.getMessages(), improves observational memory history search with filtering and paging capabilities, and introduces new accessible form field primitives in the Playground UI.

Key Highlights

  • Tool context can read full conversation via agent.getMessages() in both standard and durable agent loops
  • Observational memory history search with group filtering (groupId), explicit ordering (sortDirection), and direct record lookup
  • Memory recall can page through observation groups around search hits
  • New accessible form field primitives: Field, Fieldset, Form, and SearchInput components
  • Bot display name lookup in channel adapters for improved mentions after renaming

Breaking Changes

  • anchorTraceId removed from ThreadViewByTrace, TraceThreadPanel, and ThreadTrace components
  • ThreadTrace.LoadMoreSentinel removed; use pageSize and onLoadOlder to control pagination

New Features

  • agent.getMessages() in tool execution context for richer context-aware tool behavior
  • Group filtering and ordering for observational memory history
  • Page through observation groups with direction 'before'/'after' from matched groupId
  • New Field components for building form fields with improved accessibility
  • Bot display name lookup via botDisplayName on channel context

Full Release Notes

## 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`: `anchorTraceId` removed from `ThreadViewByTrace`, `TraceThreadPanel`, and `ThreadTrace`; `ThreadTrace.LoadMoreSentinel` removed. Use `pageSize` and `onLoadOlder` on `ThreadTrace` to control pagination/loading older turns.

## Changelog

### [@mastra/core@1.74.0](https://github.com/mastra-ai/mastra/blob/@mastra/core@1.74.0/packages/core/CHANGELOG.md)
#### 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-only `messages` field. (#25525)

  ```ts
  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 through `supportsObservationalMemoryHistorySearch`. Pass `recordId` to 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-bot` to `helper` now responds to `@helper` in channels, instead of only recognising its original username. The bot's current profile name is looked up once through the adapter and exposed as `botDisplayName` on 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](https://github.com/mastra-ai/mastra/blob/@mastra/factory@0.19.1/mastracode/factory/CHANGELOG.md)
#### Patch Changes

- Repository-backed Slack sessions can now recover from a failed `gh` authentication attempt without restarting the session. Refresh GitHub access, then retry the failed command: (#25545)

  ```text
  github_refresh_token({})
  ```

- Fixed Slack-triggered Factory runs failing with "No usable <provider> 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](https://github.com/mastra-ai/mastra/blob/@mastra/memory@1.35.0/packages/memory/CHANGELOG.md)
#### 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)

  ```ts
  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](https://github.com/mastra-ai/mastra/blob/@mastra/playground-ui@60.2.0/packages/playground-ui/CHANGELOG.md)
#### Minor Changes

- Added `Field` components for building form fields: `Field`, `FieldLabel`, `FieldDescription`, `FieldError`, `FieldContent`, `FieldItem`, `Fieldset` and `FieldsetLegend`, from `@mastra/playground-ui/components/Field`. They are built on Base UI Field and Fieldset. Put a label and any control inside a `Field`, 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, `FieldLabel` needs no `htmlFor` and the control no `id`. Code copied from shadcn that still passes them keeps working. (#25317)

  ```tsx
  // 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`, `RadioGroup` and `CodeEditor`. For a control that is not built on Base UI, such as a custom popover trigger, spread `useFieldControlAria()` 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. Use `orientation="responsive"` to stack it on small screens. For a radio group, use `<Fieldset render={<RadioGroup />}>` with a `FieldsetLegend`, and wrap each option in a `FieldItem`.

  A `Field` holds one control. When one title covers several controls, use a `Fieldset` with a `FieldsetLegend` (it takes `required` like `FieldLabel`), and name each control with its own `aria-label`. For a settings row, use the new `SettingsFieldsetRow`:

  ```tsx
  <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-label` keeps that name inside a `Field` too, the same way `aria-label` wins over a native `<label>`.

  Labels are styled by the `Field`: a label beside a `Checkbox`, `Switch` or radio shows a pointer cursor, so no `cursor-*` or color classes are needed. To disable a field, put `disabled` on the `Field`, `FieldItem` or `Fieldset` rather 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 uses `required`, `type="email"`, `min` or `max`: 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. Pass `onClose` for a search that collapses: the button then reads "Close search", stays visible and calls `onClose` after clearing. `ListSearch` is now built on it and adds the 300 ms debounce and the Cmd/Ctrl+Shift+F shortcut. Emptying a `ListSearch`, by typing or with the clear button, now calls `onSearch('')` right away. Both render `<input type="search">`, so tests find them by role `searchbox` instead of `textbox`.

  `TimePicker` takes an optional `label` (default "Time") that names its group, and its hour, minute and AM/PM selects now have names. `DateTimeRangePicker` labels its pickers "Start time" and "End time".

  `InputGroupInput` now types in the same text style as `Input` (`text-label`, 13px medium) at every size, instead of a lighter body style that shrank to 12px at `sm`. 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 `*FieldBlock` components, `FieldBlock` parts with hand-built ids, and `Label` with `htmlFor`. Mistakes in the id wiring left fields without an accessible name, such as hidden labels that were dropped and radio labels pointing at a `div`. 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`, `FieldBlocksLayout` and `fieldErrorId` (`@mastra/playground-ui/components/FormFieldBlocks`): build fields with the `Field` components. A select without a visible label, such as a toolbar filter, needs no `Field`: name it with `<SelectTrigger aria-label="…">`. For a search box, use `SearchInput`, which keeps `SearchFieldBlock`'s immediate updates, or `ListSearch` for a list filter. `ListSearch` calls `onSearch` 300 ms after typing stops, and needs `shortcutDisabled` on a second search box on the same page.
  - `FieldBlock.ErrorMsg` for a message that belongs to no single control, such as a server error under a form: `FieldError` throws outside a `Field`, so wrap it in `<Field invalid>`.
  - `Label` (`@mastra/playground-ui/components/Label`): use `FieldLabel` inside a `Field`. For a group title, use `FieldsetLegend` inside a `Fieldset`.
  - The `error` prop on `Input`, `Textarea`, `InputGroupInput` and `InputGroupTextarea`: use `<Field invalid>`, or set `aria-invalid` on a control outside a `Field`.
  - The `error` and `name` props on `Combobox`, and the `root` and `error` keys of `comboboxStyles`: wrap the combobox in `<Field invalid>` with a `FieldError`.
  - The `htmlFor` prop on `SettingsRow`: pass the control as a child without an `id`, and the row's label names it.

  **Changed**

  - `JSONSchemaForm.FieldName`, `JSONSchemaForm.FieldDescription` and `JSONSchemaForm.FieldType` no longer accept the old `TextFieldBlock` or `SelectFieldBlock` props. `FieldName` and `FieldDescription` take `label`, `labelIsHidden` and the props of their input. `FieldType` takes `label`, `labelIsHidden`, `placeholder`, `size`, `disabled` and `className`.

#### Patch Changes

- Added a `repeat` option to `useKeydown`. Set it to `false` so holding a key runs the handler once instead of on every key repeat, which suits toggles: (#25438)

  ```tsx
  useKeydown({ '[': toggleSidebar }, { repeat: false });
  ```

- Fixed `SelectTrigger` and `Combobox` triggers shrinking to their content instead of filling their field. Pickers in settings rows and forms line up with the container edge again. Combobox triggers with `iconOnlyValue` stay compact. (#25591)

- Made `SettingsRow` give 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 a `SettingsRow` Storybook 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 `pageSize` prop sets how many turns load at a time (default 10). (#25693)

  **Breaking:** `anchorTraceId` was removed from `ThreadViewByTrace`, `TraceThreadPanel` and `ThreadTrace`, and `ThreadTrace.LoadMoreSentinel` was removed. Pass `onLoadOlder` to `ThreadTrace` to load older turns.

  ```tsx
  // 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](https://github.com/mastra-ai/mastra/blob/@mastra/agent-builder@1.1.25/packages/agent-builder/CHANGELOG.md)
- [@mastra/client-js@1.51.2](https://github.com/mastra-ai/mastra/blob/@mastra/client-js@1.51.2/client-sdks/client-js/CHANGELOG.md)
- [@mastra/code-sdk@1.10.1](https://github.com/mastra-ai/mastra/blob/@mastra/code-sdk@1.10.1/mastracode/sdk/CHANGELOG.md)
- [@mastra/deployer@1.74.0](https://github.com/mastra-ai/mastra/blob/@mastra/deployer@1.74.0/packages/deployer/CHANGELOG.md)
- [@mastra/deployer-cloud@1.74.0](https://github.com/mastra-ai/mastra/blob/@mastra/deployer-cloud@1.74.0/deployers/cloud/CHANGELOG.md)
- [@mastra/deployer-cloudflare@1.2.33](https://github.com/mastra-ai/mastra/blob/@mastra/deployer-cloudflare@1.2.33/deployers/cloudflare/CHANGELOG.md)
- [@mastra/deployer-netlify@1.2.33](https://github.com/mastra-ai/mastra/blob/@mastra/deployer-netlify@1.2.33/deployers/netlify/CHANGELOG.md)
- [@mastra/deployer-sandbox@0.3.18](https://github.com/mastra-ai/mastra/blob/@mastra/deployer-sandbox@0.3.18/deployers/sandbox/CHANGELOG.md)
- [@mastra/deployer-vercel@1.2.33](https://github.com/mastra-ai/mastra/blob/@mastra/deployer-vercel@1.2.33/deployers/vercel/CHANGELOG.md)
- [@mastra/editor@0.15.6](https://github.com/mastra-ai/mastra/blob/@mastra/editor@0.15.6/packages/editor/CHANGELOG.md)
- [@mastra/elysia@0.1.14](https://github.com/mastra-ai/mastra/blob/@mastra/elysia@0.1.14/server-adapters/elysia/CHANGELOG.md)
- [@mastra/express@1.5.18](https://github.com/mastra-ai/mastra/blob/@mastra/express@1.5.18/server-adapters/express/CHANGELOG.md)
- [@mastra/fastify@1.5.18](https://github.com/mastra-ai/mastra/blob/@mastra/fastify@1.5.18/server-adapters/fastify/CHANGELOG.md)
- [@mastra/hono@1.7.16](https://github.com/mastra-ai/mastra/blob/@mastra/hono@1.7.16/server-adapters/hono/CHANGELOG.md)
- [@mastra/koa@1.7.18](https://github.com/mastra-ai/mastra/blob/@mastra/koa@1.7.18/server-adapters/koa/CHANGELOG.md)
- [@mastra/longmemeval@1.1.33](https://github.com/mastra-ai/mastra/blob/@mastra/longmemeval@1.1.33/explorations/longmemeval/CHANGELOG.md)
- [@mastra/mcp-docs-server@1.3.4](https://github.com/mastra-ai/mastra/blob/@mastra/mcp-docs-server@1.3.4/packages/mcp-docs-server/CHANGELOG.md)
- [@mastra/nestjs@0.2.33](https://github.com/mastra-ai/mastra/blob/@mastra/nestjs@0.2.33/server-adapters/nestjs/CHANGELOG.md)
- [@mastra/next@0.2.32](https://github.com/mastra-ai/mastra/blob/@mastra/next@0.2.32/server-adapters/next/CHANGELOG.md)
- [@mastra/opencode@0.1.33](https://github.com/mastra-ai/mastra/blob/@mastra/opencode@0.1.33/integrations/opencode/CHANGELOG.md)
- [@mastra/react@1.7.2](https://github.com/mastra-ai/mastra/blob/@mastra/react@1.7.2/client-sdks/react/CHANGELOG.md)
- [@mastra/server@1.74.0](https://github.com/mastra-ai/mastra/blob/@mastra/server@1.74.0/packages/server/CHANGELOG.md)
- [@mastra/tanstack-start@0.2.32](https://github.com/mastra-ai/mastra/blob/@mastra/tanstack-start@0.2.32/server-adapters/tanstack-start/CHANGELOG.md)
- [@mastra/temporal@0.4.12](https://github.com/mastra-ai/mastra/blob/@mastra/temporal@0.4.12/workflows/temporal/CHANGELOG.md)
- [@mastra/turso@0.1.12](https://github.com/mastra-ai/mastra/blob/@mastra/turso@0.1.12/stores/turso/CHANGELOG.md)

Related Repositories