@mastra/memory 1.39.0 → 1.39.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/SKILL.md +2 -1
- package/dist/docs/assets/SOURCE_MAP.json +56 -56
- package/dist/docs/references/docs-agents-human-in-the-loop.md +18 -5
- package/dist/docs/references/docs-agents-networks.md +1 -1
- package/dist/docs/references/docs-guides-context-engineering.md +13 -6
- package/dist/docs/references/docs-harness-background-tasks.md +3 -3
- package/dist/docs/references/docs-harness-goals.md +5 -5
- package/dist/docs/references/docs-memory-memory-processors.md +7 -7
- package/dist/docs/references/docs-memory-message-history.md +5 -5
- package/dist/docs/references/docs-memory-multi-user-threads.md +1 -1
- package/dist/docs/references/docs-memory-observational-memory.md +14 -14
- package/dist/docs/references/docs-memory-semantic-recall.md +2 -2
- package/dist/docs/references/docs-memory-working-memory.md +2 -2
- package/dist/docs/references/docs-signals-overview.md +94 -0
- package/dist/docs/references/docs-storage.md +1 -1
- package/dist/docs/references/docs-subagents.md +6 -6
- package/dist/docs/references/integrations-channels-github.md +2 -2
- package/dist/docs/references/integrations-databases-aurora-dsql.md +1 -1
- package/dist/docs/references/integrations-databases-elasticsearch.md +1 -1
- package/dist/docs/references/integrations-databases-mongodb.md +1 -1
- package/dist/docs/references/integrations-databases-oracledb.md +1 -1
- package/dist/docs/references/integrations-databases-postgresql.md +1 -1
- package/dist/docs/references/integrations-databases-redis.md +1 -1
- package/dist/docs/references/integrations-databases-upstash.md +1 -1
- package/dist/docs/references/reference-memory-memory-class.md +3 -3
- package/dist/docs/references/reference-memory-observational-memory.md +16 -16
- 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-migrations-agentnetwork.md +4 -4
- package/dist/docs/references/reference-processors-token-limiter-processor.md +4 -4
- package/dist/docs/references/reference-vectors-libsql.md +1 -1
- package/dist/docs/references/reference-vectors-mongodb.md +2 -2
- package/dist/docs/references/reference-vectors-oracledb.md +2 -2
- package/dist/docs/references/reference-vectors-pg.md +1 -1
- package/dist/docs/references/reference-vectors-upstash.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/persistence-projection.test-utils.d.ts +3 -0
- package/dist/persistence-projection.test-utils.d.ts.map +1 -0
- package/dist/processors/index.cjs +1 -1
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/measure-image-buffer.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/step.d.ts +7 -0
- package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/turn.d.ts +0 -6
- package/dist/processors/observational-memory/observation-turn/turn.d.ts.map +1 -1
- package/dist/processors/observational-memory/processor.d.ts +1 -0
- package/dist/processors/observational-memory/processor.d.ts.map +1 -1
- package/dist/{src-DxZ7N8nO.js → src-BUWL69LT.js} +129 -31
- package/dist/{src-DxZ7N8nO.js.map → src-BUWL69LT.js.map} +1 -1
- package/dist/{src-IWcrqO0n.cjs → src-BjH9gT88.cjs} +129 -31
- package/dist/{src-IWcrqO0n.cjs.map → src-BjH9gT88.cjs.map} +1 -1
- package/package.json +10 -10
|
@@ -36668,7 +36668,6 @@ var ObservationStep = class {
|
|
|
36668
36668
|
let observerExchange;
|
|
36669
36669
|
const step0Messages = this.stepNumber === 0 ? getObservableMessages(messageList) : [];
|
|
36670
36670
|
if (this.stepNumber === 0) {
|
|
36671
|
-
this.turn.inputMessageIds = messageList.get.input.db().map((msg) => msg.id);
|
|
36672
36671
|
const activation = await om.activate({
|
|
36673
36672
|
threadId,
|
|
36674
36673
|
resourceId,
|
|
@@ -36799,7 +36798,7 @@ var ObservationStep = class {
|
|
|
36799
36798
|
drainedKeys.set(msg.id, /* @__PURE__ */ new Set([...seen ?? [], ...keys]));
|
|
36800
36799
|
return !seen || keys.some((key) => !seen.has(key));
|
|
36801
36800
|
}).map((msg) => msg.id);
|
|
36802
|
-
inFlightIds = [
|
|
36801
|
+
inFlightIds = [...new Set(unreadIds)];
|
|
36803
36802
|
if (messagesToSave.length > 0) {
|
|
36804
36803
|
for (const msg of messagesToSave) messageList.add(msg, "memory");
|
|
36805
36804
|
try {
|
|
@@ -36876,7 +36875,7 @@ var ObservationStep = class {
|
|
|
36876
36875
|
});
|
|
36877
36876
|
if (!didThresholdCleanup) {
|
|
36878
36877
|
const fallbackCursor = this.turn.record.threadId ? (0, _mastra_core_memory.getThreadOMMetadata)((await om.getStorage().getThreadById({ threadId: this.turn.record.threadId }))?.metadata)?.lastObservedMessageCursor : void 0;
|
|
36879
|
-
const pendingMessageIds = new Set([...messageList.get.input.db(), ...messageList.get.response.db()].map((msg) => msg.id).concat(inFlightIds ?? [], this.
|
|
36878
|
+
const pendingMessageIds = new Set([...messageList.get.input.db(), ...messageList.get.response.db()].map((msg) => msg.id).concat(inFlightIds ?? [], this.changedSinceDrain(messageList)).filter(Boolean));
|
|
36880
36879
|
filterObservedMessages({
|
|
36881
36880
|
messageList,
|
|
36882
36881
|
record: this.turn.record,
|
|
@@ -37162,12 +37161,6 @@ var ObservationTurn = class {
|
|
|
37162
37161
|
/** Generation count at turn start — used to detect if reflection happened during the turn. */
|
|
37163
37162
|
_generationCountAtStart = -1;
|
|
37164
37163
|
/**
|
|
37165
|
-
* Ids of the messages this turn was started with (the user's request). Mid-turn
|
|
37166
|
-
* observation may record them, but they stay in the live prompt until the turn ends.
|
|
37167
|
-
* @internal Set by step 0.
|
|
37168
|
-
*/
|
|
37169
|
-
inputMessageIds = [];
|
|
37170
|
-
/**
|
|
37171
37164
|
* Fingerprints of the non-marker parts each message had when a step last drained it. A message
|
|
37172
37165
|
* is unread step output only if it gained a part the model has not seen — including a tool result
|
|
37173
37166
|
* merged in place into an existing tool-invocation part — not when it only gained OM markers.
|
|
@@ -41937,6 +41930,29 @@ var ObservationalMemoryProcessor = class {
|
|
|
41937
41930
|
this.turn.agent = args.agent;
|
|
41938
41931
|
this.turn.requestContext = requestContext;
|
|
41939
41932
|
await this.turn.start(this.memory, runState);
|
|
41933
|
+
if (stepNumber > 0) {
|
|
41934
|
+
if (this.memory?.getPersistedMessages) {
|
|
41935
|
+
const responseIds = messageList.getPersisted.response.db().map((message) => message.id);
|
|
41936
|
+
const snapshotMessages = new Map(messageList.get.all.db().map((message) => [message.id, message]));
|
|
41937
|
+
const storedMessages = await this.memory.getPersistedMessages(threadId, responseIds);
|
|
41938
|
+
for (const stored of storedMessages) {
|
|
41939
|
+
const snapshot = snapshotMessages.get(stored.id);
|
|
41940
|
+
if (!snapshot) continue;
|
|
41941
|
+
const snapshotTools = snapshot.content.parts.filter((part) => part.type === "tool-invocation");
|
|
41942
|
+
if (stored.content.parts.some((part) => {
|
|
41943
|
+
if (part.type !== "tool-invocation" || part.toolInvocation.state !== "result") return false;
|
|
41944
|
+
const previous = snapshotTools.find((candidate) => candidate.toolInvocation.toolCallId === part.toolInvocation.toolCallId);
|
|
41945
|
+
if (!previous || previous.toolInvocation.state !== "result") return true;
|
|
41946
|
+
const previousTask = previous.providerMetadata?.mastra?.backgroundTask;
|
|
41947
|
+
const storedTask = part.providerMetadata?.mastra?.backgroundTask;
|
|
41948
|
+
return previousTask?.status === "running" && (storedTask?.status === "completed" || storedTask?.status === "failed");
|
|
41949
|
+
})) {
|
|
41950
|
+
this.turn.drainedPartKeys.set(stored.id, new Set(getPartKeys(snapshot)));
|
|
41951
|
+
messageList.add(stored, "memory");
|
|
41952
|
+
}
|
|
41953
|
+
}
|
|
41954
|
+
}
|
|
41955
|
+
}
|
|
41940
41956
|
const observedIds = this.turn.record.observedMessageIds;
|
|
41941
41957
|
const response = messageId ? messageList.get.all.db().find((message) => message.id === messageId) : void 0;
|
|
41942
41958
|
const responseSealed = (response?.content?.metadata)?.mastra?.sealed === true;
|
|
@@ -42081,6 +42097,7 @@ var ObservationalMemoryProcessor = class {
|
|
|
42081
42097
|
writer: args.writer,
|
|
42082
42098
|
observabilityContext: getOmObservabilityContext(args)
|
|
42083
42099
|
}));
|
|
42100
|
+
if (observed) args.rotateResponseMessageId?.();
|
|
42084
42101
|
return { retry: activated || observed };
|
|
42085
42102
|
}
|
|
42086
42103
|
get config() {
|
|
@@ -43166,9 +43183,7 @@ ${workingMemory}`;
|
|
|
43166
43183
|
async saveMessages({ messages, memoryConfig, observabilityContext }) {
|
|
43167
43184
|
const span = this.createMemorySpan("save", observabilityContext, void 0, { messageCount: messages.length });
|
|
43168
43185
|
try {
|
|
43169
|
-
const updatedMessages =
|
|
43170
|
-
return this.updateMessageToHideWorkingMemoryV2(m);
|
|
43171
|
-
}).filter((m) => Boolean(m));
|
|
43186
|
+
const updatedMessages = this.prepareMessagesForPersistence(messages);
|
|
43172
43187
|
const config = this.getMergedThreadConfig(memoryConfig);
|
|
43173
43188
|
const dbMessages = new _mastra_core_agent.MessageList({ generateMessageId: () => this.generateId() }).add(updatedMessages, "memory").get.all.db();
|
|
43174
43189
|
const memoryStore = await this.getMemoryStore();
|
|
@@ -43274,12 +43289,17 @@ ${workingMemory}`;
|
|
|
43274
43289
|
throw error;
|
|
43275
43290
|
}
|
|
43276
43291
|
}
|
|
43292
|
+
prepareMessagesForPersistence(messages) {
|
|
43293
|
+
return messages.filter((m) => m.role !== "system" && !isTransientSignalMessage(m)).map((m) => this.updateMessageToHideWorkingMemoryV2(m)).filter((m) => m !== null);
|
|
43294
|
+
}
|
|
43277
43295
|
updateMessageToHideWorkingMemoryV2(message) {
|
|
43278
43296
|
const newMessage = { ...message };
|
|
43279
43297
|
if (message.content && typeof message.content === "object" && !Array.isArray(message.content)) newMessage.content = { ...message.content };
|
|
43280
43298
|
if (typeof newMessage.content?.content === "string" && newMessage.content.content.length > 0) newMessage.content.content = removeWorkingMemoryTags(newMessage.content.content).trim();
|
|
43281
43299
|
if (Array.isArray(newMessage.content?.parts)) {
|
|
43282
43300
|
if (Array.isArray(newMessage.content.toolInvocations)) newMessage.content.toolInvocations = removeWorkingMemoryToolInvocations(newMessage.content.toolInvocations);
|
|
43301
|
+
const lastOriginalPart = newMessage.content.parts.at(-1);
|
|
43302
|
+
const sealMetadata = lastOriginalPart && "metadata" in lastOriginalPart ? lastOriginalPart.metadata : void 0;
|
|
43283
43303
|
newMessage.content.parts = removeWorkingMemoryToolInvocationParts(newMessage.content.parts).map((part) => {
|
|
43284
43304
|
if (part?.type === "text") {
|
|
43285
43305
|
const text = typeof part.text === "string" ? part.text : "";
|
|
@@ -43290,6 +43310,26 @@ ${workingMemory}`;
|
|
|
43290
43310
|
}
|
|
43291
43311
|
return part;
|
|
43292
43312
|
});
|
|
43313
|
+
const lastIndex = newMessage.content.parts.length - 1;
|
|
43314
|
+
const lastPart = newMessage.content.parts[lastIndex];
|
|
43315
|
+
if (lastPart && sealMetadata && typeof sealMetadata === "object" && "mastra" in sealMetadata) {
|
|
43316
|
+
const mastra = sealMetadata.mastra;
|
|
43317
|
+
if (mastra && typeof mastra === "object" && "sealedAt" in mastra && typeof mastra.sealedAt === "number") {
|
|
43318
|
+
const existingMetadata = "metadata" in lastPart ? lastPart.metadata : void 0;
|
|
43319
|
+
const metadata = existingMetadata && typeof existingMetadata === "object" ? existingMetadata : {};
|
|
43320
|
+
const existingMastra = "mastra" in metadata && metadata.mastra && typeof metadata.mastra === "object" ? metadata.mastra : {};
|
|
43321
|
+
newMessage.content.parts[lastIndex] = {
|
|
43322
|
+
...lastPart,
|
|
43323
|
+
metadata: {
|
|
43324
|
+
...metadata,
|
|
43325
|
+
mastra: {
|
|
43326
|
+
...existingMastra,
|
|
43327
|
+
sealedAt: mastra.sealedAt
|
|
43328
|
+
}
|
|
43329
|
+
}
|
|
43330
|
+
};
|
|
43331
|
+
}
|
|
43332
|
+
}
|
|
43293
43333
|
if (newMessage.content.parts.length === 0) {
|
|
43294
43334
|
if (!(typeof newMessage.content.content === "string" && newMessage.content.content.trim().length > 0)) return null;
|
|
43295
43335
|
}
|
|
@@ -43370,6 +43410,16 @@ ${workingMemory}`;
|
|
|
43370
43410
|
data: workingMemoryData
|
|
43371
43411
|
});
|
|
43372
43412
|
}
|
|
43413
|
+
/** Fetch current stored copies of messages in a resumed turn, bypassing run-state history caches. */
|
|
43414
|
+
async getPersistedMessages(threadId, ids) {
|
|
43415
|
+
if (!ids.length) return [];
|
|
43416
|
+
return (await (await this.getMemoryStore()).listMessages({
|
|
43417
|
+
threadId,
|
|
43418
|
+
perPage: 0,
|
|
43419
|
+
include: ids.map((id) => ({ id })),
|
|
43420
|
+
includeTotal: false
|
|
43421
|
+
})).messages.filter((message) => ids.includes(message.id));
|
|
43422
|
+
}
|
|
43373
43423
|
/**
|
|
43374
43424
|
* Get everything needed for an LLM call in one shot.
|
|
43375
43425
|
*
|
|
@@ -43529,12 +43579,12 @@ ${workingMemory}`;
|
|
|
43529
43579
|
};
|
|
43530
43580
|
}
|
|
43531
43581
|
/**
|
|
43532
|
-
* Raw message upsert —
|
|
43582
|
+
* Raw message upsert — apply the persistence projection without embedding or extracting working memory.
|
|
43533
43583
|
* Used by the processor to save sealed messages before firing a background buffer operation.
|
|
43534
43584
|
*/
|
|
43535
43585
|
async persistMessages(messages) {
|
|
43536
43586
|
if (messages.length === 0) return;
|
|
43537
|
-
const persistableMessages =
|
|
43587
|
+
const persistableMessages = this.prepareMessagesForPersistence(messages);
|
|
43538
43588
|
if (persistableMessages.length === 0) return;
|
|
43539
43589
|
await (await this.getMemoryStore()).saveMessages({ messages: persistableMessages });
|
|
43540
43590
|
}
|
|
@@ -44016,27 +44066,75 @@ Notes:
|
|
|
44016
44066
|
if (messages.length === 0) return [];
|
|
44017
44067
|
const memoryStore = await this.getMemoryStore();
|
|
44018
44068
|
const config = this.getMergedThreadConfig(memoryConfig);
|
|
44069
|
+
const existing = await memoryStore.listMessagesById({ messageIds: messages.map((m) => m.id) });
|
|
44070
|
+
const existingById = new Map(existing.messages.map((m) => [m.id, m]));
|
|
44071
|
+
const textForEmbeddingById = /* @__PURE__ */ new Map();
|
|
44072
|
+
const textFields = ["content", "parts"];
|
|
44073
|
+
const textOf = (content, fields) => {
|
|
44074
|
+
for (const field of fields) {
|
|
44075
|
+
const text = field === "content" ? content.content?.trim() ? content.content : null : (content.parts ?? []).filter((part) => part?.type === "text").map((part) => part.text).join(" ").trim();
|
|
44076
|
+
if (text) return text;
|
|
44077
|
+
}
|
|
44078
|
+
return null;
|
|
44079
|
+
};
|
|
44080
|
+
messages = messages.flatMap((update) => {
|
|
44081
|
+
const stored = existingById.get(update.id);
|
|
44082
|
+
if (!stored) return [];
|
|
44083
|
+
const effective = {
|
|
44084
|
+
...stored,
|
|
44085
|
+
...update,
|
|
44086
|
+
content: update.content === void 0 ? stored.content : {
|
|
44087
|
+
...stored.content,
|
|
44088
|
+
...update.content,
|
|
44089
|
+
metadata: {
|
|
44090
|
+
...stored.content.metadata,
|
|
44091
|
+
...update.content.metadata
|
|
44092
|
+
}
|
|
44093
|
+
}
|
|
44094
|
+
};
|
|
44095
|
+
const [projected] = this.prepareMessagesForPersistence([effective]);
|
|
44096
|
+
if (!projected) return [];
|
|
44097
|
+
if (update.content === void 0) {
|
|
44098
|
+
existingById.set(update.id, effective);
|
|
44099
|
+
return [update];
|
|
44100
|
+
}
|
|
44101
|
+
const content = {
|
|
44102
|
+
...update.content,
|
|
44103
|
+
...update.content.parts !== void 0 ? { parts: projected.content.parts } : {},
|
|
44104
|
+
...update.content.content !== void 0 ? { content: projected.content.content } : {},
|
|
44105
|
+
...update.content.toolInvocations !== void 0 ? { toolInvocations: projected.content.toolInvocations } : {}
|
|
44106
|
+
};
|
|
44107
|
+
existingById.set(update.id, {
|
|
44108
|
+
...effective,
|
|
44109
|
+
content: {
|
|
44110
|
+
...effective.content,
|
|
44111
|
+
...content
|
|
44112
|
+
}
|
|
44113
|
+
});
|
|
44114
|
+
const patched = textFields.filter((field) => update.content?.[field] !== void 0);
|
|
44115
|
+
if (patched.length > 0) {
|
|
44116
|
+
const omitted = textFields.filter((field) => !patched.includes(field));
|
|
44117
|
+
const text = textOf(projected.content, patched) ?? (textOf(update.content, patched) ? textOf(projected.content, omitted) : null);
|
|
44118
|
+
textForEmbeddingById.set(update.id, text);
|
|
44119
|
+
}
|
|
44120
|
+
return [{
|
|
44121
|
+
...update,
|
|
44122
|
+
content
|
|
44123
|
+
}];
|
|
44124
|
+
});
|
|
44125
|
+
if (messages.length === 0) return [];
|
|
44019
44126
|
if (this.vector && config.semanticRecall) {
|
|
44020
|
-
const
|
|
44021
|
-
if (
|
|
44022
|
-
const
|
|
44023
|
-
const existingMessagesMap = new Map(existingMessagesResult.messages.map((m) => [m.id, m]));
|
|
44127
|
+
const messagesWithTextUpdates = [...textForEmbeddingById.keys()].map((id) => ({ id }));
|
|
44128
|
+
if (messagesWithTextUpdates.length > 0) {
|
|
44129
|
+
const existingMessagesMap = new Map(existing.messages.map((m) => [m.id, m]));
|
|
44024
44130
|
const embeddingData = [];
|
|
44025
44131
|
let dimension;
|
|
44026
44132
|
const messageIdsWithNewEmbeddings = /* @__PURE__ */ new Set();
|
|
44027
44133
|
const messageIdsWithClearedContent = /* @__PURE__ */ new Set();
|
|
44028
|
-
await Promise.all(
|
|
44134
|
+
await Promise.all(messagesWithTextUpdates.map(async (message) => {
|
|
44029
44135
|
const existingMessage = existingMessagesMap.get(message.id);
|
|
44030
44136
|
if (!existingMessage) return;
|
|
44031
|
-
|
|
44032
|
-
const content = message.content;
|
|
44033
|
-
if (content) {
|
|
44034
|
-
if ("content" in content && content.content && typeof content.content === "string" && content.content.trim() !== "") textForEmbedding = content.content;
|
|
44035
|
-
else if ("parts" in content && content.parts && Array.isArray(content.parts) && content.parts.length > 0) {
|
|
44036
|
-
const joined = content.parts.filter((part) => part?.type === "text").map((part) => part.text).join(" ").trim();
|
|
44037
|
-
if (joined) textForEmbedding = joined;
|
|
44038
|
-
}
|
|
44039
|
-
}
|
|
44137
|
+
const textForEmbedding = textForEmbeddingById.get(message.id) ?? null;
|
|
44040
44138
|
if (textForEmbedding) {
|
|
44041
44139
|
let embeddings = [];
|
|
44042
44140
|
let documents;
|
|
@@ -44739,9 +44837,9 @@ Notes:
|
|
|
44739
44837
|
if (configuredProcessors.some((p) => !("workflow" in p) && p.id === "observational-memory")) return null;
|
|
44740
44838
|
const runtimeMemory = context?.get("MastraMemory");
|
|
44741
44839
|
const runtimeObservationalMemory = normalizeObservationalMemoryConfig(runtimeMemory?.memoryConfig?.observationalMemory);
|
|
44742
|
-
const effectiveConfig = normalizeObservationalMemoryConfig((
|
|
44840
|
+
const effectiveConfig = normalizeObservationalMemoryConfig((runtimeMemory?.memoryConfig?.observationalMemory !== void 0 ? this.getMergedThreadConfig({
|
|
44743
44841
|
...runtimeMemory?.memoryConfig,
|
|
44744
|
-
observationalMemory: runtimeObservationalMemory
|
|
44842
|
+
observationalMemory: runtimeObservationalMemory ?? false
|
|
44745
44843
|
}) : this.threadConfig).observationalMemory);
|
|
44746
44844
|
if (!effectiveConfig) return null;
|
|
44747
44845
|
const engine = await this.omEngine;
|
|
@@ -45088,4 +45186,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
|
|
|
45088
45186
|
}
|
|
45089
45187
|
});
|
|
45090
45188
|
|
|
45091
|
-
//# sourceMappingURL=src-
|
|
45189
|
+
//# sourceMappingURL=src-BjH9gT88.cjs.map
|