@mastra/memory 0.0.0-error-handler-fix-20251020202607 → 0.0.0-esbuild-bundle-worker-20260807182016
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 +4656 -3
- package/LICENSE.md +15 -0
- package/README.md +26 -1
- package/dist/_types/@internal_ai-sdk-v4/dist/index.d.ts +7450 -0
- package/dist/docs/SKILL.md +62 -0
- package/dist/docs/assets/SOURCE_MAP.json +11 -0
- package/dist/docs/references/docs-agents-agent-approval.md +664 -0
- package/dist/docs/references/docs-agents-networks.md +184 -0
- package/dist/docs/references/docs-capabilities-subagents.md +454 -0
- package/dist/docs/references/docs-evals-evals-with-memory.md +146 -0
- package/dist/docs/references/docs-long-running-agents-background-tasks.md +382 -0
- package/dist/docs/references/docs-long-running-agents-goals.md +118 -0
- package/dist/docs/references/docs-memory-memory-processors.md +385 -0
- package/dist/docs/references/docs-memory-message-history.md +348 -0
- package/dist/docs/references/docs-memory-multi-user-threads.md +208 -0
- package/dist/docs/references/docs-memory-observational-memory.md +835 -0
- package/dist/docs/references/docs-memory-overview.md +266 -0
- package/dist/docs/references/docs-memory-semantic-recall.md +401 -0
- package/dist/docs/references/docs-memory-working-memory.md +431 -0
- package/dist/docs/references/docs-storage-overview.md +214 -0
- package/dist/docs/references/reference-core-getMemory.md +51 -0
- package/dist/docs/references/reference-core-listMemory.md +57 -0
- package/dist/docs/references/reference-file-based-agents-memory.md +58 -0
- package/dist/docs/references/reference-memory-clone-utilities.md +203 -0
- package/dist/docs/references/reference-memory-cloneThread.md +173 -0
- package/dist/docs/references/reference-memory-createThread.md +70 -0
- package/dist/docs/references/reference-memory-getThreadById.md +26 -0
- package/dist/docs/references/reference-memory-listThreads.md +147 -0
- package/dist/docs/references/reference-memory-memory-class.md +148 -0
- package/dist/docs/references/reference-memory-observational-memory.md +877 -0
- package/dist/docs/references/reference-memory-summarizeConversation.md +99 -0
- package/dist/docs/references/reference-memory-summarizeThread.md +93 -0
- package/dist/docs/references/reference-processors-token-limiter-processor.md +158 -0
- package/dist/docs/references/reference-storage-dsql.md +430 -0
- package/dist/docs/references/reference-storage-dynamodb.md +284 -0
- package/dist/docs/references/reference-storage-libsql.md +143 -0
- package/dist/docs/references/reference-storage-mongodb.md +267 -0
- package/dist/docs/references/reference-storage-postgresql.md +531 -0
- package/dist/docs/references/reference-storage-redis.md +268 -0
- package/dist/docs/references/reference-storage-upstash.md +162 -0
- package/dist/docs/references/reference-vectors-libsql.md +307 -0
- package/dist/docs/references/reference-vectors-mongodb.md +567 -0
- package/dist/docs/references/reference-vectors-pg.md +430 -0
- package/dist/docs/references/reference-vectors-upstash.md +296 -0
- package/dist/index.cjs +35 -893
- package/dist/index.d.ts +465 -62
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -887
- package/dist/processors/index.cjs +32 -165
- package/dist/processors/index.d.ts +1 -2
- package/dist/processors/index.d.ts.map +1 -1
- package/dist/processors/index.js +2 -158
- package/dist/processors/observational-memory/activation-ttl.d.ts +4 -0
- package/dist/processors/observational-memory/activation-ttl.d.ts.map +1 -0
- package/dist/processors/observational-memory/anchor-ids.d.ts +4 -0
- package/dist/processors/observational-memory/anchor-ids.d.ts.map +1 -0
- package/dist/processors/observational-memory/buffering-coordinator.d.ts +61 -0
- package/dist/processors/observational-memory/buffering-coordinator.d.ts.map +1 -0
- package/dist/processors/observational-memory/built-in-extractors.d.ts +15 -0
- package/dist/processors/observational-memory/built-in-extractors.d.ts.map +1 -0
- package/dist/processors/observational-memory/constants.d.ts +74 -0
- package/dist/processors/observational-memory/constants.d.ts.map +1 -0
- package/dist/processors/observational-memory/date-utils.d.ts +41 -0
- package/dist/processors/observational-memory/date-utils.d.ts.map +1 -0
- package/dist/processors/observational-memory/debug.d.ts +3 -0
- package/dist/processors/observational-memory/debug.d.ts.map +1 -0
- package/dist/processors/observational-memory/extracted-values.d.ts +44 -0
- package/dist/processors/observational-memory/extracted-values.d.ts.map +1 -0
- package/dist/processors/observational-memory/extraction-runner.d.ts +22 -0
- package/dist/processors/observational-memory/extraction-runner.d.ts.map +1 -0
- package/dist/processors/observational-memory/extractor.d.ts +76 -0
- package/dist/processors/observational-memory/extractor.d.ts.map +1 -0
- package/dist/processors/observational-memory/index.d.ts +30 -0
- package/dist/processors/observational-memory/index.d.ts.map +1 -0
- package/dist/processors/observational-memory/internal-request-context.d.ts +17 -0
- package/dist/processors/observational-memory/internal-request-context.d.ts.map +1 -0
- package/dist/processors/observational-memory/markers.d.ts +118 -0
- package/dist/processors/observational-memory/markers.d.ts.map +1 -0
- package/dist/processors/observational-memory/message-utils.d.ts +83 -0
- package/dist/processors/observational-memory/message-utils.d.ts.map +1 -0
- package/dist/processors/observational-memory/model-by-input-tokens.d.ts +14 -0
- package/dist/processors/observational-memory/model-by-input-tokens.d.ts.map +1 -0
- package/dist/processors/observational-memory/model-context.d.ts +2 -0
- package/dist/processors/observational-memory/model-context.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-groups.d.ts +15 -0
- package/dist/processors/observational-memory/observation-groups.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/async-buffer.d.ts +39 -0
- package/dist/processors/observational-memory/observation-strategies/async-buffer.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/base.d.ts +122 -0
- package/dist/processors/observational-memory/observation-strategies/base.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/index.d.ts +7 -0
- package/dist/processors/observational-memory/observation-strategies/index.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts +43 -0
- package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/sync.d.ts +41 -0
- package/dist/processors/observational-memory/observation-strategies/sync.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/types.d.ts +103 -0
- package/dist/processors/observational-memory/observation-strategies/types.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/index.d.ts +4 -0
- package/dist/processors/observational-memory/observation-turn/index.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/load-memory-context.d.ts +9 -0
- package/dist/processors/observational-memory/observation-turn/load-memory-context.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/step.d.ts +53 -0
- package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/turn.d.ts +139 -0
- package/dist/processors/observational-memory/observation-turn/turn.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/types.d.ts +46 -0
- package/dist/processors/observational-memory/observation-turn/types.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-utils.d.ts +16 -0
- package/dist/processors/observational-memory/observation-utils.d.ts.map +1 -0
- package/dist/processors/observational-memory/observational-memory.d.ts +930 -0
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -0
- package/dist/processors/observational-memory/observer-agent.d.ts +190 -0
- package/dist/processors/observational-memory/observer-agent.d.ts.map +1 -0
- package/dist/processors/observational-memory/observer-runner.d.ts +141 -0
- package/dist/processors/observational-memory/observer-runner.d.ts.map +1 -0
- package/dist/processors/observational-memory/operation-registry.d.ts +14 -0
- package/dist/processors/observational-memory/operation-registry.d.ts.map +1 -0
- package/dist/processors/observational-memory/processor.d.ts +70 -0
- package/dist/processors/observational-memory/processor.d.ts.map +1 -0
- package/dist/processors/observational-memory/reflector-agent.d.ts +62 -0
- package/dist/processors/observational-memory/reflector-agent.d.ts.map +1 -0
- package/dist/processors/observational-memory/reflector-runner.d.ts +133 -0
- package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -0
- package/dist/processors/observational-memory/repro-capture.d.ts +33 -0
- package/dist/processors/observational-memory/repro-capture.d.ts.map +1 -0
- package/dist/processors/observational-memory/retry.d.ts +63 -0
- package/dist/processors/observational-memory/retry.d.ts.map +1 -0
- package/dist/processors/observational-memory/string-utils.d.ts +13 -0
- package/dist/processors/observational-memory/string-utils.d.ts.map +1 -0
- package/dist/processors/observational-memory/summarize.d.ts +92 -0
- package/dist/processors/observational-memory/summarize.d.ts.map +1 -0
- package/dist/processors/observational-memory/temporal-markers.d.ts +4 -0
- package/dist/processors/observational-memory/temporal-markers.d.ts.map +1 -0
- package/dist/processors/observational-memory/temporary-memory.d.ts +8 -0
- package/dist/processors/observational-memory/temporary-memory.d.ts.map +1 -0
- package/dist/processors/observational-memory/thresholds.d.ts +52 -0
- package/dist/processors/observational-memory/thresholds.d.ts.map +1 -0
- package/dist/processors/observational-memory/token-counter.d.ts +57 -0
- package/dist/processors/observational-memory/token-counter.d.ts.map +1 -0
- package/dist/processors/observational-memory/tool-result-helpers.d.ts +12 -0
- package/dist/processors/observational-memory/tool-result-helpers.d.ts.map +1 -0
- package/dist/processors/observational-memory/tracing.d.ts +17 -0
- package/dist/processors/observational-memory/tracing.d.ts.map +1 -0
- package/dist/processors/observational-memory/types.d.ts +997 -0
- package/dist/processors/observational-memory/types.d.ts.map +1 -0
- package/dist/processors/observational-memory/working-memory-extractor.d.ts +5 -0
- package/dist/processors/observational-memory/working-memory-extractor.d.ts.map +1 -0
- package/dist/processors/working-memory-state/index.d.ts +2 -0
- package/dist/processors/working-memory-state/index.d.ts.map +1 -0
- package/dist/processors/working-memory-state/processor.d.ts +53 -0
- package/dist/processors/working-memory-state/processor.d.ts.map +1 -0
- package/dist/src-C1tlhGeW.js +28559 -0
- package/dist/src-C1tlhGeW.js.map +1 -0
- package/dist/src-DqoifKIy.cjs +28813 -0
- package/dist/src-DqoifKIy.cjs.map +1 -0
- package/dist/tools/om-tools.d.ts +172 -0
- package/dist/tools/om-tools.d.ts.map +1 -0
- package/dist/tools/working-memory.d.ts +33 -28
- package/dist/tools/working-memory.d.ts.map +1 -1
- package/package.json +36 -28
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/processors/index.cjs.map +0 -1
- package/dist/processors/index.js.map +0 -1
- package/dist/processors/token-limiter.d.ts +0 -32
- package/dist/processors/token-limiter.d.ts.map +0 -1
- package/dist/processors/tool-call-filter.d.ts +0 -20
- package/dist/processors/tool-call-filter.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,893 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
execute: async (params) => {
|
|
37
|
-
const { context, threadId, memory, resourceId } = params;
|
|
38
|
-
if (!threadId || !memory || !resourceId) {
|
|
39
|
-
throw new Error("Thread ID, Memory instance, and resourceId are required for working memory updates");
|
|
40
|
-
}
|
|
41
|
-
let thread = await memory.getThreadById({ threadId });
|
|
42
|
-
if (!thread) {
|
|
43
|
-
thread = await memory.createThread({
|
|
44
|
-
threadId,
|
|
45
|
-
resourceId,
|
|
46
|
-
memoryConfig
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
if (thread.resourceId && thread.resourceId !== resourceId) {
|
|
50
|
-
throw new Error(`Thread with id ${threadId} resourceId does not match the current resourceId ${resourceId}`);
|
|
51
|
-
}
|
|
52
|
-
const workingMemory = typeof context.memory === "string" ? context.memory : JSON.stringify(context.memory);
|
|
53
|
-
await memory.updateWorkingMemory({
|
|
54
|
-
threadId,
|
|
55
|
-
resourceId,
|
|
56
|
-
workingMemory,
|
|
57
|
-
memoryConfig
|
|
58
|
-
});
|
|
59
|
-
return { success: true };
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
|
-
var __experimental_updateWorkingMemoryToolVNext = (config) => {
|
|
64
|
-
return tools.createTool({
|
|
65
|
-
id: "update-working-memory",
|
|
66
|
-
description: "Update the working memory with new information.",
|
|
67
|
-
inputSchema: zod.z.object({
|
|
68
|
-
newMemory: zod.z.string().optional().describe(
|
|
69
|
-
`The ${config.workingMemory?.schema ? "JSON" : "Markdown"} formatted working memory content to store`
|
|
70
|
-
),
|
|
71
|
-
searchString: zod.z.string().optional().describe(
|
|
72
|
-
"The working memory string to find. Will be replaced with the newMemory string. If this is omitted or doesn't exist, the newMemory string will be appended to the end of your working memory. Replacing single lines at a time is encouraged for greater accuracy. If updateReason is not 'append-new-memory', this search string must be provided or the tool call will be rejected."
|
|
73
|
-
),
|
|
74
|
-
updateReason: zod.z.enum(["append-new-memory", "clarify-existing-memory", "replace-irrelevant-memory"]).optional().describe(
|
|
75
|
-
"The reason you're updating working memory. Passing any value other than 'append-new-memory' requires a searchString to be provided. Defaults to append-new-memory"
|
|
76
|
-
)
|
|
77
|
-
}),
|
|
78
|
-
execute: async (params) => {
|
|
79
|
-
const { context, threadId, memory, resourceId } = params;
|
|
80
|
-
if (!threadId || !memory || !resourceId) {
|
|
81
|
-
throw new Error("Thread ID, Memory instance, and resourceId are required for working memory updates");
|
|
82
|
-
}
|
|
83
|
-
let thread = await memory.getThreadById({ threadId });
|
|
84
|
-
if (!thread) {
|
|
85
|
-
thread = await memory.createThread({
|
|
86
|
-
threadId,
|
|
87
|
-
resourceId,
|
|
88
|
-
memoryConfig: config
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
if (thread.resourceId && thread.resourceId !== resourceId) {
|
|
92
|
-
throw new Error(`Thread with id ${threadId} resourceId does not match the current resourceId ${resourceId}`);
|
|
93
|
-
}
|
|
94
|
-
const workingMemory = context.newMemory || "";
|
|
95
|
-
if (!context.updateReason) context.updateReason = `append-new-memory`;
|
|
96
|
-
if (context.searchString && config.workingMemory?.scope === `resource` && context.updateReason === `replace-irrelevant-memory`) {
|
|
97
|
-
context.searchString = void 0;
|
|
98
|
-
}
|
|
99
|
-
if (context.updateReason === `append-new-memory` && context.searchString) {
|
|
100
|
-
context.searchString = void 0;
|
|
101
|
-
}
|
|
102
|
-
if (context.updateReason !== `append-new-memory` && !context.searchString) {
|
|
103
|
-
return {
|
|
104
|
-
success: false,
|
|
105
|
-
reason: `updateReason was ${context.updateReason} but no searchString was provided. Unable to replace undefined with "${context.newMemory}"`
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
const result = await memory.__experimental_updateWorkingMemoryVNext({
|
|
109
|
-
threadId,
|
|
110
|
-
resourceId,
|
|
111
|
-
workingMemory,
|
|
112
|
-
searchString: context.searchString,
|
|
113
|
-
memoryConfig: config
|
|
114
|
-
});
|
|
115
|
-
if (result) {
|
|
116
|
-
return result;
|
|
117
|
-
}
|
|
118
|
-
return { success: true };
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
// src/index.ts
|
|
124
|
-
var CHARS_PER_TOKEN = 4;
|
|
125
|
-
var DEFAULT_MESSAGE_RANGE = { before: 2, after: 2 };
|
|
126
|
-
var DEFAULT_TOP_K = 2;
|
|
127
|
-
var isZodObject = (v) => v instanceof zod.ZodObject;
|
|
128
|
-
var Memory = class extends memory.MastraMemory {
|
|
129
|
-
constructor(config = {}) {
|
|
130
|
-
super({ name: "Memory", ...config });
|
|
131
|
-
const mergedConfig = this.getMergedThreadConfig({
|
|
132
|
-
workingMemory: config.options?.workingMemory || {
|
|
133
|
-
// these defaults are now set inside @mastra/core/memory in getMergedThreadConfig.
|
|
134
|
-
// In a future release we can remove it from this block - for now if we remove it
|
|
135
|
-
// and someone bumps @mastra/memory without bumping @mastra/core the defaults wouldn't exist yet
|
|
136
|
-
enabled: false,
|
|
137
|
-
template: this.defaultWorkingMemoryTemplate
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
this.threadConfig = mergedConfig;
|
|
141
|
-
}
|
|
142
|
-
async validateThreadIsOwnedByResource(threadId, resourceId, config) {
|
|
143
|
-
const resourceScope = typeof config?.semanticRecall === "object" && config?.semanticRecall?.scope === "resource";
|
|
144
|
-
const thread = await this.storage.getThreadById({ threadId });
|
|
145
|
-
if (!thread && !resourceScope) {
|
|
146
|
-
throw new Error(`No thread found with id ${threadId}`);
|
|
147
|
-
}
|
|
148
|
-
if (thread && thread.resourceId !== resourceId) {
|
|
149
|
-
throw new Error(
|
|
150
|
-
`Thread with id ${threadId} is for resource with id ${thread.resourceId} but resource ${resourceId} was queried.`
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
checkStorageFeatureSupport(config) {
|
|
155
|
-
if (typeof config.semanticRecall === `object` && config.semanticRecall.scope === `resource` && !this.storage.supports.selectByIncludeResourceScope) {
|
|
156
|
-
throw new Error(
|
|
157
|
-
`Memory error: Attached storage adapter "${this.storage.name || "unknown"}" doesn't support semanticRecall: { scope: "resource" } yet and currently only supports per-thread semantic recall.`
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
if (config.workingMemory?.enabled && config.workingMemory.scope === `resource` && !this.storage.supports.resourceWorkingMemory) {
|
|
161
|
-
throw new Error(
|
|
162
|
-
`Memory error: Attached storage adapter "${this.storage.name || "unknown"}" doesn't support workingMemory: { scope: "resource" } yet and currently only supports per-thread working memory. Supported adapters: LibSQL, PostgreSQL, Upstash.`
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
async query({
|
|
167
|
-
threadId,
|
|
168
|
-
resourceId,
|
|
169
|
-
selectBy,
|
|
170
|
-
threadConfig
|
|
171
|
-
}) {
|
|
172
|
-
const config = this.getMergedThreadConfig(threadConfig || {});
|
|
173
|
-
if (resourceId) await this.validateThreadIsOwnedByResource(threadId, resourceId, config);
|
|
174
|
-
const vectorResults = [];
|
|
175
|
-
this.logger.debug(`Memory query() with:`, {
|
|
176
|
-
threadId,
|
|
177
|
-
selectBy,
|
|
178
|
-
threadConfig
|
|
179
|
-
});
|
|
180
|
-
this.checkStorageFeatureSupport(config);
|
|
181
|
-
const defaultRange = DEFAULT_MESSAGE_RANGE;
|
|
182
|
-
const defaultTopK = DEFAULT_TOP_K;
|
|
183
|
-
const vectorConfig = typeof config?.semanticRecall === `boolean` ? {
|
|
184
|
-
topK: defaultTopK,
|
|
185
|
-
messageRange: defaultRange
|
|
186
|
-
} : {
|
|
187
|
-
topK: config?.semanticRecall?.topK ?? defaultTopK,
|
|
188
|
-
messageRange: config?.semanticRecall?.messageRange ?? defaultRange
|
|
189
|
-
};
|
|
190
|
-
const resourceScope = typeof config?.semanticRecall === "object" && config?.semanticRecall?.scope === `resource`;
|
|
191
|
-
if (config?.semanticRecall && selectBy?.vectorSearchString && this.vector) {
|
|
192
|
-
const { embeddings, dimension } = await this.embedMessageContent(selectBy.vectorSearchString);
|
|
193
|
-
const { indexName } = await this.createEmbeddingIndex(dimension, config);
|
|
194
|
-
await Promise.all(
|
|
195
|
-
embeddings.map(async (embedding) => {
|
|
196
|
-
if (typeof this.vector === `undefined`) {
|
|
197
|
-
throw new Error(
|
|
198
|
-
`Tried to query vector index ${indexName} but this Memory instance doesn't have an attached vector db.`
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
vectorResults.push(
|
|
202
|
-
...await this.vector.query({
|
|
203
|
-
indexName,
|
|
204
|
-
queryVector: embedding,
|
|
205
|
-
topK: vectorConfig.topK,
|
|
206
|
-
filter: resourceScope ? {
|
|
207
|
-
resource_id: resourceId
|
|
208
|
-
} : {
|
|
209
|
-
thread_id: threadId
|
|
210
|
-
}
|
|
211
|
-
})
|
|
212
|
-
);
|
|
213
|
-
})
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
let rawMessages;
|
|
217
|
-
if (selectBy?.pagination) {
|
|
218
|
-
const paginatedResult = await this.storage.getMessagesPaginated({
|
|
219
|
-
threadId,
|
|
220
|
-
resourceId,
|
|
221
|
-
format: "v2",
|
|
222
|
-
selectBy: {
|
|
223
|
-
...selectBy,
|
|
224
|
-
...vectorResults?.length ? {
|
|
225
|
-
include: vectorResults.map((r) => ({
|
|
226
|
-
id: r.metadata?.message_id,
|
|
227
|
-
threadId: r.metadata?.thread_id,
|
|
228
|
-
withNextMessages: typeof vectorConfig.messageRange === "number" ? vectorConfig.messageRange : vectorConfig.messageRange.after,
|
|
229
|
-
withPreviousMessages: typeof vectorConfig.messageRange === "number" ? vectorConfig.messageRange : vectorConfig.messageRange.before
|
|
230
|
-
}))
|
|
231
|
-
} : {}
|
|
232
|
-
},
|
|
233
|
-
threadConfig: config
|
|
234
|
-
});
|
|
235
|
-
rawMessages = paginatedResult.messages;
|
|
236
|
-
} else {
|
|
237
|
-
rawMessages = await this.storage.getMessages({
|
|
238
|
-
threadId,
|
|
239
|
-
resourceId,
|
|
240
|
-
format: "v2",
|
|
241
|
-
selectBy: {
|
|
242
|
-
...selectBy,
|
|
243
|
-
...vectorResults?.length ? {
|
|
244
|
-
include: vectorResults.map((r) => ({
|
|
245
|
-
id: r.metadata?.message_id,
|
|
246
|
-
threadId: r.metadata?.thread_id,
|
|
247
|
-
withNextMessages: typeof vectorConfig.messageRange === "number" ? vectorConfig.messageRange : vectorConfig.messageRange.after,
|
|
248
|
-
withPreviousMessages: typeof vectorConfig.messageRange === "number" ? vectorConfig.messageRange : vectorConfig.messageRange.before
|
|
249
|
-
}))
|
|
250
|
-
} : {}
|
|
251
|
-
},
|
|
252
|
-
threadConfig: config
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
const list = new agent.MessageList({ threadId, resourceId }).add(rawMessages, "memory");
|
|
256
|
-
return {
|
|
257
|
-
get messages() {
|
|
258
|
-
const v1Messages = list.get.all.v1();
|
|
259
|
-
if (selectBy?.last && v1Messages.length > selectBy.last) {
|
|
260
|
-
return v1Messages.slice(v1Messages.length - selectBy.last);
|
|
261
|
-
}
|
|
262
|
-
return v1Messages;
|
|
263
|
-
},
|
|
264
|
-
get uiMessages() {
|
|
265
|
-
return list.get.all.ui();
|
|
266
|
-
},
|
|
267
|
-
get messagesV2() {
|
|
268
|
-
return list.get.all.v2();
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
async rememberMessages({
|
|
273
|
-
threadId,
|
|
274
|
-
resourceId,
|
|
275
|
-
vectorMessageSearch,
|
|
276
|
-
config
|
|
277
|
-
}) {
|
|
278
|
-
const threadConfig = this.getMergedThreadConfig(config || {});
|
|
279
|
-
if (resourceId) await this.validateThreadIsOwnedByResource(threadId, resourceId, threadConfig);
|
|
280
|
-
if (!threadConfig.lastMessages && !threadConfig.semanticRecall) {
|
|
281
|
-
return {
|
|
282
|
-
messages: [],
|
|
283
|
-
messagesV2: []
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
const messagesResult = await this.query({
|
|
287
|
-
resourceId,
|
|
288
|
-
threadId,
|
|
289
|
-
selectBy: {
|
|
290
|
-
last: threadConfig.lastMessages,
|
|
291
|
-
vectorSearchString: threadConfig.semanticRecall && vectorMessageSearch ? vectorMessageSearch : void 0
|
|
292
|
-
},
|
|
293
|
-
threadConfig: config,
|
|
294
|
-
format: "v2"
|
|
295
|
-
});
|
|
296
|
-
const list = new agent.MessageList({ threadId, resourceId }).add(messagesResult.messagesV2, "memory");
|
|
297
|
-
this.logger.debug(`Remembered message history includes ${messagesResult.messages.length} messages.`);
|
|
298
|
-
return { messages: list.get.all.v1(), messagesV2: list.get.all.v2() };
|
|
299
|
-
}
|
|
300
|
-
async getThreadById({ threadId }) {
|
|
301
|
-
return this.storage.getThreadById({ threadId });
|
|
302
|
-
}
|
|
303
|
-
async getThreadsByResourceId({
|
|
304
|
-
resourceId,
|
|
305
|
-
orderBy,
|
|
306
|
-
sortDirection
|
|
307
|
-
}) {
|
|
308
|
-
return this.storage.getThreadsByResourceId({ resourceId, orderBy, sortDirection });
|
|
309
|
-
}
|
|
310
|
-
async getThreadsByResourceIdPaginated({
|
|
311
|
-
resourceId,
|
|
312
|
-
page,
|
|
313
|
-
perPage,
|
|
314
|
-
orderBy,
|
|
315
|
-
sortDirection
|
|
316
|
-
}) {
|
|
317
|
-
return this.storage.getThreadsByResourceIdPaginated({
|
|
318
|
-
resourceId,
|
|
319
|
-
page,
|
|
320
|
-
perPage,
|
|
321
|
-
orderBy,
|
|
322
|
-
sortDirection
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
async handleWorkingMemoryFromMetadata({
|
|
326
|
-
workingMemory,
|
|
327
|
-
resourceId,
|
|
328
|
-
memoryConfig
|
|
329
|
-
}) {
|
|
330
|
-
const config = this.getMergedThreadConfig(memoryConfig || {});
|
|
331
|
-
if (config.workingMemory?.enabled) {
|
|
332
|
-
this.checkStorageFeatureSupport(config);
|
|
333
|
-
const scope = config.workingMemory.scope || "thread";
|
|
334
|
-
if (scope === "resource" && resourceId) {
|
|
335
|
-
await this.storage.updateResource({
|
|
336
|
-
resourceId,
|
|
337
|
-
workingMemory
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
async saveThread({
|
|
343
|
-
thread,
|
|
344
|
-
memoryConfig
|
|
345
|
-
}) {
|
|
346
|
-
const savedThread = await this.storage.saveThread({ thread });
|
|
347
|
-
if (thread.metadata?.workingMemory && typeof thread.metadata.workingMemory === "string" && thread.resourceId) {
|
|
348
|
-
await this.handleWorkingMemoryFromMetadata({
|
|
349
|
-
workingMemory: thread.metadata.workingMemory,
|
|
350
|
-
resourceId: thread.resourceId,
|
|
351
|
-
memoryConfig
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
return savedThread;
|
|
355
|
-
}
|
|
356
|
-
async updateThread({
|
|
357
|
-
id,
|
|
358
|
-
title,
|
|
359
|
-
metadata,
|
|
360
|
-
memoryConfig
|
|
361
|
-
}) {
|
|
362
|
-
const updatedThread = await this.storage.updateThread({
|
|
363
|
-
id,
|
|
364
|
-
title,
|
|
365
|
-
metadata
|
|
366
|
-
});
|
|
367
|
-
if (metadata?.workingMemory && typeof metadata.workingMemory === "string" && updatedThread.resourceId) {
|
|
368
|
-
await this.handleWorkingMemoryFromMetadata({
|
|
369
|
-
workingMemory: metadata.workingMemory,
|
|
370
|
-
resourceId: updatedThread.resourceId,
|
|
371
|
-
memoryConfig
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
return updatedThread;
|
|
375
|
-
}
|
|
376
|
-
async deleteThread(threadId) {
|
|
377
|
-
await this.storage.deleteThread({ threadId });
|
|
378
|
-
}
|
|
379
|
-
async updateWorkingMemory({
|
|
380
|
-
threadId,
|
|
381
|
-
resourceId,
|
|
382
|
-
workingMemory,
|
|
383
|
-
memoryConfig
|
|
384
|
-
}) {
|
|
385
|
-
const config = this.getMergedThreadConfig(memoryConfig || {});
|
|
386
|
-
if (!config.workingMemory?.enabled) {
|
|
387
|
-
throw new Error("Working memory is not enabled for this memory instance");
|
|
388
|
-
}
|
|
389
|
-
this.checkStorageFeatureSupport(config);
|
|
390
|
-
const scope = config.workingMemory.scope || "thread";
|
|
391
|
-
if (scope === "resource" && resourceId) {
|
|
392
|
-
await this.storage.updateResource({
|
|
393
|
-
resourceId,
|
|
394
|
-
workingMemory
|
|
395
|
-
});
|
|
396
|
-
} else {
|
|
397
|
-
const thread = await this.storage.getThreadById({ threadId });
|
|
398
|
-
if (!thread) {
|
|
399
|
-
throw new Error(`Thread ${threadId} not found`);
|
|
400
|
-
}
|
|
401
|
-
await this.storage.updateThread({
|
|
402
|
-
id: threadId,
|
|
403
|
-
title: thread.title || "Untitled Thread",
|
|
404
|
-
metadata: {
|
|
405
|
-
...thread.metadata,
|
|
406
|
-
workingMemory
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
updateWorkingMemoryMutexes = /* @__PURE__ */ new Map();
|
|
412
|
-
/**
|
|
413
|
-
* @warning experimental! can be removed or changed at any time
|
|
414
|
-
*/
|
|
415
|
-
async __experimental_updateWorkingMemoryVNext({
|
|
416
|
-
threadId,
|
|
417
|
-
resourceId,
|
|
418
|
-
workingMemory,
|
|
419
|
-
searchString,
|
|
420
|
-
memoryConfig
|
|
421
|
-
}) {
|
|
422
|
-
const config = this.getMergedThreadConfig(memoryConfig || {});
|
|
423
|
-
if (!config.workingMemory?.enabled) {
|
|
424
|
-
throw new Error("Working memory is not enabled for this memory instance");
|
|
425
|
-
}
|
|
426
|
-
this.checkStorageFeatureSupport(config);
|
|
427
|
-
const mutexKey = memoryConfig?.workingMemory?.scope === `resource` ? `resource-${resourceId}` : `thread-${threadId}`;
|
|
428
|
-
const mutex = this.updateWorkingMemoryMutexes.has(mutexKey) ? this.updateWorkingMemoryMutexes.get(mutexKey) : new asyncMutex.Mutex();
|
|
429
|
-
this.updateWorkingMemoryMutexes.set(mutexKey, mutex);
|
|
430
|
-
const release = await mutex.acquire();
|
|
431
|
-
try {
|
|
432
|
-
const existingWorkingMemory = await this.getWorkingMemory({ threadId, resourceId, memoryConfig }) || "";
|
|
433
|
-
const template = await this.getWorkingMemoryTemplate({ memoryConfig });
|
|
434
|
-
let reason = "";
|
|
435
|
-
if (existingWorkingMemory) {
|
|
436
|
-
if (searchString && existingWorkingMemory?.includes(searchString)) {
|
|
437
|
-
workingMemory = existingWorkingMemory.replace(searchString, workingMemory);
|
|
438
|
-
reason = `found and replaced searchString with newMemory`;
|
|
439
|
-
} else if (existingWorkingMemory.includes(workingMemory) || template?.content?.trim() === workingMemory.trim()) {
|
|
440
|
-
return {
|
|
441
|
-
success: false,
|
|
442
|
-
reason: `attempted to insert duplicate data into working memory. this entry was skipped`
|
|
443
|
-
};
|
|
444
|
-
} else {
|
|
445
|
-
if (searchString) {
|
|
446
|
-
reason = `attempted to replace working memory string that doesn't exist. Appending to working memory instead.`;
|
|
447
|
-
} else {
|
|
448
|
-
reason = `appended newMemory to end of working memory`;
|
|
449
|
-
}
|
|
450
|
-
workingMemory = existingWorkingMemory + `
|
|
451
|
-
${workingMemory}`;
|
|
452
|
-
}
|
|
453
|
-
} else if (workingMemory === template?.content) {
|
|
454
|
-
return {
|
|
455
|
-
success: false,
|
|
456
|
-
reason: `try again when you have data to add. newMemory was equal to the working memory template`
|
|
457
|
-
};
|
|
458
|
-
} else {
|
|
459
|
-
reason = `started new working memory`;
|
|
460
|
-
}
|
|
461
|
-
workingMemory = template?.content ? workingMemory.replaceAll(template?.content, "") : workingMemory;
|
|
462
|
-
const scope = config.workingMemory.scope || "thread";
|
|
463
|
-
if (scope === "resource" && resourceId) {
|
|
464
|
-
await this.storage.updateResource({
|
|
465
|
-
resourceId,
|
|
466
|
-
workingMemory
|
|
467
|
-
});
|
|
468
|
-
if (reason) {
|
|
469
|
-
return { success: true, reason };
|
|
470
|
-
}
|
|
471
|
-
} else {
|
|
472
|
-
const thread = await this.storage.getThreadById({ threadId });
|
|
473
|
-
if (!thread) {
|
|
474
|
-
throw new Error(`Thread ${threadId} not found`);
|
|
475
|
-
}
|
|
476
|
-
await this.storage.updateThread({
|
|
477
|
-
id: threadId,
|
|
478
|
-
title: thread.title || "Untitled Thread",
|
|
479
|
-
metadata: {
|
|
480
|
-
...thread.metadata,
|
|
481
|
-
workingMemory
|
|
482
|
-
}
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
|
-
return { success: true, reason };
|
|
486
|
-
} catch (e) {
|
|
487
|
-
this.logger.error(e instanceof Error ? e.stack || e.message : JSON.stringify(e));
|
|
488
|
-
return { success: false, reason: "Tool error." };
|
|
489
|
-
} finally {
|
|
490
|
-
release();
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
chunkText(text, tokenSize = 4096) {
|
|
494
|
-
const charSize = tokenSize * CHARS_PER_TOKEN;
|
|
495
|
-
const chunks = [];
|
|
496
|
-
let currentChunk = "";
|
|
497
|
-
const words = text.split(/\s+/);
|
|
498
|
-
for (const word of words) {
|
|
499
|
-
const wordWithSpace = currentChunk ? " " + word : word;
|
|
500
|
-
if (currentChunk.length + wordWithSpace.length > charSize) {
|
|
501
|
-
chunks.push(currentChunk);
|
|
502
|
-
currentChunk = word;
|
|
503
|
-
} else {
|
|
504
|
-
currentChunk += wordWithSpace;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
if (currentChunk) {
|
|
508
|
-
chunks.push(currentChunk);
|
|
509
|
-
}
|
|
510
|
-
return chunks;
|
|
511
|
-
}
|
|
512
|
-
hasher = xxhash__default.default();
|
|
513
|
-
// embedding is computationally expensive so cache content -> embeddings/chunks
|
|
514
|
-
embeddingCache = /* @__PURE__ */ new Map();
|
|
515
|
-
firstEmbed;
|
|
516
|
-
async embedMessageContent(content) {
|
|
517
|
-
const key = (await this.hasher).h32(content);
|
|
518
|
-
const cached = this.embeddingCache.get(key);
|
|
519
|
-
if (cached) return cached;
|
|
520
|
-
const chunks = this.chunkText(content);
|
|
521
|
-
if (typeof this.embedder === `undefined`) {
|
|
522
|
-
throw new Error(`Tried to embed message content but this Memory instance doesn't have an attached embedder.`);
|
|
523
|
-
}
|
|
524
|
-
const isFastEmbed = this.embedder.provider === `fastembed`;
|
|
525
|
-
if (isFastEmbed && this.firstEmbed instanceof Promise) {
|
|
526
|
-
await this.firstEmbed;
|
|
527
|
-
}
|
|
528
|
-
const promise = (this.embedder.specificationVersion === `v2` ? aiV5.embedMany : ai.embedMany)({
|
|
529
|
-
values: chunks,
|
|
530
|
-
maxRetries: 3,
|
|
531
|
-
// @ts-ignore
|
|
532
|
-
model: this.embedder
|
|
533
|
-
});
|
|
534
|
-
if (isFastEmbed && !this.firstEmbed) this.firstEmbed = promise;
|
|
535
|
-
const { embeddings } = await promise;
|
|
536
|
-
const result = {
|
|
537
|
-
embeddings,
|
|
538
|
-
chunks,
|
|
539
|
-
dimension: embeddings[0]?.length
|
|
540
|
-
};
|
|
541
|
-
this.embeddingCache.set(key, result);
|
|
542
|
-
return result;
|
|
543
|
-
}
|
|
544
|
-
async saveMessages({
|
|
545
|
-
messages,
|
|
546
|
-
memoryConfig,
|
|
547
|
-
format = `v1`
|
|
548
|
-
}) {
|
|
549
|
-
const updatedMessages = messages.map((m) => {
|
|
550
|
-
if (agent.MessageList.isMastraMessageV1(m)) {
|
|
551
|
-
return this.updateMessageToHideWorkingMemory(m);
|
|
552
|
-
}
|
|
553
|
-
if (!m.type) m.type = `v2`;
|
|
554
|
-
return this.updateMessageToHideWorkingMemoryV2(m);
|
|
555
|
-
}).filter((m) => Boolean(m));
|
|
556
|
-
const config = this.getMergedThreadConfig(memoryConfig);
|
|
557
|
-
const result = this.storage.saveMessages({
|
|
558
|
-
messages: new agent.MessageList().add(updatedMessages, "memory").get.all.v2(),
|
|
559
|
-
format: "v2"
|
|
560
|
-
});
|
|
561
|
-
if (this.vector && config.semanticRecall) {
|
|
562
|
-
let indexName;
|
|
563
|
-
await Promise.all(
|
|
564
|
-
updatedMessages.map(async (message) => {
|
|
565
|
-
let textForEmbedding = null;
|
|
566
|
-
if (agent.MessageList.isMastraMessageV2(message)) {
|
|
567
|
-
if (message.content.content && typeof message.content.content === "string" && message.content.content.trim() !== "") {
|
|
568
|
-
textForEmbedding = message.content.content;
|
|
569
|
-
} else if (message.content.parts && message.content.parts.length > 0) {
|
|
570
|
-
const joined = message.content.parts.filter((part) => part.type === "text").map((part) => part.text).join(" ").trim();
|
|
571
|
-
if (joined) textForEmbedding = joined;
|
|
572
|
-
}
|
|
573
|
-
} else if (agent.MessageList.isMastraMessageV1(message)) {
|
|
574
|
-
if (message.content && typeof message.content === "string" && message.content.trim() !== "") {
|
|
575
|
-
textForEmbedding = message.content;
|
|
576
|
-
} else if (message.content && Array.isArray(message.content) && message.content.length > 0) {
|
|
577
|
-
const joined = message.content.filter((part) => part.type === "text").map((part) => part.text).join(" ").trim();
|
|
578
|
-
if (joined) textForEmbedding = joined;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
if (!textForEmbedding) return;
|
|
582
|
-
const { embeddings, chunks, dimension } = await this.embedMessageContent(textForEmbedding);
|
|
583
|
-
if (typeof indexName === `undefined`) {
|
|
584
|
-
indexName = this.createEmbeddingIndex(dimension, config).then((result2) => result2.indexName);
|
|
585
|
-
}
|
|
586
|
-
if (typeof this.vector === `undefined`) {
|
|
587
|
-
throw new Error(
|
|
588
|
-
`Tried to upsert embeddings to index ${indexName} but this Memory instance doesn't have an attached vector db.`
|
|
589
|
-
);
|
|
590
|
-
}
|
|
591
|
-
await this.vector.upsert({
|
|
592
|
-
indexName: await indexName,
|
|
593
|
-
vectors: embeddings,
|
|
594
|
-
metadata: chunks.map(() => ({
|
|
595
|
-
message_id: message.id,
|
|
596
|
-
thread_id: message.threadId,
|
|
597
|
-
resource_id: message.resourceId
|
|
598
|
-
}))
|
|
599
|
-
});
|
|
600
|
-
})
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
if (format === `v1`) return new agent.MessageList().add(await result, "memory").get.all.v1();
|
|
604
|
-
return result;
|
|
605
|
-
}
|
|
606
|
-
updateMessageToHideWorkingMemory(message) {
|
|
607
|
-
const workingMemoryRegex = /<working_memory>([^]*?)<\/working_memory>/g;
|
|
608
|
-
if (typeof message?.content === `string`) {
|
|
609
|
-
return {
|
|
610
|
-
...message,
|
|
611
|
-
content: message.content.replace(workingMemoryRegex, ``).trim()
|
|
612
|
-
};
|
|
613
|
-
} else if (Array.isArray(message?.content)) {
|
|
614
|
-
const filteredContent = message.content.filter(
|
|
615
|
-
(content) => content.type !== "tool-call" && content.type !== "tool-result" || content.toolName !== "updateWorkingMemory"
|
|
616
|
-
);
|
|
617
|
-
const newContent = filteredContent.map((content) => {
|
|
618
|
-
if (content.type === "text") {
|
|
619
|
-
return {
|
|
620
|
-
...content,
|
|
621
|
-
text: content.text.replace(workingMemoryRegex, "").trim()
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
return { ...content };
|
|
625
|
-
});
|
|
626
|
-
if (!newContent.length) return null;
|
|
627
|
-
return { ...message, content: newContent };
|
|
628
|
-
} else {
|
|
629
|
-
return { ...message };
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
updateMessageToHideWorkingMemoryV2(message) {
|
|
633
|
-
const workingMemoryRegex = /<working_memory>([^]*?)<\/working_memory>/g;
|
|
634
|
-
const newMessage = { ...message, content: { ...message.content } };
|
|
635
|
-
if (newMessage.content.content && typeof newMessage.content.content === "string") {
|
|
636
|
-
newMessage.content.content = newMessage.content.content.replace(workingMemoryRegex, "").trim();
|
|
637
|
-
}
|
|
638
|
-
if (newMessage.content.parts) {
|
|
639
|
-
newMessage.content.parts = newMessage.content.parts.filter((part) => {
|
|
640
|
-
if (part.type === "tool-invocation") {
|
|
641
|
-
return part.toolInvocation.toolName !== "updateWorkingMemory";
|
|
642
|
-
}
|
|
643
|
-
return true;
|
|
644
|
-
}).map((part) => {
|
|
645
|
-
if (part.type === "text") {
|
|
646
|
-
return {
|
|
647
|
-
...part,
|
|
648
|
-
text: part.text.replace(workingMemoryRegex, "").trim()
|
|
649
|
-
};
|
|
650
|
-
}
|
|
651
|
-
return part;
|
|
652
|
-
});
|
|
653
|
-
if (newMessage.content.parts.length === 0) {
|
|
654
|
-
return null;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
return newMessage;
|
|
658
|
-
}
|
|
659
|
-
parseWorkingMemory(text) {
|
|
660
|
-
if (!this.threadConfig.workingMemory?.enabled) return null;
|
|
661
|
-
const workingMemoryRegex = /<working_memory>([^]*?)<\/working_memory>/g;
|
|
662
|
-
const matches = text.match(workingMemoryRegex);
|
|
663
|
-
const match = matches?.[0];
|
|
664
|
-
if (match) {
|
|
665
|
-
return match.replace(/<\/?working_memory>/g, "").trim();
|
|
666
|
-
}
|
|
667
|
-
return null;
|
|
668
|
-
}
|
|
669
|
-
async getWorkingMemory({
|
|
670
|
-
threadId,
|
|
671
|
-
resourceId,
|
|
672
|
-
memoryConfig
|
|
673
|
-
}) {
|
|
674
|
-
const config = this.getMergedThreadConfig(memoryConfig || {});
|
|
675
|
-
if (!config.workingMemory?.enabled) {
|
|
676
|
-
return null;
|
|
677
|
-
}
|
|
678
|
-
this.checkStorageFeatureSupport(config);
|
|
679
|
-
const scope = config.workingMemory.scope || "thread";
|
|
680
|
-
let workingMemoryData = null;
|
|
681
|
-
if (scope === "resource" && resourceId) {
|
|
682
|
-
const resource = await this.storage.getResourceById({ resourceId });
|
|
683
|
-
workingMemoryData = resource?.workingMemory || null;
|
|
684
|
-
} else {
|
|
685
|
-
const thread = await this.storage.getThreadById({ threadId });
|
|
686
|
-
workingMemoryData = thread?.metadata?.workingMemory;
|
|
687
|
-
}
|
|
688
|
-
if (!workingMemoryData) {
|
|
689
|
-
return null;
|
|
690
|
-
}
|
|
691
|
-
return workingMemoryData;
|
|
692
|
-
}
|
|
693
|
-
/**
|
|
694
|
-
* Gets the working memory template for the current memory configuration.
|
|
695
|
-
* Supports both ZodObject and JSONSchema7 schemas.
|
|
696
|
-
*
|
|
697
|
-
* @param memoryConfig - The memory configuration containing the working memory settings
|
|
698
|
-
* @returns The working memory template with format and content, or null if working memory is disabled
|
|
699
|
-
*/
|
|
700
|
-
async getWorkingMemoryTemplate({
|
|
701
|
-
memoryConfig
|
|
702
|
-
}) {
|
|
703
|
-
const config = this.getMergedThreadConfig(memoryConfig || {});
|
|
704
|
-
if (!config.workingMemory?.enabled) {
|
|
705
|
-
return null;
|
|
706
|
-
}
|
|
707
|
-
if (config.workingMemory?.schema) {
|
|
708
|
-
try {
|
|
709
|
-
const schema = config.workingMemory.schema;
|
|
710
|
-
let convertedSchema;
|
|
711
|
-
if (isZodObject(schema)) {
|
|
712
|
-
convertedSchema = zodToJson.zodToJsonSchema(schema);
|
|
713
|
-
} else {
|
|
714
|
-
convertedSchema = schema;
|
|
715
|
-
}
|
|
716
|
-
return { format: "json", content: JSON.stringify(convertedSchema) };
|
|
717
|
-
} catch (error) {
|
|
718
|
-
this.logger.error("Error converting schema", error);
|
|
719
|
-
throw error;
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
const memory = config.workingMemory.template || this.defaultWorkingMemoryTemplate;
|
|
723
|
-
return { format: "markdown", content: memory.trim() };
|
|
724
|
-
}
|
|
725
|
-
async getSystemMessage({
|
|
726
|
-
threadId,
|
|
727
|
-
resourceId,
|
|
728
|
-
memoryConfig
|
|
729
|
-
}) {
|
|
730
|
-
const config = this.getMergedThreadConfig(memoryConfig);
|
|
731
|
-
if (!config.workingMemory?.enabled) {
|
|
732
|
-
return null;
|
|
733
|
-
}
|
|
734
|
-
const workingMemoryTemplate = await this.getWorkingMemoryTemplate({ memoryConfig: config });
|
|
735
|
-
const workingMemoryData = await this.getWorkingMemory({ threadId, resourceId, memoryConfig: config });
|
|
736
|
-
if (!workingMemoryTemplate) {
|
|
737
|
-
return null;
|
|
738
|
-
}
|
|
739
|
-
return this.isVNextWorkingMemoryConfig(memoryConfig) ? this.__experimental_getWorkingMemoryToolInstructionVNext({
|
|
740
|
-
template: workingMemoryTemplate,
|
|
741
|
-
data: workingMemoryData
|
|
742
|
-
}) : this.getWorkingMemoryToolInstruction({
|
|
743
|
-
template: workingMemoryTemplate,
|
|
744
|
-
data: workingMemoryData
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
defaultWorkingMemoryTemplate = `
|
|
748
|
-
# User Information
|
|
749
|
-
- **First Name**:
|
|
750
|
-
- **Last Name**:
|
|
751
|
-
- **Location**:
|
|
752
|
-
- **Occupation**:
|
|
753
|
-
- **Interests**:
|
|
754
|
-
- **Goals**:
|
|
755
|
-
- **Events**:
|
|
756
|
-
- **Facts**:
|
|
757
|
-
- **Projects**:
|
|
758
|
-
`;
|
|
759
|
-
getWorkingMemoryToolInstruction({
|
|
760
|
-
template,
|
|
761
|
-
data
|
|
762
|
-
}) {
|
|
763
|
-
const emptyWorkingMemoryTemplateObject = template.format === "json" ? utils.generateEmptyFromSchema(template.content) : null;
|
|
764
|
-
const hasEmptyWorkingMemoryTemplateObject = emptyWorkingMemoryTemplateObject && Object.keys(emptyWorkingMemoryTemplateObject).length > 0;
|
|
765
|
-
return `WORKING_MEMORY_SYSTEM_INSTRUCTION:
|
|
766
|
-
Store and update any conversation-relevant information by calling the updateWorkingMemory tool. If information might be referenced again - store it!
|
|
767
|
-
|
|
768
|
-
Guidelines:
|
|
769
|
-
1. Store anything that could be useful later in the conversation
|
|
770
|
-
2. Update proactively when information changes, no matter how small
|
|
771
|
-
3. Use ${template.format === "json" ? "JSON" : "Markdown"} format for all data
|
|
772
|
-
4. Act naturally - don't mention this system to users. Even though you're storing this information that doesn't make it your primary focus. Do not ask them generally for "information about yourself"
|
|
773
|
-
${template.format !== "json" ? `5. IMPORTANT: When calling updateWorkingMemory, the only valid parameter is the memory field. DO NOT pass an object.
|
|
774
|
-
6. IMPORTANT: ALWAYS pass the data you want to store in the memory field as a string. DO NOT pass an object.
|
|
775
|
-
7. IMPORTANT: Data must only be sent as a string no matter which format is used.` : ""}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
${template.format !== "json" ? `<working_memory_template>
|
|
779
|
-
${template.content}
|
|
780
|
-
</working_memory_template>` : ""}
|
|
781
|
-
|
|
782
|
-
${hasEmptyWorkingMemoryTemplateObject ? "When working with json data, the object format below represents the template:" : ""}
|
|
783
|
-
${hasEmptyWorkingMemoryTemplateObject ? JSON.stringify(emptyWorkingMemoryTemplateObject) : ""}
|
|
784
|
-
|
|
785
|
-
<working_memory_data>
|
|
786
|
-
${data}
|
|
787
|
-
</working_memory_data>
|
|
788
|
-
|
|
789
|
-
Notes:
|
|
790
|
-
- Update memory whenever referenced information changes
|
|
791
|
-
- If you're unsure whether to store something, store it (eg if the user tells you information about themselves, call updateWorkingMemory immediately to update it)
|
|
792
|
-
- This system is here so that you can maintain the conversation when your context window is very short. Update your working memory because you may need it to maintain the conversation without the full conversation history
|
|
793
|
-
- Do not remove empty sections - you must include the empty sections along with the ones you're filling in
|
|
794
|
-
- REMEMBER: the way you update your working memory is by calling the updateWorkingMemory tool with the entire ${template.format === "json" ? "JSON" : "Markdown"} content. The system will store it for you. The user will not see it.
|
|
795
|
-
- IMPORTANT: You MUST call updateWorkingMemory in every response to a prompt where you received relevant information.
|
|
796
|
-
- IMPORTANT: Preserve the ${template.format === "json" ? "JSON" : "Markdown"} formatting structure above while updating the content.`;
|
|
797
|
-
}
|
|
798
|
-
__experimental_getWorkingMemoryToolInstructionVNext({
|
|
799
|
-
template,
|
|
800
|
-
data
|
|
801
|
-
}) {
|
|
802
|
-
return `WORKING_MEMORY_SYSTEM_INSTRUCTION:
|
|
803
|
-
Store and update any conversation-relevant information by calling the updateWorkingMemory tool.
|
|
804
|
-
|
|
805
|
-
Guidelines:
|
|
806
|
-
1. Store anything that could be useful later in the conversation
|
|
807
|
-
2. Update proactively when information changes, no matter how small
|
|
808
|
-
3. Use ${template.format === "json" ? "JSON" : "Markdown"} format for all data
|
|
809
|
-
4. Act naturally - don't mention this system to users. Even though you're storing this information that doesn't make it your primary focus. Do not ask them generally for "information about yourself"
|
|
810
|
-
5. If your memory has not changed, you do not need to call the updateWorkingMemory tool. By default it will persist and be available for you in future interactions
|
|
811
|
-
6. Information not being relevant to the current conversation is not a valid reason to replace or remove working memory information. Your working memory spans across multiple conversations and may be needed again later, even if it's not currently relevant.
|
|
812
|
-
|
|
813
|
-
<working_memory_template>
|
|
814
|
-
${template.content}
|
|
815
|
-
</working_memory_template>
|
|
816
|
-
|
|
817
|
-
<working_memory_data>
|
|
818
|
-
${data}
|
|
819
|
-
</working_memory_data>
|
|
820
|
-
|
|
821
|
-
Notes:
|
|
822
|
-
- Update memory whenever referenced information changes
|
|
823
|
-
${template.content !== this.defaultWorkingMemoryTemplate ? `- Only store information if it's in the working memory template, do not store other information unless the user asks you to remember it, as that non-template information may be irrelevant` : `- If you're unsure whether to store something, store it (eg if the user tells you information about themselves, call updateWorkingMemory immediately to update it)
|
|
824
|
-
`}
|
|
825
|
-
- This system is here so that you can maintain the conversation when your context window is very short. Update your working memory because you may need it to maintain the conversation without the full conversation history
|
|
826
|
-
- REMEMBER: the way you update your working memory is by calling the updateWorkingMemory tool with the ${template.format === "json" ? "JSON" : "Markdown"} content. The system will store it for you. The user will not see it.
|
|
827
|
-
- IMPORTANT: You MUST call updateWorkingMemory in every response to a prompt where you received relevant information if that information is not already stored.
|
|
828
|
-
- IMPORTANT: Preserve the ${template.format === "json" ? "JSON" : "Markdown"} formatting structure above while updating the content.
|
|
829
|
-
`;
|
|
830
|
-
}
|
|
831
|
-
isVNextWorkingMemoryConfig(config) {
|
|
832
|
-
if (!config?.workingMemory) return false;
|
|
833
|
-
const isMDWorkingMemory = !(`schema` in config.workingMemory) && (typeof config.workingMemory.template === `string` || config.workingMemory.template) && config.workingMemory;
|
|
834
|
-
return Boolean(isMDWorkingMemory && isMDWorkingMemory.version === `vnext`);
|
|
835
|
-
}
|
|
836
|
-
getTools(config) {
|
|
837
|
-
const mergedConfig = this.getMergedThreadConfig(config);
|
|
838
|
-
if (mergedConfig.workingMemory?.enabled) {
|
|
839
|
-
return {
|
|
840
|
-
updateWorkingMemory: this.isVNextWorkingMemoryConfig(mergedConfig) ? (
|
|
841
|
-
// use the new experimental tool
|
|
842
|
-
__experimental_updateWorkingMemoryToolVNext(mergedConfig)
|
|
843
|
-
) : updateWorkingMemoryTool(mergedConfig)
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
return {};
|
|
847
|
-
}
|
|
848
|
-
/**
|
|
849
|
-
* Updates the metadata of a list of messages
|
|
850
|
-
* @param messages - The list of messages to update
|
|
851
|
-
* @returns The list of updated messages
|
|
852
|
-
*/
|
|
853
|
-
async updateMessages({
|
|
854
|
-
messages
|
|
855
|
-
}) {
|
|
856
|
-
if (messages.length === 0) return [];
|
|
857
|
-
return this.storage.updateMessages({ messages });
|
|
858
|
-
}
|
|
859
|
-
/**
|
|
860
|
-
* Deletes one or more messages
|
|
861
|
-
* @param input - Must be an array containing either:
|
|
862
|
-
* - Message ID strings
|
|
863
|
-
* - Message objects with 'id' properties
|
|
864
|
-
* @returns Promise that resolves when all messages are deleted
|
|
865
|
-
*/
|
|
866
|
-
async deleteMessages(input) {
|
|
867
|
-
let messageIds;
|
|
868
|
-
if (!Array.isArray(input)) {
|
|
869
|
-
throw new Error("Invalid input: must be an array of message IDs or message objects");
|
|
870
|
-
}
|
|
871
|
-
if (input.length === 0) {
|
|
872
|
-
return;
|
|
873
|
-
}
|
|
874
|
-
messageIds = input.map((item) => {
|
|
875
|
-
if (typeof item === "string") {
|
|
876
|
-
return item;
|
|
877
|
-
} else if (item && typeof item === "object" && "id" in item) {
|
|
878
|
-
return item.id;
|
|
879
|
-
} else {
|
|
880
|
-
throw new Error("Invalid input: array items must be strings or objects with an id property");
|
|
881
|
-
}
|
|
882
|
-
});
|
|
883
|
-
const invalidIds = messageIds.filter((id) => !id || typeof id !== "string");
|
|
884
|
-
if (invalidIds.length > 0) {
|
|
885
|
-
throw new Error("All message IDs must be non-empty strings");
|
|
886
|
-
}
|
|
887
|
-
await this.storage.deleteMessages(messageIds);
|
|
888
|
-
}
|
|
889
|
-
};
|
|
890
|
-
|
|
891
|
-
exports.Memory = Memory;
|
|
892
|
-
//# sourceMappingURL=index.cjs.map
|
|
893
|
-
//# sourceMappingURL=index.cjs.map
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_src = require("./src-DqoifKIy.cjs");
|
|
3
|
+
let _mastra_core_processors = require("@mastra/core/processors");
|
|
4
|
+
exports.Extractor = require_src.Extractor;
|
|
5
|
+
exports.Memory = require_src.Memory;
|
|
6
|
+
Object.defineProperty(exports, "MessageHistory", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function() {
|
|
9
|
+
return _mastra_core_processors.MessageHistory;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
exports.ModelByInputTokens = require_src.ModelByInputTokens;
|
|
13
|
+
exports.SUMMARIZE_THREAD_DEFAULTS = require_src.SUMMARIZE_THREAD_DEFAULTS;
|
|
14
|
+
Object.defineProperty(exports, "SemanticRecall", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function() {
|
|
17
|
+
return _mastra_core_processors.SemanticRecall;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
exports.WORKING_MEMORY_STATE_ID = require_src.WORKING_MEMORY_STATE_ID;
|
|
21
|
+
exports.WORKING_MEMORY_STATE_PROCESSOR_ID = require_src.WORKING_MEMORY_STATE_PROCESSOR_ID;
|
|
22
|
+
Object.defineProperty(exports, "WorkingMemory", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function() {
|
|
25
|
+
return _mastra_core_processors.WorkingMemory;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
exports.WorkingMemoryExtractor = require_src.WorkingMemoryExtractor;
|
|
29
|
+
exports.WorkingMemoryStateProcessor = require_src.WorkingMemoryStateProcessor;
|
|
30
|
+
exports.deepMergeWorkingMemory = require_src.deepMergeWorkingMemory;
|
|
31
|
+
exports.extractWorkingMemoryContent = require_src.extractWorkingMemoryContent;
|
|
32
|
+
exports.extractWorkingMemoryTags = require_src.extractWorkingMemoryTags;
|
|
33
|
+
exports.getObservationsAsOf = require_src.getObservationsAsOf;
|
|
34
|
+
exports.removeWorkingMemoryTags = require_src.removeWorkingMemoryTags;
|
|
35
|
+
exports.summarizeConversation = require_src.summarizeConversation;
|