@mastra/memory 1.24.0-alpha.0 → 1.25.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/CHANGELOG.md +53 -0
- package/dist/docs/SKILL.md +6 -6
- package/dist/docs/assets/SOURCE_MAP.json +3 -205
- package/dist/docs/references/docs-agents-agent-approval.md +85 -11
- package/dist/docs/references/docs-agents-networks.md +2 -2
- package/dist/docs/references/docs-agents-supervisor-agents.md +19 -13
- package/dist/docs/references/docs-evals-evals-with-memory.md +4 -4
- package/dist/docs/references/docs-long-running-agents-background-tasks.md +10 -10
- package/dist/docs/references/docs-long-running-agents-goals.md +15 -11
- package/dist/docs/references/docs-memory-memory-processors.md +10 -10
- package/dist/docs/references/docs-memory-message-history.md +11 -5
- package/dist/docs/references/docs-memory-multi-user-threads.md +6 -6
- package/dist/docs/references/docs-memory-observational-memory.md +57 -38
- package/dist/docs/references/docs-memory-overview.md +24 -10
- package/dist/docs/references/docs-memory-semantic-recall.md +3 -3
- package/dist/docs/references/docs-memory-working-memory.md +8 -8
- package/dist/docs/references/docs-storage-overview.md +2 -2
- package/dist/docs/references/reference-memory-clone-utilities.md +1 -1
- package/dist/docs/references/reference-memory-cloneThread.md +3 -3
- package/dist/docs/references/reference-memory-listThreads.md +1 -1
- package/dist/docs/references/reference-memory-memory-class.md +4 -4
- package/dist/docs/references/reference-memory-observational-memory.md +88 -38
- package/dist/docs/references/reference-memory-summarizeConversation.md +3 -3
- package/dist/docs/references/reference-memory-summarizeThread.md +3 -3
- package/dist/docs/references/reference-processors-token-limiter-processor.md +4 -4
- package/dist/docs/references/reference-storage-dsql.md +3 -3
- package/dist/docs/references/reference-storage-dynamodb.md +7 -7
- package/dist/docs/references/reference-storage-mongodb.md +2 -2
- package/dist/docs/references/reference-storage-postgresql.md +2 -2
- package/dist/docs/references/reference-storage-redis.md +1 -1
- package/dist/docs/references/reference-storage-upstash.md +1 -1
- package/dist/docs/references/reference-vectors-libsql.md +2 -2
- package/dist/docs/references/reference-vectors-mongodb.md +188 -7
- package/dist/docs/references/reference-vectors-pg.md +5 -5
- package/dist/docs/references/reference-vectors-upstash.md +1 -1
- package/dist/index.cjs +30 -72
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/processors/index.cjs +32 -129
- package/dist/processors/index.js +2 -4
- package/dist/processors/observational-memory/index.d.ts +1 -1
- package/dist/processors/observational-memory/index.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/types.d.ts +6 -0
- package/dist/processors/observational-memory/observation-strategies/types.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -1
- package/dist/processors/observational-memory/observational-memory.d.ts +30 -1
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/processor.d.ts.map +1 -1
- package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -1
- package/dist/processors/observational-memory/types.d.ts +50 -6
- package/dist/processors/observational-memory/types.d.ts.map +1 -1
- package/dist/src-BYZh9IBv.js +28250 -0
- package/dist/src-BYZh9IBv.js.map +1 -0
- package/dist/src-naeQog_T.cjs +28504 -0
- package/dist/src-naeQog_T.cjs.map +1 -0
- package/package.json +9 -9
- package/dist/chunk-3UXBG7HA.js +0 -31429
- package/dist/chunk-3UXBG7HA.js.map +0 -1
- package/dist/chunk-43FJOLKM.cjs +0 -108
- package/dist/chunk-43FJOLKM.cjs.map +0 -1
- package/dist/chunk-D4J4XPGM.cjs +0 -111
- package/dist/chunk-D4J4XPGM.cjs.map +0 -1
- package/dist/chunk-EGRHWZRV.js +0 -3
- package/dist/chunk-EGRHWZRV.js.map +0 -1
- package/dist/chunk-LSJJAJAF.js +0 -105
- package/dist/chunk-LSJJAJAF.js.map +0 -1
- package/dist/chunk-NKIQRCOM.cjs +0 -4
- package/dist/chunk-NKIQRCOM.cjs.map +0 -1
- package/dist/chunk-RY3SV3BJ.cjs +0 -31496
- package/dist/chunk-RY3SV3BJ.cjs.map +0 -1
- package/dist/chunk-WCGXQIEN.js +0 -103
- package/dist/chunk-WCGXQIEN.js.map +0 -1
- package/dist/constants-RMCTOZE3.js +0 -3
- package/dist/constants-RMCTOZE3.js.map +0 -1
- package/dist/constants-ZEKSZ4UM.cjs +0 -28
- package/dist/constants-ZEKSZ4UM.cjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/observational-memory-FF4AVBKG.cjs +0 -129
- package/dist/observational-memory-FF4AVBKG.cjs.map +0 -1
- package/dist/observational-memory-OSTBP4LB.js +0 -4
- package/dist/observational-memory-OSTBP4LB.js.map +0 -1
- package/dist/processors/index.cjs.map +0 -1
- package/dist/processors/index.js.map +0 -1
- package/dist/working-memory-state-LDPWYVCG.cjs +0 -24
- package/dist/working-memory-state-LDPWYVCG.cjs.map +0 -1
- package/dist/working-memory-state-OMSMSYAW.js +0 -3
- package/dist/working-memory-state-OMSMSYAW.js.map +0 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Added in:** `@mastra/memory@1.1.0`
|
|
6
6
|
|
|
7
|
-
Observational Memory (OM) is Mastra's memory system for long-context agentic memory.
|
|
7
|
+
Observational Memory (OM) is Mastra's memory system for long-context agentic memory. An **Observer** watches conversations and creates observations. A **Reflector** restructures those observations by combining related items and condensing overarching patterns. Together, they maintain an observation log that replaces raw message history as it grows.
|
|
8
8
|
|
|
9
9
|
## Usage
|
|
10
10
|
|
|
@@ -27,7 +27,7 @@ export const agent = new Agent({
|
|
|
27
27
|
|
|
28
28
|
## Configuration
|
|
29
29
|
|
|
30
|
-
The `observationalMemory` option accepts `true`, a configuration object, or `false`. Setting `true` enables OM with `google/gemini-2.5-flash` as the default model. When passing a config object,
|
|
30
|
+
The `observationalMemory` option accepts `true`, a configuration object, or `false`. Setting `true` enables OM with `google/gemini-2.5-flash` as the default model. When passing a config object, set `model` at the top level or on `observation.model` and/or `reflection.model`; when all model fields are omitted, OM falls back to `google/gemini-2.5-flash`.
|
|
31
31
|
|
|
32
32
|
Observer input is multimodal-aware. OM keeps text placeholders like `[Image #1: screenshot.png]` in the transcript it builds for the Observer, and also sends the underlying image parts when possible. This applies to both single-thread observation and batched multi-thread observation. Non-image files appear as placeholders only.
|
|
33
33
|
|
|
@@ -35,7 +35,7 @@ OM performs thresholding with fast local token estimation. Text uses `tokenx`, a
|
|
|
35
35
|
|
|
36
36
|
**enabled** (`boolean`): Enable or disable Observational Memory. When omitted from a config object, defaults to true. Only enabled: false explicitly disables it. (Default: `true`)
|
|
37
37
|
|
|
38
|
-
**model** (`string | LanguageModel | DynamicModel | ModelByInputTokens | ModelWithRetries[]`): Model for both the Observer and Reflector agents. Sets the model for both at once. Cannot be used together with observation.model or reflection.model — an error will be thrown if both are set. When
|
|
38
|
+
**model** (`string | LanguageModel | DynamicModel | ModelByInputTokens | ModelWithRetries[]`): Model for both the Observer and Reflector agents. Sets the model for both at once. Cannot be used together with observation.model or reflection.model — an error will be thrown if both are set. When this and observation.model/reflection.model are all omitted, OM falls back to google/gemini-2.5-flash. Use "default" to explicitly use the default model (google/gemini-2.5-flash). (Default: `'google/gemini-2.5-flash'`)
|
|
39
39
|
|
|
40
40
|
**scope** (`'resource' | 'thread'`): Memory scope for observations. 'thread' keeps observations per-thread. 'resource' (experimental) shares observations across all threads for a resource, enabling cross-conversation memory. (Default: `'thread'`)
|
|
41
41
|
|
|
@@ -47,7 +47,9 @@ OM performs thresholding with fast local token estimation. Text uses `tokenx`, a
|
|
|
47
47
|
|
|
48
48
|
**temporalMarkers** (`boolean`): Insert temporal-gap reminder markers before new user messages when the previous message in the thread is at least 10 minutes older. The marker is persisted in memory, emitted as an inline reminder event so clients can render it specially, and shown to the observer so it can anchor observations to when events occurred. (Default: `false`)
|
|
49
49
|
|
|
50
|
-
**retrieval** (`boolean | { vector?: boolean; scope?: 'thread' | 'resource' }`):
|
|
50
|
+
**retrieval** (`boolean | { vector?: boolean; scope?: 'thread' | 'resource' }`): Let the agent look up the raw message history behind its observations. Observation groups keep durable pointers to the original messages, and a recall tool is registered so the agent can browse them. true enables cross-thread browsing by default. { vector: true } also enables semantic search using Memory's vector store and embedder. { scope: 'thread' } restricts the recall tool to the current thread only. Default scope is 'resource'. (Default: `false`)
|
|
51
|
+
|
|
52
|
+
**hooks** (`ObserveHooks`): Lifecycle hooks fired for every observation/reflection cycle — the manual observe()/reflect() APIs, turn-driven synchronous observation, and fire-and-forget async buffering. Callbacks receive threadId/resourceId/trigger call context ('manual' | 'turn-sync' | 'async-buffer'), and the end hooks (onObservationEnd/onReflectionEnd) additionally receive the OM model call's token usage and providerMetadata (where providers such as the AI Gateway report per-call cost), so apps can account for OM model spend without wrapping the observer/reflector models in middleware. Failed async-buffered cycles never throw; they report through the end hook's error field. Errors thrown by these hooks are caught and logged — they never fail the cycle.
|
|
51
53
|
|
|
52
54
|
**observation** (`ObservationalMemoryObservationConfig`): Configuration for the observation step. Controls when the Observer agent runs and how it behaves.
|
|
53
55
|
|
|
@@ -59,29 +61,33 @@ OM performs thresholding with fast local token estimation. Text uses `tokenx`, a
|
|
|
59
61
|
|
|
60
62
|
**observation.extract** (`Extractor[]`): Custom values to extract after observation. Schema-less extractors are requested inline in the Observer output. Schema-backed extractors run as a follow-up structured output call and are stored in thread OM metadata.
|
|
61
63
|
|
|
62
|
-
**observation.
|
|
64
|
+
**observation.manageWorkingMemory** (`boolean`): Let the Observer manage working memory through OM extraction. Adds WorkingMemoryExtractor, defaults workingMemory.agentManaged to false, and defaults workingMemory.useStateSignals to true. See Working memory updates.
|
|
65
|
+
|
|
66
|
+
**observation.observeAttachments** (`'auto' | boolean | string[]`): Controls which image/file attachments are forwarded to the Observer model alongside their placeholder text lines. true (default) forwards all attachments. false drops all attachments while keeping placeholders visible. 'auto' uses the provider capabilities registry to decide: attachments are forwarded when the Observer model supports multimodal input, dropped otherwise, and forwarded when no capability data is available for the model. An array is a case-insensitive mimeType allowlist supporting exact matches ('application/pdf'), wildcard subtypes ('image/\*'), and bare '\*' for everything. Useful when the Observer model is text-only (e.g. some DeepSeek endpoints) while the main agent uses a multimodal model. Tool-result attachments are filtered using the same rule.
|
|
63
67
|
|
|
64
68
|
**observation.messageTokens** (`number`): Token count of unobserved messages that triggers observation. When unobserved message tokens exceed this threshold, the Observer agent is called. Text is estimated locally with tokenx. Image parts are included with model-aware heuristics when possible, with deterministic fallbacks when image metadata is incomplete. Image-like file parts are counted the same way when uploads are normalized as files.
|
|
65
69
|
|
|
66
70
|
**observation.maxTokensPerBatch** (`number`): Maximum tokens per batch when observing multiple threads in resource scope. Threads are chunked into batches of this size and processed in parallel. Lower values mean more parallelism but more API calls.
|
|
67
71
|
|
|
68
|
-
**observation.modelSettings** (`ObservationalMemoryModelSettings`): Model settings for the Observer agent.
|
|
72
|
+
**observation.modelSettings** (`ObservationalMemoryModelSettings`): Model settings for the Observer agent. The maxOutputTokens: 100\_000 default is only applied with default model selection (no model set, "default", or a ModelByInputTokens selector). Custom models get no maxOutputTokens default.
|
|
69
73
|
|
|
70
74
|
**observation.modelSettings.temperature** (`number`): Temperature for generation. Lower values produce more consistent output.
|
|
71
75
|
|
|
72
|
-
**observation.modelSettings.maxOutputTokens** (`number`): Maximum output tokens. Set high to prevent truncation of observations.
|
|
76
|
+
**observation.modelSettings.maxOutputTokens** (`number`): Maximum output tokens. Set high to prevent truncation of observations. The 100000 default is only applied with default model selection; custom models get no default.
|
|
73
77
|
|
|
74
|
-
**observation.
|
|
78
|
+
**observation.providerOptions** (`ProviderOptions`): Provider-specific options passed to the Observer agent, such as Google thinking configuration.
|
|
79
|
+
|
|
80
|
+
**observation.bufferTokens** (`number | false`): How often background observation buffering runs. Values between 0 and 1 are fractions of messageTokens: 0.25 buffers every 25% of the threshold (7.5k tokens with the default 30k). Values of 1 or more are absolute token counts: 5000 buffers every 5k tokens. Buffered observations are stored until the messageTokens threshold is reached, then activate instantly without a blocking LLM call. Must resolve to less than messageTokens. Set to false to disable all async buffering (both observation and reflection).
|
|
75
81
|
|
|
76
82
|
**observation.bufferOnIdle** (`boolean`): Run background observation buffering when an agent turn ends and the agent becomes idle. This is separate from bufferTokens, which controls step-time async buffering. Set this to true to buffer short idle turns without waiting for the next turn or the messageTokens threshold.
|
|
77
83
|
|
|
78
|
-
**observation.bufferActivation** (`number`):
|
|
84
|
+
**observation.bufferActivation** (`number`): How much of the message window to clear when buffered observations activate. Values between 0 and 1 are the fraction of messageTokens to remove: 0.8 removes \~80% of the message history and keeps \~20% (6k tokens with the default 30k). Values of 1000 or more are the token count to keep: 4000 keeps \~4k message tokens after activation. Note the direction flips: a higher ratio removes more history, while a higher token count keeps more.
|
|
79
85
|
|
|
80
|
-
**observation.activateAfterIdle** (`number | string | false | "auto"`): Time before buffered observations are forced to activate after inactivity. Accepts milliseconds, a duration string, "auto" for a provider-aware prompt cache TTL, or false. If unset, the top-level activateAfterIdle value is used for observations. Set false to disable the top-level idle setting for observations.
|
|
86
|
+
**observation.activateAfterIdle** (`number | string | false | "auto"`): Time before buffered observations are forced to activate after inactivity. Accepts milliseconds, a duration string, "auto" for a provider-aware prompt cache TTL, or false. If unset, the top-level activateAfterIdle value is used for observations. Set false to disable the top-level idle setting for observations. Currently only applied when using the standalone ObservationalMemory class; new Memory(...) applies the top-level activateAfterIdle only.
|
|
81
87
|
|
|
82
|
-
**observation.activateOnProviderChange** (`boolean`): Force buffered observations to activate when the actor provider or model changes. If unset, the top-level activateOnProviderChange value is used for observations.
|
|
88
|
+
**observation.activateOnProviderChange** (`boolean`): Force buffered observations to activate when the actor provider or model changes. If unset, the top-level activateOnProviderChange value is used for observations. Currently only applied when using the standalone ObservationalMemory class; new Memory(...) applies the top-level activateOnProviderChange only.
|
|
83
89
|
|
|
84
|
-
**observation.blockAfter** (`number`):
|
|
90
|
+
**observation.blockAfter** (`number`): Safety net that forces a synchronous (blocking) observation when background buffering can't keep up. Values from 1 up to (but not including) 100 are multipliers of messageTokens: 1.2 forces a blocking observation at 120% of the threshold (36k tokens with the default 30k). Values of 100 or more are absolute token counts and must be greater than messageTokens. Between messageTokens and blockAfter, only async buffering and activation run; buffered activation still preserves a minimum remaining context (the smaller of 1000 tokens or the retention floor). Only relevant when bufferTokens is set. Defaults to 1.2 when async buffering is enabled.
|
|
85
91
|
|
|
86
92
|
**observation.previousObserverTokens** (`number | false`): Optional token budget for the observer's previous-observations context. When set to a number, the observations passed to the Observer agent are tail-truncated to fit within this budget while keeping the newest observations and preserving highlighted 🔴 items when possible. When a buffered reflection is pending, the already-reflected observation lines are automatically replaced with the reflection summary before truncation. Set to 0 to omit previous observations entirely, or false to disable truncation explicitly.
|
|
87
93
|
|
|
@@ -95,19 +101,21 @@ OM performs thresholding with fast local token estimation. Text uses `tokenx`, a
|
|
|
95
101
|
|
|
96
102
|
**reflection.observationTokens** (`number`): Token count of observations that triggers reflection. When observation tokens exceed this threshold, the Reflector agent is called to condense them.
|
|
97
103
|
|
|
98
|
-
**reflection.modelSettings** (`ObservationalMemoryModelSettings`): Model settings for the Reflector agent.
|
|
104
|
+
**reflection.modelSettings** (`ObservationalMemoryModelSettings`): Model settings for the Reflector agent. The maxOutputTokens: 100\_000 default is only applied with default model selection (no model set, "default", or a ModelByInputTokens selector). Custom models get no maxOutputTokens default.
|
|
99
105
|
|
|
100
106
|
**reflection.modelSettings.temperature** (`number`): Temperature for generation. Lower values produce more consistent output.
|
|
101
107
|
|
|
102
|
-
**reflection.modelSettings.maxOutputTokens** (`number`): Maximum output tokens. Set high to prevent truncation of observations.
|
|
108
|
+
**reflection.modelSettings.maxOutputTokens** (`number`): Maximum output tokens. Set high to prevent truncation of observations. The 100000 default is only applied with default model selection; custom models get no default.
|
|
109
|
+
|
|
110
|
+
**reflection.providerOptions** (`ProviderOptions`): Provider-specific options passed to the Reflector agent, such as Google thinking configuration.
|
|
103
111
|
|
|
104
|
-
**reflection.bufferActivation** (`number`):
|
|
112
|
+
**reflection.bufferActivation** (`number`): When background reflection starts, as a ratio (0-1) of observationTokens: 0.5 starts reflecting in the background once observations reach 50% of the threshold (20k tokens with the default 40k). When the full threshold is reached, the buffered reflection replaces the observations it covers, preserving any new observations appended after that range.
|
|
105
113
|
|
|
106
|
-
**reflection.activateAfterIdle** (`number | string | false | "auto"`): Time before buffered reflections are forced to activate after inactivity. Accepts milliseconds, a duration string, "auto" for a provider-aware prompt cache TTL, or false. Reflections do not inherit top-level activateAfterIdle; set this explicitly to opt reflections into idle activation.
|
|
114
|
+
**reflection.activateAfterIdle** (`number | string | false | "auto"`): Time before buffered reflections are forced to activate after inactivity. Accepts milliseconds, a duration string, "auto" for a provider-aware prompt cache TTL, or false. Reflections do not inherit top-level activateAfterIdle; set this explicitly to opt reflections into idle activation. Currently only applied when using the standalone ObservationalMemory class; this setting has no effect through new Memory(...).
|
|
107
115
|
|
|
108
|
-
**reflection.activateOnProviderChange** (`boolean`): Force buffered reflections to activate when the actor provider or model changes. Reflections do not inherit top-level activateOnProviderChange; set this explicitly to opt reflections into provider-change activation.
|
|
116
|
+
**reflection.activateOnProviderChange** (`boolean`): Force buffered reflections to activate when the actor provider or model changes. Reflections do not inherit top-level activateOnProviderChange; set this explicitly to opt reflections into provider-change activation. Currently only applied when using the standalone ObservationalMemory class; this setting has no effect through new Memory(...).
|
|
109
117
|
|
|
110
|
-
**reflection.blockAfter** (`number`):
|
|
118
|
+
**reflection.blockAfter** (`number`): Safety net that forces a synchronous (blocking) reflection when background reflection can't keep up. Values from 1 up to (but not including) 100 are multipliers of observationTokens: 1.2 forces a blocking reflection at 120% of the threshold (48k tokens with the default 40k). Values of 100 or more are absolute token counts and must be greater than observationTokens. Between observationTokens and blockAfter, only async buffering and activation run. Only relevant when bufferActivation is set. Defaults to 1.2 when async reflection is enabled.
|
|
111
119
|
|
|
112
120
|
### Token estimate metadata cache
|
|
113
121
|
|
|
@@ -150,7 +158,7 @@ const memory = new Memory({
|
|
|
150
158
|
|
|
151
159
|
**name** (`string`): Human-readable extractor name. OM slugifies this value into the extractor slug. Names must be unique after slug generation.
|
|
152
160
|
|
|
153
|
-
**slug** (`string`): Generated stable identifier for persisted values and XML tags. Slugs use lowercase letters, numbers, and hyphens. Built-in slugs and reserved XML tags cannot be used by custom extractors.
|
|
161
|
+
**slug** (`string`): Read-only property derived from name — not a constructor option. Generated stable identifier for persisted values and XML tags. Slugs use lowercase letters, numbers, and hyphens. Built-in slugs and reserved XML tags cannot be used by custom extractors.
|
|
154
162
|
|
|
155
163
|
**instructions** (`string | (context) => string`): Instructions for what to extract and when to update the value. Use a function to derive instructions from runtime context.
|
|
156
164
|
|
|
@@ -158,6 +166,8 @@ const memory = new Memory({
|
|
|
158
166
|
|
|
159
167
|
**includePreviousExtraction** (`boolean`): Controls whether the previous extraction is shown to the extractor on future OM runs. Set to false for values that should only come from the current OM run. (Default: `true`)
|
|
160
168
|
|
|
169
|
+
**metadataKeyPath** (`string | false`): Dot-separated OM metadata path used to persist the extracted value. Set to false to skip OM metadata persistence entirely. (Default: `'extracted.<slug>'`)
|
|
170
|
+
|
|
161
171
|
**onExtracted** (`(context) => T | void | Promise<T | void>`): Optional hook called after a custom extractor returns a value and before metadata is persisted. Returning a value replaces the extracted value. Throwing records an extraction failure.
|
|
162
172
|
|
|
163
173
|
### Extraction behavior
|
|
@@ -170,7 +180,7 @@ const memory = new Memory({
|
|
|
170
180
|
- Schema-less extractors are inline string extractors emitted directly in the Observer or Reflector output.
|
|
171
181
|
- Dynamic extractor functions receive runtime context, including `source`, `threadId`, `resourceId`, `mainAgent`, `memory`, and `requestContext` when available.
|
|
172
182
|
- `WorkingMemoryExtractor` uses the normal extractor pipeline to update working memory through the active `Memory` instance. It uses structured extraction when working memory has a JSON schema and skips OM metadata persistence, so the working memory payload isn't duplicated under OM extracted metadata.
|
|
173
|
-
- `observationalMemory.observation.manageWorkingMemory` adds `WorkingMemoryExtractor
|
|
183
|
+
- `observationalMemory.observation.manageWorkingMemory` adds `WorkingMemoryExtractor` and defaults `workingMemory.agentManaged` to `false`. It defaults `workingMemory.useStateSignals` to `true` when working memory is enabled.
|
|
174
184
|
- Extraction failures are reported in OM marker data and don't discard other successful extracted values.
|
|
175
185
|
|
|
176
186
|
## Examples
|
|
@@ -269,7 +279,7 @@ export const agent = new Agent({
|
|
|
269
279
|
id: 'my-agent',
|
|
270
280
|
name: 'my-agent',
|
|
271
281
|
instructions: 'You are a helpful assistant.',
|
|
272
|
-
model: 'openai/gpt-5.
|
|
282
|
+
model: 'openai/gpt-5.6-sol',
|
|
273
283
|
memory: new Memory({
|
|
274
284
|
options: {
|
|
275
285
|
observationalMemory: {
|
|
@@ -290,7 +300,7 @@ export const agent = new Agent({
|
|
|
290
300
|
id: 'my-agent',
|
|
291
301
|
name: 'my-agent',
|
|
292
302
|
instructions: 'You are a helpful assistant.',
|
|
293
|
-
model: 'openai/gpt-5.
|
|
303
|
+
model: 'openai/gpt-5.6-sol',
|
|
294
304
|
memory: new Memory({
|
|
295
305
|
options: {
|
|
296
306
|
observationalMemory: {
|
|
@@ -318,7 +328,7 @@ export const agent = new Agent({
|
|
|
318
328
|
id: 'health-assistant',
|
|
319
329
|
name: 'health-assistant',
|
|
320
330
|
instructions: 'You are a health and wellness assistant.',
|
|
321
|
-
model: 'openai/gpt-5.
|
|
331
|
+
model: 'openai/gpt-5.6-sol',
|
|
322
332
|
memory: new Memory({
|
|
323
333
|
options: {
|
|
324
334
|
observationalMemory: {
|
|
@@ -341,16 +351,16 @@ export const agent = new Agent({
|
|
|
341
351
|
|
|
342
352
|
### Async buffering
|
|
343
353
|
|
|
344
|
-
Async buffering is **enabled by default**. It pre-computes observations in the background as the conversation grows
|
|
354
|
+
Async buffering is **enabled by default**. It pre-computes observations in the background as the conversation grows: when the `messageTokens` threshold is reached, buffered observations activate instantly with no blocking LLM call.
|
|
345
355
|
|
|
346
|
-
The lifecycle
|
|
356
|
+
The lifecycle follows **buffer → activate → remove messages → repeat**. Background Observer calls run at `bufferTokens` intervals, each producing a chunk of observations. At threshold, chunks activate: observations move into the log, raw messages are removed from context. The `blockAfter` threshold forces a synchronous fallback if buffering can't keep up.
|
|
347
357
|
|
|
348
358
|
Default settings:
|
|
349
359
|
|
|
350
|
-
- `observation.bufferTokens: 0.2
|
|
351
|
-
- `observation.bufferActivation: 0.8
|
|
360
|
+
- `observation.bufferTokens: 0.2`: Buffer every 20% of `messageTokens` (e.g. every \~6k tokens with a 30k threshold)
|
|
361
|
+
- `observation.bufferActivation: 0.8`: On activation, remove enough messages to keep only 20% of the threshold remaining
|
|
352
362
|
- Buffered observations include continuation hints (`suggestedResponse`, `currentTask`) that survive activation to maintain conversational continuity
|
|
353
|
-
- `reflection.bufferActivation: 0.5
|
|
363
|
+
- `reflection.bufferActivation: 0.5`: start background reflection at 50% of observation threshold
|
|
354
364
|
|
|
355
365
|
To customize:
|
|
356
366
|
|
|
@@ -476,7 +486,7 @@ interface DataOmStatusPart {
|
|
|
476
486
|
}
|
|
477
487
|
```
|
|
478
488
|
|
|
479
|
-
`buffered.reflection.inputObservationTokens` is the size of the observations that were sent to the Reflector. `buffered.reflection.observationTokens` is the compressed result
|
|
489
|
+
`buffered.reflection.inputObservationTokens` is the size of the observations that were sent to the Reflector. `buffered.reflection.observationTokens` is the compressed result: the size of what will replace those observations when the reflection activates. A client can use these two values to show a compression ratio.
|
|
480
490
|
|
|
481
491
|
Clients can derive percentages and post-activation estimates from the raw values:
|
|
482
492
|
|
|
@@ -643,7 +653,7 @@ Emitted when async buffering fails. The system falls back to synchronous process
|
|
|
643
653
|
|
|
644
654
|
### `data-om-activation`
|
|
645
655
|
|
|
646
|
-
Emitted when buffered observations or reflections are activated (moved into the active context window). This is an instant operation
|
|
656
|
+
Emitted when buffered observations or reflections are activated (moved into the active context window). This is an instant operation: no LLM call is involved.
|
|
647
657
|
|
|
648
658
|
**cycleId** (`string`): Unique ID for this activation event.
|
|
649
659
|
|
|
@@ -663,18 +673,45 @@ Emitted when buffered observations or reflections are activated (moved into the
|
|
|
663
673
|
|
|
664
674
|
**observations** (`string`): The activated observations text.
|
|
665
675
|
|
|
676
|
+
**triggeredBy** (`'threshold' | 'ttl' | 'provider_change'`): Whether activation was triggered by threshold crossing, activateAfterIdle expiry, or a model/provider change.
|
|
677
|
+
|
|
678
|
+
**lastActivityAt** (`number`): Unix-ms timestamp of the last assistant message part used for TTL checks.
|
|
679
|
+
|
|
680
|
+
**ttlExpiredMs** (`number`): How long activateAfterIdle had been exceeded when activation fired.
|
|
681
|
+
|
|
682
|
+
**previousModel** (`string`): Previous assistant model identifier that triggered activation (e.g. openai/gpt-4o).
|
|
683
|
+
|
|
684
|
+
**currentModel** (`string`): Current actor model identifier that triggered activation.
|
|
685
|
+
|
|
666
686
|
**recordId** (`string`): The OM record ID.
|
|
667
687
|
|
|
668
688
|
**threadId** (`string`): This thread's ID.
|
|
669
689
|
|
|
670
690
|
**config** (`ObservationMarkerConfig`): Snapshot of config at activation time.
|
|
671
691
|
|
|
692
|
+
### `data-om-thread-update`
|
|
693
|
+
|
|
694
|
+
Emitted when the Observer updates the thread title. Only emitted when `observation.threadTitle` is enabled.
|
|
695
|
+
|
|
696
|
+
**cycleId** (`string`): Unique ID for this observation cycle — shared with observation markers.
|
|
697
|
+
|
|
698
|
+
**threadId** (`string`): The thread ID that was updated.
|
|
699
|
+
|
|
700
|
+
**oldTitle** (`string`): The previous thread title. Undefined if the thread had no title.
|
|
701
|
+
|
|
702
|
+
**newTitle** (`string`): The new thread title.
|
|
703
|
+
|
|
704
|
+
**timestamp** (`string`): When this update occurred.
|
|
705
|
+
|
|
672
706
|
## Standalone usage
|
|
673
707
|
|
|
674
708
|
Most users should use the `Memory` class above. Using `ObservationalMemory` directly is mainly useful for benchmarking, experimentation, or when you need to control processor ordering with other processors (like [guardrails](https://mastra.ai/docs/agents/guardrails)).
|
|
675
709
|
|
|
710
|
+
The `ObservationalMemory` class is the engine; to attach it to an agent, wrap it in an `ObservationalMemoryProcessor`, which needs a `Memory` instance for loading and persisting messages. Note that `stores.memory` is typed as optional on storage adapters, so a non-null assertion (or a runtime check) is needed:
|
|
711
|
+
|
|
676
712
|
```typescript
|
|
677
|
-
import { ObservationalMemory } from '@mastra/memory/processors'
|
|
713
|
+
import { ObservationalMemory, ObservationalMemoryProcessor } from '@mastra/memory/processors'
|
|
714
|
+
import { Memory } from '@mastra/memory'
|
|
678
715
|
import { Agent } from '@mastra/core/agent'
|
|
679
716
|
import { LibSQLStore } from '@mastra/libsql'
|
|
680
717
|
|
|
@@ -683,8 +720,11 @@ const storage = new LibSQLStore({
|
|
|
683
720
|
url: 'file:./memory.db',
|
|
684
721
|
})
|
|
685
722
|
|
|
723
|
+
const memory = new Memory({ storage })
|
|
724
|
+
|
|
686
725
|
const om = new ObservationalMemory({
|
|
687
|
-
storage: storage.stores.memory
|
|
726
|
+
storage: storage.stores.memory!,
|
|
727
|
+
memory,
|
|
688
728
|
model: 'google/gemini-2.5-flash',
|
|
689
729
|
scope: 'resource',
|
|
690
730
|
observation: {
|
|
@@ -695,13 +735,15 @@ const om = new ObservationalMemory({
|
|
|
695
735
|
},
|
|
696
736
|
})
|
|
697
737
|
|
|
738
|
+
const omProcessor = new ObservationalMemoryProcessor(om, memory)
|
|
739
|
+
|
|
698
740
|
export const agent = new Agent({
|
|
699
741
|
id: 'my-agent',
|
|
700
742
|
name: 'my-agent',
|
|
701
743
|
instructions: 'You are a helpful assistant.',
|
|
702
744
|
model: 'openai/gpt-5-mini',
|
|
703
|
-
inputProcessors: [
|
|
704
|
-
outputProcessors: [
|
|
745
|
+
inputProcessors: [omProcessor],
|
|
746
|
+
outputProcessors: [omProcessor],
|
|
705
747
|
})
|
|
706
748
|
```
|
|
707
749
|
|
|
@@ -717,7 +759,7 @@ The standalone `ObservationalMemory` class accepts all the same options as the `
|
|
|
717
759
|
|
|
718
760
|
## Recall tool
|
|
719
761
|
|
|
720
|
-
When `retrieval` is set (any truthy value), a `recall` tool is registered so the agent can page through raw messages behind observation group ranges. By default (scope `'resource'`), the tool supports listing threads (`mode: "threads"`), browsing other threads (`threadId`), and cross-thread search. With `retrieval: { vector: true }`, semantic search is available (`mode: "search"`). Set `scope: 'thread'` to restrict the tool to the current thread only. The tool is automatically added to the agent's tool list
|
|
762
|
+
When `retrieval` is set (any truthy value), a `recall` tool is registered so the agent can page through raw messages behind observation group ranges. By default (scope `'resource'`), the tool supports listing threads (`mode: "threads"`), browsing other threads (`threadId`), and cross-thread search. With `retrieval: { vector: true }`, semantic search is available (`mode: "search"`). Set `scope: 'thread'` to restrict the tool to the current thread only. The tool is automatically added to the agent's tool list.
|
|
721
763
|
|
|
722
764
|
### Parameters
|
|
723
765
|
|
|
@@ -725,9 +767,11 @@ When `retrieval` is set (any truthy value), a `recall` tool is registered so the
|
|
|
725
767
|
|
|
726
768
|
**query** (`string`): Search query for mode: "search". Finds messages semantically similar to this text across all threads for the current user.
|
|
727
769
|
|
|
728
|
-
**cursor** (`string`): A message ID to anchor the recall query.
|
|
770
|
+
**cursor** (`string`): A message ID to anchor the recall query. Extract the start or end ID from an observation group range (e.g. from \_range: \startId:endId\\\_, use either startId or endId). If a range string is passed directly, the tool returns a hint explaining how to extract the correct ID. When both cursor and threadId are omitted for mode: "messages", the tool browses the current thread from the position set by anchor.
|
|
771
|
+
|
|
772
|
+
**threadId** (`string`): Browse a different thread by its ID, or pass "current" for the active thread. Use mode: "threads" first to discover thread IDs. When provided without a cursor, reading starts from the beginning of the thread.
|
|
729
773
|
|
|
730
|
-
**
|
|
774
|
+
**anchor** (`'start' | 'end'`): For mode: "messages" without a cursor, page from the start (oldest-first) or end (newest-first) of the thread. (Default: `'start'`)
|
|
731
775
|
|
|
732
776
|
**page** (`number`): Pagination offset. For messages: positive values page forward from cursor, negative values page backward. For threads: page number (0-indexed). 0 is treated as 1 for messages. (Default: `1`)
|
|
733
777
|
|
|
@@ -735,6 +779,10 @@ When `retrieval` is set (any truthy value), a `recall` tool is registered so the
|
|
|
735
779
|
|
|
736
780
|
**detail** (`'low' | 'high'`): Controls how much content is shown per message part. 'low' shows truncated text and tool names with positional indices (\[p0], \[p1]). 'high' shows full content including tool arguments and results, clamped to one part per call with continuation hints. (Default: `'low'`)
|
|
737
781
|
|
|
782
|
+
**partType** (`'text' | 'tool-call' | 'tool-result' | 'reasoning' | 'image' | 'file'`): Filter results to only include message parts of this type. Only applies to mode: "messages".
|
|
783
|
+
|
|
784
|
+
**toolName** (`string`): Filter results to only include tool-call and tool-result parts matching this tool name. Only applies to mode: "messages".
|
|
785
|
+
|
|
738
786
|
**partIndex** (`number`): Fetch a single message part at full detail by its positional index. Use this when a low-detail recall shows an interesting part at \[p1] — call again with partIndex: 1 to see the full content without loading every part.
|
|
739
787
|
|
|
740
788
|
**before** (`string`): For mode: "threads" only. Filter to threads created before this date. Accepts ISO 8601 format (e.g. "2026-03-15", "2026-03-10T00:00:00Z").
|
|
@@ -753,6 +801,8 @@ When `retrieval` is set (any truthy value), a `recall` tool is registered so the
|
|
|
753
801
|
|
|
754
802
|
**limit** (`number`): The limit used for this query.
|
|
755
803
|
|
|
804
|
+
**detail** (`'low' | 'high'`): The detail level used for this query.
|
|
805
|
+
|
|
756
806
|
**hasNextPage** (`boolean`): Whether more messages exist after this page.
|
|
757
807
|
|
|
758
808
|
**hasPrevPage** (`boolean`): Whether more messages exist before this page.
|
|
@@ -798,7 +848,7 @@ const selector = new ModelByInputTokens({
|
|
|
798
848
|
upTo: {
|
|
799
849
|
10_000: 'google/gemini-2.5-flash', // Fast for small inputs
|
|
800
850
|
40_000: 'openai/gpt-5-mini', // Stronger for medium inputs
|
|
801
|
-
1_000_000: 'openai/gpt-5.
|
|
851
|
+
1_000_000: 'openai/gpt-5.6-sol', // Most capable for large inputs
|
|
802
852
|
},
|
|
803
853
|
})
|
|
804
854
|
```
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
# summarizeConversation()
|
|
4
4
|
|
|
5
|
-
The standalone `summarizeConversation()` function summarizes a conversation in one shot. It distills the messages you pass in with the same Observer plumbing that powers [Observational Memory](https://mastra.ai/reference/memory/observational-memory)
|
|
5
|
+
The standalone `summarizeConversation()` function summarizes a conversation in one shot. It distills the messages you pass in with the same Observer plumbing that powers [Observational Memory](https://mastra.ai/reference/memory/observational-memory): without Observational Memory attached to an agent, and without reading from or writing to storage.
|
|
6
6
|
|
|
7
|
-
Nothing is written back to memory. The summary and extracted values are returned to you (and to each extractor's `onExtracted` hook), so you decide where they go
|
|
7
|
+
Nothing is written back to memory. The summary and extracted values are returned to you (and to each extractor's `onExtracted` hook), so you decide where they go: for example your own database.
|
|
8
8
|
|
|
9
|
-
Use this when you already have the messages in hand and want explicit control over what gets summarized.
|
|
9
|
+
Use this when you already have the messages in hand and want explicit control over what gets summarized. For a stored thread identified by ID, use [`Memory.summarizeThread()`](https://mastra.ai/reference/memory/summarizeThread), which loads the messages for you.
|
|
10
10
|
|
|
11
11
|
## Usage example
|
|
12
12
|
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
# Memory.summarizeThread()
|
|
4
4
|
|
|
5
|
-
The `.summarizeThread()` method summarizes a thread's conversation in one shot. It loads the thread's messages from storage and distills them with the same Observer plumbing that powers [Observational Memory](https://mastra.ai/reference/memory/observational-memory)
|
|
5
|
+
The `.summarizeThread()` method summarizes a thread's conversation in one shot. It loads the thread's messages from storage and distills them with the same Observer plumbing that powers [Observational Memory](https://mastra.ai/reference/memory/observational-memory): as a standalone call, without Observational Memory attached to an agent.
|
|
6
6
|
|
|
7
7
|
Messages load page-by-page starting from the newest, bounded by `lastMessages` and `maxInputTokens`, so summarizing a long thread doesn't read its entire history from storage.
|
|
8
8
|
|
|
9
|
-
Nothing is written back to memory. The summary and extracted values are returned to you (and to each extractor's `onExtracted` hook), so you decide where they go
|
|
9
|
+
Nothing is written back to memory. The summary and extracted values are returned to you (and to each extractor's `onExtracted` hook), so you decide where they go: for example your own database.
|
|
10
10
|
|
|
11
|
-
Use this when a session ends and you want a summary or structured extraction of the whole conversation, such as a voice call at hang-up.
|
|
11
|
+
Use this when a session ends and you want a summary or structured extraction of the whole conversation, such as a voice call at hang-up. For messages you already have in hand (without loading them from a thread), use the standalone [`summarizeConversation()`](https://mastra.ai/reference/memory/summarizeConversation) function instead. It takes the same options with `messages` in place of `threadId`.
|
|
12
12
|
|
|
13
13
|
## Usage example
|
|
14
14
|
|
|
@@ -84,7 +84,7 @@ export const agent = new Agent({
|
|
|
84
84
|
id: 'context-limited-agent',
|
|
85
85
|
name: 'context-limited-agent',
|
|
86
86
|
instructions: 'You are a helpful assistant',
|
|
87
|
-
model: 'openai/gpt-5.
|
|
87
|
+
model: 'openai/gpt-5.6-sol',
|
|
88
88
|
memory: new Memory({/* ... */}),
|
|
89
89
|
inputProcessors: [
|
|
90
90
|
new TokenLimiterProcessor({ limit: 4000 }), // Limits historical messages to ~4000 tokens
|
|
@@ -94,7 +94,7 @@ export const agent = new Agent({
|
|
|
94
94
|
|
|
95
95
|
### As a per-step input processor (limit multi-step token growth)
|
|
96
96
|
|
|
97
|
-
When an agent uses tools across multiple steps (e.g. `maxSteps > 1`), each step accumulates conversation history from all previous steps. Use `inputProcessors` to also limit tokens at each step of the agentic loop
|
|
97
|
+
When an agent uses tools across multiple steps (e.g. `maxSteps > 1`), each step accumulates conversation history from all previous steps. Use `inputProcessors` to also limit tokens at each step of the agentic loop. The `TokenLimiterProcessor` automatically applies to both the initial input and every subsequent step:
|
|
98
98
|
|
|
99
99
|
```typescript
|
|
100
100
|
import { Agent } from '@mastra/core/agent'
|
|
@@ -104,7 +104,7 @@ export const agent = new Agent({
|
|
|
104
104
|
id: 'multi-step-agent',
|
|
105
105
|
name: 'multi-step-agent',
|
|
106
106
|
instructions: 'You are a helpful research assistant with access to tools',
|
|
107
|
-
model: 'openai/gpt-5.
|
|
107
|
+
model: 'openai/gpt-5.6-sol',
|
|
108
108
|
inputProcessors: [
|
|
109
109
|
new TokenLimiterProcessor({ limit: 8000 }), // Applied at every step
|
|
110
110
|
],
|
|
@@ -128,7 +128,7 @@ export const agent = new Agent({
|
|
|
128
128
|
id: 'response-limited-agent',
|
|
129
129
|
name: 'response-limited-agent',
|
|
130
130
|
instructions: 'You are a helpful assistant',
|
|
131
|
-
model: 'openai/gpt-5.
|
|
131
|
+
model: 'openai/gpt-5.6-sol',
|
|
132
132
|
outputProcessors: [
|
|
133
133
|
new TokenLimiterProcessor({
|
|
134
134
|
limit: 1000,
|
|
@@ -183,7 +183,7 @@ storage.db // Database client for executing queries
|
|
|
183
183
|
storage.pool // Underlying pg.Pool instance
|
|
184
184
|
```
|
|
185
185
|
|
|
186
|
-
|
|
186
|
+
It supports direct queries and custom transaction management. When using these fields:
|
|
187
187
|
|
|
188
188
|
- You are responsible for proper connection and transaction handling.
|
|
189
189
|
- Closing the store (`storage.close()`) will destroy the connection pool if it was created by the store.
|
|
@@ -199,7 +199,7 @@ Connections are authenticated with IAM. No database passwords are required. `@ma
|
|
|
199
199
|
|
|
200
200
|
#### Single database, schema-based isolation
|
|
201
201
|
|
|
202
|
-
Each cluster exposes a single database
|
|
202
|
+
Each cluster exposes a single database `postgres`. Logical separation is done via schemas. The `schemaName` option controls where Mastra tables are created.
|
|
203
203
|
|
|
204
204
|
#### No PostgreSQL extensions
|
|
205
205
|
|
|
@@ -243,7 +243,7 @@ export const dsqlAgent = new Agent({
|
|
|
243
243
|
name: 'DSQL Agent',
|
|
244
244
|
instructions:
|
|
245
245
|
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
|
|
246
|
-
model: 'openai/gpt-5.
|
|
246
|
+
model: 'openai/gpt-5.6-sol',
|
|
247
247
|
memory: new Memory({
|
|
248
248
|
storage: new DSQLStore({
|
|
249
249
|
id: 'dsql-agent-storage',
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# DynamoDB storage
|
|
4
4
|
|
|
5
|
-
The DynamoDB storage implementation provides a
|
|
5
|
+
The DynamoDB storage implementation provides a high-capacity and performant NoSQL database solution for Mastra, using a single-table design pattern with [ElectroDB](https://electrodb.dev/).
|
|
6
6
|
|
|
7
7
|
> **Observability Not Supported:** DynamoDB storage **doesn't support the observability domain**. Traces from the `MastraStorageExporter` can't be persisted to DynamoDB, and [Studio's](https://mastra.ai/docs/studio/overview) observability features won't work with DynamoDB as your only storage provider. To enable observability, use [composite storage](https://mastra.ai/reference/storage/composite) to route observability data to a supported provider like ClickHouse.
|
|
8
8
|
|
|
@@ -124,7 +124,7 @@ For local development, you can use [DynamoDB Local](https://docs.aws.amazon.com/
|
|
|
124
124
|
|
|
125
125
|
## TTL (time to live) configuration
|
|
126
126
|
|
|
127
|
-
DynamoDB TTL allows you to automatically delete items after a specified
|
|
127
|
+
DynamoDB TTL allows you to automatically delete items after a specified duration for these use cases:
|
|
128
128
|
|
|
129
129
|
- **Cost optimization**: Automatically remove old data to reduce storage costs
|
|
130
130
|
- **Data lifecycle management**: Implement retention policies for compliance
|
|
@@ -259,19 +259,19 @@ Before diving into the architectural details, keep these key points in mind when
|
|
|
259
259
|
|
|
260
260
|
## Architectural approach
|
|
261
261
|
|
|
262
|
-
This storage adapter utilizes a **single-table design pattern**
|
|
262
|
+
This storage adapter utilizes a **single-table design pattern** with [ElectroDB](https://electrodb.dev/), a common and recommended approach for DynamoDB. This differs architecturally from relational database adapters (like `@mastra/pg` or `@mastra/libsql`) that typically use multiple tables, each dedicated to a specific entity (threads, messages, etc.).
|
|
263
263
|
|
|
264
264
|
Key aspects of this approach:
|
|
265
265
|
|
|
266
|
-
- **DynamoDB Native:** The single-table design is optimized for DynamoDB's key-value and query capabilities, often leading to better performance and
|
|
266
|
+
- **DynamoDB Native:** The single-table design is optimized for DynamoDB's key-value and query capabilities, often leading to better performance and capacity compared to mimicking relational models.
|
|
267
267
|
- **External Table Management:** Unlike some adapters that might offer helper functions to create tables via code, this adapter **expects the DynamoDB table and its associated Global Secondary Indexes (GSIs) to be provisioned externally** before use. Please refer to [TABLE\_SETUP.md](https://github.com/mastra-ai/mastra/blob/main/stores/dynamodb/TABLE_SETUP.md) for detailed instructions using tools like AWS CloudFormation or CDK. The adapter focuses solely on interacting with the pre-existing table structure.
|
|
268
268
|
- **Consistency via Interface:** While the underlying storage model differs, this adapter adheres to the same `MastraStorage` interface as other adapters, ensuring it can be used interchangeably within the Mastra `Memory` component.
|
|
269
269
|
|
|
270
270
|
### Mastra Data in the Single Table
|
|
271
271
|
|
|
272
|
-
Within the single DynamoDB table, different Mastra data entities (such as Threads, Messages, Traces, Evals, and Workflows) are managed and distinguished using ElectroDB. ElectroDB defines specific models for each entity type, which include unique key structures and attributes.
|
|
272
|
+
Within the single DynamoDB table, different Mastra data entities (such as Threads, Messages, Traces, Evals, and Workflows) are managed and distinguished using ElectroDB. ElectroDB defines specific models for each entity type, which include unique key structures and attributes. It allows the adapter to store and retrieve diverse data types efficiently within the same table.
|
|
273
273
|
|
|
274
|
-
For example, a `Thread` item might have a primary key like `THREAD#<threadId>`, while a `Message` item belonging to that thread might use `THREAD#<threadId>` as a partition key and `MESSAGE#<messageId>` as a sort key. The Global Secondary Indexes (GSIs), detailed in `TABLE_SETUP.md`, are strategically designed to support common access patterns across these different entities, such as fetching all messages for a thread or querying traces associated with a
|
|
274
|
+
For example, a `Thread` item might have a primary key like `THREAD#<threadId>`, while a `Message` item belonging to that thread might use `THREAD#<threadId>` as a partition key and `MESSAGE#<messageId>` as a sort key. The Global Secondary Indexes (GSIs), detailed in `TABLE_SETUP.md`, are strategically designed to support common access patterns across these different entities, such as fetching all messages for a thread or querying traces associated with a workflow.
|
|
275
275
|
|
|
276
276
|
### Advantages of Single-Table Design
|
|
277
277
|
|
|
@@ -279,6 +279,6 @@ This implementation uses a single-table design pattern with ElectroDB, which off
|
|
|
279
279
|
|
|
280
280
|
1. **Lower cost (potentially):** Fewer tables can simplify Read/Write Capacity Unit (RCU/WCU) provisioning and management, especially with on-demand capacity.
|
|
281
281
|
2. **Better performance:** Related data can be co-located or accessed efficiently through GSIs, enabling fast lookups for common access patterns.
|
|
282
|
-
3. **Simplified administration:** Fewer distinct tables to monitor
|
|
282
|
+
3. **Simplified administration:** Fewer distinct tables to monitor and back up, with less to manage.
|
|
283
283
|
4. **Reduced complexity in access patterns:** ElectroDB helps manage the complexity of item types and access patterns on a single table.
|
|
284
284
|
5. **Transaction support:** DynamoDB transactions can be used across different "entity" types stored within the same table if needed.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# MongoDB storage
|
|
4
4
|
|
|
5
|
-
The MongoDB storage implementation provides a
|
|
5
|
+
The MongoDB storage implementation provides a high-capacity storage solution using MongoDB databases with support for both document storage and vector operations.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -210,7 +210,7 @@ export const mongodbAgent = new Agent({
|
|
|
210
210
|
name: 'mongodb-agent',
|
|
211
211
|
instructions:
|
|
212
212
|
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
|
|
213
|
-
model: 'openai/gpt-5.
|
|
213
|
+
model: 'openai/gpt-5.6-sol',
|
|
214
214
|
memory: new Memory({
|
|
215
215
|
storage: new MongoDBStore({
|
|
216
216
|
id: 'mongodb-storage',
|
|
@@ -317,7 +317,7 @@ export const mastra = new Mastra({
|
|
|
317
317
|
})
|
|
318
318
|
```
|
|
319
319
|
|
|
320
|
-
|
|
320
|
+
The pattern ensures only one `PostgresStore` instance is created regardless of how many times the module is reloaded during development. The same pattern can be applied to other storage providers like `LibSQLStore`.
|
|
321
321
|
|
|
322
322
|
> **Tip:** This singleton pattern is only necessary during local development with HMR. In production builds, modules are only loaded once.
|
|
323
323
|
|
|
@@ -337,7 +337,7 @@ export const pgAgent = new Agent({
|
|
|
337
337
|
name: 'PG Agent',
|
|
338
338
|
instructions:
|
|
339
339
|
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
|
|
340
|
-
model: 'openai/gpt-5.
|
|
340
|
+
model: 'openai/gpt-5.6-sol',
|
|
341
341
|
memory: new Memory({
|
|
342
342
|
storage: new PostgresStore({
|
|
343
343
|
id: 'pg-agent-storage',
|
|
@@ -183,7 +183,7 @@ export const redisAgent = new Agent({
|
|
|
183
183
|
name: 'Redis Agent',
|
|
184
184
|
instructions:
|
|
185
185
|
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
|
|
186
|
-
model: 'openai/gpt-5.
|
|
186
|
+
model: 'openai/gpt-5.6-sol',
|
|
187
187
|
memory: new Memory({
|
|
188
188
|
storage: new RedisStore({
|
|
189
189
|
id: 'redis-agent-storage',
|
|
@@ -105,7 +105,7 @@ export const upstashAgent = new Agent({
|
|
|
105
105
|
name: 'Upstash Agent',
|
|
106
106
|
instructions:
|
|
107
107
|
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
|
|
108
|
-
model: 'openai/gpt-5.
|
|
108
|
+
model: 'openai/gpt-5.6-sol',
|
|
109
109
|
memory: new Memory({
|
|
110
110
|
storage: new UpstashStore({
|
|
111
111
|
id: 'upstash-agent-storage',
|
|
@@ -85,7 +85,7 @@ const results = await store.query({
|
|
|
85
85
|
|
|
86
86
|
### `createIndex()`
|
|
87
87
|
|
|
88
|
-
Creates a new vector collection. The index name must start with a letter or underscore and can only contain letters, numbers, and
|
|
88
|
+
Creates a new vector collection. The index name must start with a letter or underscore and can only contain letters, numbers, and underscore characters. The dimension must be a positive integer.
|
|
89
89
|
|
|
90
90
|
**indexName** (`string`): Name of the index to create
|
|
91
91
|
|
|
@@ -279,7 +279,7 @@ export const libsqlAgent = new Agent({
|
|
|
279
279
|
name: 'libSQL Agent',
|
|
280
280
|
instructions:
|
|
281
281
|
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
|
|
282
|
-
model: 'openai/gpt-5.
|
|
282
|
+
model: 'openai/gpt-5.6-sol',
|
|
283
283
|
memory: new Memory({
|
|
284
284
|
storage: new LibSQLStore({
|
|
285
285
|
id: 'libsql-agent-storage',
|