@mastra/memory 1.31.0-alpha.3 → 1.32.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-agents-human-in-the-loop.md +38 -1
- package/dist/docs/references/docs-memory-memory-processors.md +7 -1
- package/dist/docs/references/docs-memory-message-history.md +40 -1
- package/dist/docs/references/docs-memory-observational-memory.md +3 -1
- package/dist/docs/references/reference-memory-memory-class.md +3 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/processors/index.cjs +1 -1
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/observation-turn/load-memory-context.d.ts.map +1 -1
- package/dist/{src-CSVmHSng.js → src-2UN5fCQ5.js} +1248 -459
- package/dist/src-2UN5fCQ5.js.map +1 -0
- package/dist/{src-QqTmOY5X.cjs → src-DmZEArj1.cjs} +1248 -459
- package/dist/src-DmZEArj1.cjs.map +1 -0
- package/package.json +8 -8
- package/dist/src-CSVmHSng.js.map +0 -1
- package/dist/src-QqTmOY5X.cjs.map +0 -1
package/dist/docs/SKILL.md
CHANGED
|
@@ -116,7 +116,44 @@ const stream = await agent.stream('Clean up old records', {
|
|
|
116
116
|
})
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
The function can be asynchronous. For decisions that depend on the tool name and arguments, use a [classifier](https://mastra.ai/reference/classifier/classifier) to estimate whether the call needs human review:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { Classifier } from '@mastra/core/classifier'
|
|
123
|
+
import { model } from '../models/evaluation-model'
|
|
124
|
+
import { agent } from './agent'
|
|
125
|
+
|
|
126
|
+
const approvalClassifier = new Classifier({
|
|
127
|
+
id: 'tool-approval-classifier',
|
|
128
|
+
model,
|
|
129
|
+
questions: {
|
|
130
|
+
requiresApproval: {
|
|
131
|
+
type: 'boolean',
|
|
132
|
+
instructions:
|
|
133
|
+
'Does this tool call need human approval because it is destructive, irreversible, expensive, or handles sensitive data?',
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
const stream = await agent.stream('Clean up old records', {
|
|
139
|
+
requireToolApproval: async ({ toolName, args }) => {
|
|
140
|
+
const result = await approvalClassifier.evaluate({
|
|
141
|
+
state: {
|
|
142
|
+
toolName,
|
|
143
|
+
argumentNames: Object.keys(args),
|
|
144
|
+
},
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
return result.answers.requiresApproval.probability >= 0.7
|
|
148
|
+
},
|
|
149
|
+
})
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The example sends argument names rather than values because the classifier forwards its state to the configured evaluation model. If the decision requires argument values, redact sensitive data first or use an evaluation model and provider that meet the protected tool's data-handling requirements.
|
|
153
|
+
|
|
154
|
+
Returning `true` pauses the tool call for human approval. It doesn't approve or decline the call automatically. Choose a threshold that matches the risk of the tools available to the agent. If this `requireToolApproval` function throws, it defaults to requiring approval.
|
|
155
|
+
|
|
156
|
+
The runtime then combines that result with the tool's `requireApproval` setting. A boolean `true` requires approval, while `false` doesn't disable approval required by `requireToolApproval`. A tool-level `requireApproval` function is authoritative and replaces the combined result for that tool.
|
|
120
157
|
|
|
121
158
|
> **Note:** Function-based `requireToolApproval` is only available on regular `stream()` / `generate()` calls. Durable agents and stored agents persist their options, and a function can't be serialized, so they accept only a boolean. If you pass a function in those contexts it falls back to requiring approval for every tool call.
|
|
122
159
|
|
|
@@ -14,6 +14,12 @@ Memory processors are [processors](https://mastra.ai/docs/agents/processors) tha
|
|
|
14
14
|
|
|
15
15
|
Mastra automatically adds these processors when memory is enabled:
|
|
16
16
|
|
|
17
|
+
### `MemoryInputFilter`
|
|
18
|
+
|
|
19
|
+
Trims client-echoed history before memory loaders run. For an existing thread, it keeps only the current user turn or new tool results. For an empty thread, it keeps the full initial input and removes provider item metadata from assistant parts that could refer to items that don't exist in storage.
|
|
20
|
+
|
|
21
|
+
This processor runs first so `MessageHistory`, `SemanticRecall`, and Observational Memory receive only the new input they need.
|
|
22
|
+
|
|
17
23
|
### `MessageHistory`
|
|
18
24
|
|
|
19
25
|
Retrieves message history and persists new messages.
|
|
@@ -206,7 +212,7 @@ Understanding the execution order is important when combining guardrails with me
|
|
|
206
212
|
[Memory Processors] → [Your inputProcessors]
|
|
207
213
|
```
|
|
208
214
|
|
|
209
|
-
1. **Memory processors run FIRST**: `WorkingMemory`, `MessageHistory`, `SemanticRecall`
|
|
215
|
+
1. **Memory processors run FIRST**: `MemoryInputFilter`, then `WorkingMemory`, `MessageHistory`, and `SemanticRecall`
|
|
210
216
|
2. **Your input processors run AFTER**: guardrails, filters, validators
|
|
211
217
|
|
|
212
218
|
As a result, memory loads message history before your processors can validate or filter the input.
|
|
@@ -12,7 +12,9 @@ You can also retrieve message history to display past conversations in your UI.
|
|
|
12
12
|
|
|
13
13
|
> **Warning:** When you use memory with a client application, send **only the new message** from the client instead of the full conversation history.
|
|
14
14
|
>
|
|
15
|
-
> Sending the full history is redundant because Mastra loads messages from storage
|
|
15
|
+
> Sending the full history is redundant because Mastra loads messages from storage. Mastra filters client-echoed history before loading stored messages and uses the stored copy as the base when message IDs match, preserving stored timestamps and provider metadata while retaining new tool results.
|
|
16
|
+
>
|
|
17
|
+
> If you assemble the request input yourself and need it processed exactly as sent, set `retainFullInput: true` on `memory.options` for that call, or in the memory constructor options to apply it agent-wide. This disables the filtering described above. History still loads underneath. Every input message that isn't already stored is saved to the thread, including few-shot examples.
|
|
16
18
|
>
|
|
17
19
|
> For an AI SDK example, see [Using Mastra Memory](https://mastra.ai/integrations/agentic-ui/ai-sdk-ui).
|
|
18
20
|
|
|
@@ -170,6 +172,43 @@ export const supportAgent = new Agent({
|
|
|
170
172
|
|
|
171
173
|
Title generation runs asynchronously after the agent responds and doesn't affect response time.
|
|
172
174
|
|
|
175
|
+
### Streaming the generated title
|
|
176
|
+
|
|
177
|
+
By default title generation runs in the background and the run's stream doesn't wait for it, so HTTP clients only see the title on their next thread fetch. Set `emitEvent: true` to deliver the title on the run's stream instead: the stream waits for the title and emits a transient `data-thread-title` chunk before `finish`.
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { Agent } from '@mastra/core/agent'
|
|
181
|
+
import { Memory } from '@mastra/memory'
|
|
182
|
+
|
|
183
|
+
export const supportAgent = new Agent({
|
|
184
|
+
id: 'support-agent',
|
|
185
|
+
name: 'Support agent',
|
|
186
|
+
instructions: 'Answer customer support questions.',
|
|
187
|
+
model: 'openai/gpt-5.6-sol',
|
|
188
|
+
memory: new Memory({
|
|
189
|
+
options: {
|
|
190
|
+
generateTitle: {
|
|
191
|
+
emitEvent: true,
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
}),
|
|
195
|
+
})
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Stream consumers receive the chunk with the persisted title, so a chat UI can rename its thread list entry without polling:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
for await (const chunk of stream.fullStream) {
|
|
202
|
+
if (chunk.type === 'data-thread-title') {
|
|
203
|
+
renameThreadInSidebar(chunk.data.threadId, chunk.data.title)
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
The chunk is transient: it's delivered to stream consumers but never persisted as part of the conversation's messages. Because the stream waits for the title, `emitEvent` delays the stream's `finish` on the turn that generates the title: the first turn of a thread, or a later turn when `minMessages` sets a higher threshold. Leave it off to keep title generation fully non-blocking.
|
|
209
|
+
|
|
210
|
+
> **Note:** `emitEvent` applies to `stream()` runs. `generate()` returns JSON and can't carry the chunk, so it keeps non-blocking title generation. [Durable and evented agents](https://mastra.ai/docs/harness/durable-agents) don't emit this chunk yet. In all of these cases the title is still generated and persisted.
|
|
211
|
+
|
|
173
212
|
To optimize cost or behavior, provide a smaller [`model`](https://mastra.ai/models) and custom `instructions`:
|
|
174
213
|
|
|
175
214
|
```typescript
|
|
@@ -92,7 +92,9 @@ See [configuration options](https://mastra.ai/reference/memory/observational-mem
|
|
|
92
92
|
|
|
93
93
|
> **Warning:** When you use OM with a client application, send **only the new message** from the client instead of the full conversation history.
|
|
94
94
|
>
|
|
95
|
-
> Observational memory still relies on stored conversation history. Sending the full history is redundant and can cause message ordering bugs when client-side timestamps conflict with stored timestamps.
|
|
95
|
+
> Observational memory still relies on stored conversation history. Sending the full history is redundant and can cause message ordering bugs when client-side timestamps conflict with stored timestamps. Mastra filters client-echoed history before loading stored messages and uses the stored copy as the base when message IDs match, preserving stored timestamps and provider metadata while retaining new tool results.
|
|
96
|
+
>
|
|
97
|
+
> If you assemble the request input yourself and need it processed exactly as sent, set `retainFullInput: true` on `memory.options` for that call, or in the memory constructor options to apply it agent-wide. This disables that filtering. History still loads underneath. Every input message that isn't already stored is saved to the thread, including few-shot examples.
|
|
96
98
|
>
|
|
97
99
|
> For an AI SDK example, see [Using Mastra Memory](https://mastra.ai/integrations/agentic-ui/ai-sdk-ui).
|
|
98
100
|
|
|
@@ -45,13 +45,15 @@ export const agent = new Agent({
|
|
|
45
45
|
|
|
46
46
|
**options.readOnly** (`boolean`): When true, prevents memory from saving new messages and provides working memory as read-only context (without the updateWorkingMemory tool). Useful for read-only operations like previews, internal routing agents, or sub agents that should reference but not modify memory.
|
|
47
47
|
|
|
48
|
+
**options.retainFullInput** (`boolean`): When true, the request input is processed exactly as supplied instead of being filtered against stored history. Use this when you assemble the input yourself and need the message sequence preserved. Stored history is still loaded underneath, and every input message that isn't already stored is saved to the thread, including few-shot examples. Can be set per call on memory.options or agent-wide in the memory constructor options.
|
|
49
|
+
|
|
48
50
|
**options.semanticRecall** (`boolean | { topK: number; messageRange: number | { before: number; after: number }; scope?: 'thread' | 'resource' }`): Enable semantic search in message history. Can be a boolean or an object with configuration options. When enabled, requires both vector store and embedder to be configured. Default topK is 4, default messageRange is {before: 1, after: 1}.
|
|
49
51
|
|
|
50
52
|
**options.workingMemory** (`WorkingMemory`): Configuration for working memory feature. Can be { enabled: boolean; template?: string; schema?: ZodObject\<any> | JSONSchema7; scope?: 'thread' | 'resource' } or { enabled: boolean } to disable.
|
|
51
53
|
|
|
52
54
|
**options.observationalMemory** (`boolean | ObservationalMemoryOptions`): Enable Observational Memory for long-context agentic memory. Set to true for defaults, or pass a config object to customize token budgets, models, and scope. See Observational Memory reference for configuration details.
|
|
53
55
|
|
|
54
|
-
**options.generateTitle** (`boolean | { model
|
|
56
|
+
**options.generateTitle** (`boolean | { model?: DynamicArgument<MastraModelConfig>; instructions?: DynamicArgument<string>; minMessages?: number; emitEvent?: boolean }`): Controls automatic thread title generation from the conversation transcript. Accepts a boolean or an object with a custom model (any MastraModelConfig: a model instance, a "provider/model" ID, or an OpenAI-compatible config; defaults to the agent's own model), custom instructions, a minimum message count, and emitEvent. With emitEvent: true the run's stream waits for the title and emits it as a transient data-thread-title chunk before finish (durable and evented agents persist the title but don't emit the chunk yet).
|
|
55
57
|
|
|
56
58
|
## Returns
|
|
57
59
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_src = require("./src-
|
|
2
|
+
const require_src = require("./src-DmZEArj1.cjs");
|
|
3
3
|
let _mastra_core_processors = require("@mastra/core/processors");
|
|
4
4
|
exports.Extractor = require_src.Extractor;
|
|
5
5
|
exports.KnowledgeSemanticIndexCoordinator = require_src.KnowledgeSemanticIndexCoordinator;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as SUMMARIZE_THREAD_DEFAULTS, G as ModelByInputTokens, H as KnowledgeSemanticIndexCoordinator, S as WorkingMemoryExtractor, U as StaleKnowledgeSemanticIndexError, V as Subconscious, X as Extractor, a as extractWorkingMemoryContent, b as WorkingMemoryStateProcessor, c as getObservationsAsOf, i as WorkingMemory, n as MessageHistory, o as extractWorkingMemoryTags, r as SemanticRecall, s as removeWorkingMemoryTags, t as Memory, v as WORKING_MEMORY_STATE_ID, w as summarizeConversation, x as deepMergeWorkingMemory, y as WORKING_MEMORY_STATE_PROCESSOR_ID } from "./src-
|
|
1
|
+
import { C as SUMMARIZE_THREAD_DEFAULTS, G as ModelByInputTokens, H as KnowledgeSemanticIndexCoordinator, S as WorkingMemoryExtractor, U as StaleKnowledgeSemanticIndexError, V as Subconscious, X as Extractor, a as extractWorkingMemoryContent, b as WorkingMemoryStateProcessor, c as getObservationsAsOf, i as WorkingMemory, n as MessageHistory, o as extractWorkingMemoryTags, r as SemanticRecall, s as removeWorkingMemoryTags, t as Memory, v as WORKING_MEMORY_STATE_ID, w as summarizeConversation, x as deepMergeWorkingMemory, y as WORKING_MEMORY_STATE_PROCESSOR_ID } from "./src-2UN5fCQ5.js";
|
|
2
2
|
export { Extractor, KnowledgeSemanticIndexCoordinator, Memory, MessageHistory, ModelByInputTokens, SUMMARIZE_THREAD_DEFAULTS, SemanticRecall, StaleKnowledgeSemanticIndexError, Subconscious, WORKING_MEMORY_STATE_ID, WORKING_MEMORY_STATE_PROCESSOR_ID, WorkingMemory, WorkingMemoryExtractor, WorkingMemoryStateProcessor, deepMergeWorkingMemory, extractWorkingMemoryContent, extractWorkingMemoryTags, getObservationsAsOf, removeWorkingMemoryTags, summarizeConversation };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_src = require("../src-
|
|
2
|
+
const require_src = require("../src-DmZEArj1.cjs");
|
|
3
3
|
exports.Extractor = require_src.Extractor;
|
|
4
4
|
exports.KnowledgeSemanticIndexCoordinator = require_src.KnowledgeSemanticIndexCoordinator;
|
|
5
5
|
exports.ModelByInputTokens = require_src.ModelByInputTokens;
|
package/dist/processors/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as formatMessagesForObserver, B as OBSERVATION_CONTINUATION_HINT, D as buildObserverPrompt, E as OBSERVER_SYSTEM_PROMPT, F as parseAnchorId, G as ModelByInputTokens, H as KnowledgeSemanticIndexCoordinator, I as stripEphemeralAnchorIds, J as publishSubconsciousActivity, K as SUBCONSCIOUS_ACTIVITY_STATE_ID, L as OBSERVATIONAL_MEMORY_DEFAULTS, M as optimizeObservationsForContext, N as parseObserverOutput, O as buildObserverSystemPrompt, P as injectAnchorIds, R as OBSERVATION_CONTEXT_INSTRUCTIONS, S as WorkingMemoryExtractor, T as TokenCounter, U as StaleKnowledgeSemanticIndexError, V as Subconscious, W as SubconsciousRemindExtractor, X as Extractor, Y as renderSubconsciousActivity, _ as wrapInObservationGroup, c as getObservationsAsOf, d as combineObservationGroupRanges, f as deriveObservationGroupProvenance, g as stripObservationGroups, h as renderObservationGroupsForReflection, j as hasCurrentTaskSection, k as extractCurrentTask, l as ObservationalMemoryProcessor, m as reconcileObservationGroupsFromReflection, p as parseObservationGroups, q as buildSubconsciousActivitySnapshot, u as ObservationalMemory, w as summarizeConversation, z as OBSERVATION_CONTEXT_PROMPT } from "../src-
|
|
1
|
+
import { A as formatMessagesForObserver, B as OBSERVATION_CONTINUATION_HINT, D as buildObserverPrompt, E as OBSERVER_SYSTEM_PROMPT, F as parseAnchorId, G as ModelByInputTokens, H as KnowledgeSemanticIndexCoordinator, I as stripEphemeralAnchorIds, J as publishSubconsciousActivity, K as SUBCONSCIOUS_ACTIVITY_STATE_ID, L as OBSERVATIONAL_MEMORY_DEFAULTS, M as optimizeObservationsForContext, N as parseObserverOutput, O as buildObserverSystemPrompt, P as injectAnchorIds, R as OBSERVATION_CONTEXT_INSTRUCTIONS, S as WorkingMemoryExtractor, T as TokenCounter, U as StaleKnowledgeSemanticIndexError, V as Subconscious, W as SubconsciousRemindExtractor, X as Extractor, Y as renderSubconsciousActivity, _ as wrapInObservationGroup, c as getObservationsAsOf, d as combineObservationGroupRanges, f as deriveObservationGroupProvenance, g as stripObservationGroups, h as renderObservationGroupsForReflection, j as hasCurrentTaskSection, k as extractCurrentTask, l as ObservationalMemoryProcessor, m as reconcileObservationGroupsFromReflection, p as parseObservationGroups, q as buildSubconsciousActivitySnapshot, u as ObservationalMemory, w as summarizeConversation, z as OBSERVATION_CONTEXT_PROMPT } from "../src-2UN5fCQ5.js";
|
|
2
2
|
export { Extractor, KnowledgeSemanticIndexCoordinator, ModelByInputTokens, OBSERVATIONAL_MEMORY_DEFAULTS, OBSERVATION_CONTEXT_INSTRUCTIONS, OBSERVATION_CONTEXT_PROMPT, OBSERVATION_CONTINUATION_HINT, OBSERVER_SYSTEM_PROMPT, ObservationalMemory, ObservationalMemoryProcessor, SUBCONSCIOUS_ACTIVITY_STATE_ID, StaleKnowledgeSemanticIndexError, Subconscious, SubconsciousRemindExtractor, TokenCounter, WorkingMemoryExtractor, buildObserverPrompt, buildObserverSystemPrompt, buildSubconsciousActivitySnapshot, combineObservationGroupRanges, deriveObservationGroupProvenance, extractCurrentTask, formatMessagesForObserver, getObservationsAsOf, hasCurrentTaskSection, injectAnchorIds, optimizeObservationsForContext, parseAnchorId, parseObservationGroups, parseObserverOutput, publishSubconsciousActivity, reconcileObservationGroupsFromReflection, renderObservationGroupsForReflection, renderSubconsciousActivity, stripEphemeralAnchorIds, stripObservationGroups, summarizeConversation, wrapInObservationGroup };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-memory-context.d.ts","sourceRoot":"","sources":["../../../../src/processors/observational-memory/observation-turn/load-memory-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,wBAAsB,yBAAyB,CAAC,EAC9C,MAAM,EACN,WAAW,EACX,QAAQ,EACR,UAAU,EACV,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,qBAAqB,CAAC;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"load-memory-context.d.ts","sourceRoot":"","sources":["../../../../src/processors/observational-memory/observation-turn/load-memory-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,wBAAsB,yBAAyB,CAAC,EAC9C,MAAM,EACN,WAAW,EACX,QAAQ,EACR,UAAU,EACV,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,qBAAqB,CAAC;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAUpE"}
|