@mastra/memory 1.30.0-alpha.1 → 1.30.0-alpha.3
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 +4 -2
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-guides-context-engineering.md +1 -1
- package/dist/docs/references/docs-harness-background-tasks.md +30 -24
- package/dist/docs/references/docs-memory-message-history.md +5 -1
- package/dist/docs/references/reference-memory-cloneThread.md +2 -0
- package/dist/docs/references/reference-memory-copyThread.md +65 -0
- package/dist/docs/references/reference-memory-memory-class.md +2 -1
- package/dist/docs/references/reference-memory-updateThreadResourceId.md +46 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +60 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/processors/index.cjs +1 -1
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/tracing.d.ts.map +1 -1
- package/dist/{src-Bze5SVTm.cjs → src-CJgJb_MC.cjs} +182 -27
- package/dist/src-CJgJb_MC.cjs.map +1 -0
- package/dist/{src-BNyqEQlx.js → src-t3Mhge0m.js} +182 -27
- package/dist/{src-BNyqEQlx.js.map → src-t3Mhge0m.js.map} +1 -1
- package/package.json +4 -4
- package/dist/src-Bze5SVTm.cjs.map +0 -1
|
@@ -19797,19 +19797,28 @@ const PHASE_CONFIG = {
|
|
|
19797
19797
|
};
|
|
19798
19798
|
async function withOmTracingSpan({ phase, model, inputTokens, requestContext, observabilityContext, metadata, callback }) {
|
|
19799
19799
|
const config = PHASE_CONFIG[phase];
|
|
19800
|
+
const tracingContext = observabilityContext?.tracingContext ?? observabilityContext?.tracing;
|
|
19801
|
+
const callerMetadata = tracingContext?.currentSpan?.metadata;
|
|
19802
|
+
const inheritedCallerThreadId = callerMetadata?.__mastraObservationalMemoryCallerThreadId;
|
|
19803
|
+
const callerThreadId = callerMetadata?.threadId;
|
|
19804
|
+
const requestThreadId = requestContext?.get(MASTRA_THREAD_ID_KEY);
|
|
19805
|
+
const omCallerThreadId = typeof inheritedCallerThreadId === "string" && inheritedCallerThreadId ? inheritedCallerThreadId : typeof callerThreadId === "string" && callerThreadId ? callerThreadId : typeof requestThreadId === "string" && requestThreadId ? requestThreadId : void 0;
|
|
19800
19806
|
const span = getOrCreateSpan({
|
|
19801
19807
|
type: SpanType.MEMORY_OPERATION,
|
|
19802
19808
|
name: config.name,
|
|
19803
19809
|
entityType: EntityType.MEMORY,
|
|
19804
19810
|
entityName: config.entityName,
|
|
19805
|
-
tracingContext
|
|
19811
|
+
tracingContext,
|
|
19806
19812
|
attributes: {
|
|
19807
19813
|
operationType: config.operationType,
|
|
19808
19814
|
inputTokens,
|
|
19809
19815
|
selectedModel: typeof model === "string" ? model : "(dynamic-model)",
|
|
19810
19816
|
...config.multiThread ? { multiThread: true } : {}
|
|
19811
19817
|
},
|
|
19812
|
-
metadata
|
|
19818
|
+
metadata: omCallerThreadId !== void 0 ? {
|
|
19819
|
+
...metadata,
|
|
19820
|
+
__mastraObservationalMemoryCallerThreadId: omCallerThreadId
|
|
19821
|
+
} : metadata,
|
|
19813
19822
|
requestContext
|
|
19814
19823
|
});
|
|
19815
19824
|
const childObservabilityContext = createObservabilityContext({ currentSpan: span });
|
|
@@ -28491,7 +28500,7 @@ ${formattedMessages}
|
|
|
28491
28500
|
if (!this.buffering.isAsyncObservationEnabled()) return false;
|
|
28492
28501
|
const lockKey = this.buffering.getLockKey(opts.threadId, opts.resourceId);
|
|
28493
28502
|
const shouldTrigger = this.buffering.shouldTriggerAsyncObservation(opts.pendingTokens, lockKey, opts.record, this.storage, opts.threshold);
|
|
28494
|
-
if (shouldTrigger) this.trackBackgroundWork(this.startAsyncBufferedObservation(opts.record, opts.threadId, opts.unobservedMessages, lockKey, opts.writer, opts.unbufferedPendingTokens, opts.requestContext));
|
|
28503
|
+
if (shouldTrigger) this.trackBackgroundWork(this.startAsyncBufferedObservation(opts.record, opts.threadId, opts.unobservedMessages, lockKey, opts.writer, opts.unbufferedPendingTokens, opts.requestContext, opts.observabilityContext));
|
|
28495
28504
|
return shouldTrigger;
|
|
28496
28505
|
}
|
|
28497
28506
|
isMessageList(value) {
|
|
@@ -30260,8 +30269,35 @@ const DEFAULT_TOP_K = 4;
|
|
|
30260
30269
|
const VECTOR_DELETE_BATCH_SIZE = 100;
|
|
30261
30270
|
const DEFAULT_EMBEDDING_CACHE_MAX_SIZE = 1e3;
|
|
30262
30271
|
/**
|
|
30263
|
-
*
|
|
30264
|
-
* and
|
|
30272
|
+
* Gives Mastra agents conversation history, with optional working memory,
|
|
30273
|
+
* semantic recall, and observational memory.
|
|
30274
|
+
*
|
|
30275
|
+
* @remarks
|
|
30276
|
+
* Configure storage on this instance or its Mastra instance before use.
|
|
30277
|
+
* See the bundled docs for setup and conversation identifiers.
|
|
30278
|
+
*
|
|
30279
|
+
* @example
|
|
30280
|
+
* Attach memory to an agent; `yourModel` is your configured model.
|
|
30281
|
+
* ```typescript
|
|
30282
|
+
* import { Agent } from '@mastra/core/agent';
|
|
30283
|
+
* import { Memory } from '@mastra/memory';
|
|
30284
|
+
*
|
|
30285
|
+
* const agent = new Agent({
|
|
30286
|
+
* id: 'assistant',
|
|
30287
|
+
* name: 'Assistant',
|
|
30288
|
+
* instructions: 'You are a helpful assistant.',
|
|
30289
|
+
* model: yourModel,
|
|
30290
|
+
* memory: new Memory(),
|
|
30291
|
+
* });
|
|
30292
|
+
* ```
|
|
30293
|
+
*
|
|
30294
|
+
* @see For documentation bundled with your installed package, locate
|
|
30295
|
+
* `@mastra/memory/package.json` with your project's resolver or package-manager
|
|
30296
|
+
* tooling, then read `dist/docs/SKILL.md` from that package root and follow its
|
|
30297
|
+
* reference links. Use package-manager tools for virtual or archived packages.
|
|
30298
|
+
*
|
|
30299
|
+
* @see [Memory documentation](https://mastra.ai/docs/memory/overview)
|
|
30300
|
+
* if packaged docs are unavailable.
|
|
30265
30301
|
*/
|
|
30266
30302
|
var Memory = class Memory extends MastraMemory {
|
|
30267
30303
|
_omEngine;
|
|
@@ -31860,18 +31896,40 @@ Notes:
|
|
|
31860
31896
|
* ```
|
|
31861
31897
|
*/
|
|
31862
31898
|
async cloneThread(args, memoryConfig) {
|
|
31863
|
-
const
|
|
31864
|
-
const
|
|
31865
|
-
|
|
31866
|
-
|
|
31867
|
-
|
|
31868
|
-
|
|
31869
|
-
|
|
31870
|
-
|
|
31871
|
-
hydrateMessages: effectiveHydrate
|
|
31899
|
+
const result = await this.copyThread(args, memoryConfig);
|
|
31900
|
+
const { messages } = await (await this.getMemoryStore()).listMessages({
|
|
31901
|
+
threadId: result.thread.id,
|
|
31902
|
+
resourceId: result.thread.resourceId,
|
|
31903
|
+
perPage: false,
|
|
31904
|
+
orderBy: {
|
|
31905
|
+
field: "createdAt",
|
|
31906
|
+
direction: "ASC"
|
|
31872
31907
|
}
|
|
31873
31908
|
});
|
|
31909
|
+
return {
|
|
31910
|
+
...result,
|
|
31911
|
+
clonedMessages: messages
|
|
31912
|
+
};
|
|
31913
|
+
}
|
|
31914
|
+
/**
|
|
31915
|
+
* Copies a thread with all its messages to a new thread without returning the
|
|
31916
|
+
* message payloads. Working memory, observational memory, and semantic-recall
|
|
31917
|
+
* embeddings are carried over exactly as with `cloneThread`; the only difference
|
|
31918
|
+
* is that message content never has to be held in the Node heap at once.
|
|
31919
|
+
*
|
|
31920
|
+
* Use this instead of `cloneThread` when only the new thread id is needed
|
|
31921
|
+
* (e.g. forking a conversation for a subagent).
|
|
31922
|
+
*
|
|
31923
|
+
* @param args - Clone parameters, same as `cloneThread`
|
|
31924
|
+
* @param memoryConfig - Optional memory configuration override
|
|
31925
|
+
* @returns The newly created thread and the source→new message id map
|
|
31926
|
+
*/
|
|
31927
|
+
async copyThread(args, memoryConfig) {
|
|
31928
|
+
const memoryStore = await this.getMemoryStore();
|
|
31929
|
+
const config = this.getMergedThreadConfig(memoryConfig);
|
|
31930
|
+
const result = await memoryStore.copyThread(args);
|
|
31874
31931
|
const sourceResourceId = (await this.getThreadById({ threadId: args.sourceThreadId }))?.resourceId;
|
|
31932
|
+
let priorDestinationResourceWm;
|
|
31875
31933
|
if (config.workingMemory?.enabled) {
|
|
31876
31934
|
const scope = config.workingMemory.scope || "resource";
|
|
31877
31935
|
if (scope === "thread" || scope === "resource" && args.resourceId && args.resourceId !== sourceResourceId) {
|
|
@@ -31880,28 +31938,125 @@ Notes:
|
|
|
31880
31938
|
resourceId: sourceResourceId,
|
|
31881
31939
|
memoryConfig
|
|
31882
31940
|
});
|
|
31883
|
-
if (sourceWm)
|
|
31884
|
-
|
|
31885
|
-
|
|
31886
|
-
|
|
31887
|
-
|
|
31888
|
-
|
|
31941
|
+
if (sourceWm) {
|
|
31942
|
+
if (scope === "resource") priorDestinationResourceWm = (await memoryStore.getResourceById({ resourceId: result.thread.resourceId }))?.workingMemory ?? null;
|
|
31943
|
+
await this.updateWorkingMemory({
|
|
31944
|
+
threadId: result.thread.id,
|
|
31945
|
+
resourceId: result.thread.resourceId,
|
|
31946
|
+
workingMemory: sourceWm,
|
|
31947
|
+
memoryConfig
|
|
31948
|
+
});
|
|
31949
|
+
}
|
|
31889
31950
|
}
|
|
31890
31951
|
}
|
|
31891
31952
|
if (memoryStore.supportsObservationalMemory && sourceResourceId) try {
|
|
31892
31953
|
await this.cloneObservationalMemory(memoryStore, args.sourceThreadId, sourceResourceId, result);
|
|
31893
31954
|
} catch (error) {
|
|
31894
|
-
|
|
31895
|
-
|
|
31896
|
-
|
|
31897
|
-
|
|
31898
|
-
|
|
31955
|
+
await this.rollbackCopiedThread(memoryStore, result.thread, "OM clone", false, priorDestinationResourceWm);
|
|
31956
|
+
throw error;
|
|
31957
|
+
}
|
|
31958
|
+
if (this.vector && this.embedder && config.semanticRecall) try {
|
|
31959
|
+
await this.embedCopiedMessagesInBatches(memoryStore, result, config);
|
|
31960
|
+
} catch (error) {
|
|
31961
|
+
await this.rollbackCopiedThread(memoryStore, result.thread, "embedding", true, priorDestinationResourceWm);
|
|
31899
31962
|
throw error;
|
|
31900
31963
|
}
|
|
31901
|
-
if (this.vector && config.semanticRecall && result.clonedMessages.length > 0) await this.embedClonedMessages(result.clonedMessages, config);
|
|
31902
31964
|
return result;
|
|
31903
31965
|
}
|
|
31904
31966
|
/**
|
|
31967
|
+
* Best-effort compensation when a later step of copyThread fails after the destination thread
|
|
31968
|
+
* was persisted. deleteThread removes the thread, its messages and thread-scoped working memory.
|
|
31969
|
+
* `priorDestinationResourceWm` is the destination resource's working memory before the copy
|
|
31970
|
+
* overwrote it (`null` = none existed); when defined it is restored. When `afterOmClone` is set the OM step already succeeded, so the thread-scoped OM record and
|
|
31971
|
+
* any vectors written so far are dropped too. Resource-scoped OM is left alone: it may be
|
|
31972
|
+
* shared with a pre-existing resource and isn't safe to clear blindly.
|
|
31973
|
+
*/
|
|
31974
|
+
async rollbackCopiedThread(memoryStore, thread, failedStep, afterOmClone, priorDestinationResourceWm) {
|
|
31975
|
+
const threadId = thread.id;
|
|
31976
|
+
try {
|
|
31977
|
+
await memoryStore.deleteThread({ threadId });
|
|
31978
|
+
} catch (rollbackError) {
|
|
31979
|
+
this.logger.error(`Failed to rollback copied thread after ${failedStep} failure`, rollbackError);
|
|
31980
|
+
}
|
|
31981
|
+
if (priorDestinationResourceWm !== void 0) try {
|
|
31982
|
+
await memoryStore.updateResource({
|
|
31983
|
+
resourceId: thread.resourceId,
|
|
31984
|
+
workingMemory: priorDestinationResourceWm ?? ""
|
|
31985
|
+
});
|
|
31986
|
+
} catch (rollbackError) {
|
|
31987
|
+
this.logger.error(`Failed to restore resource working memory after ${failedStep} failure`, rollbackError);
|
|
31988
|
+
}
|
|
31989
|
+
if (!afterOmClone) return;
|
|
31990
|
+
if (memoryStore.supportsObservationalMemory) try {
|
|
31991
|
+
await memoryStore.clearObservationalMemory(threadId, thread.resourceId);
|
|
31992
|
+
} catch (rollbackError) {
|
|
31993
|
+
this.logger.error(`Failed to rollback copied thread OM after ${failedStep} failure`, rollbackError);
|
|
31994
|
+
}
|
|
31995
|
+
try {
|
|
31996
|
+
const messageIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
|
|
31997
|
+
await Promise.all(messageIndexes.map((indexName) => this.vector.deleteVectors({
|
|
31998
|
+
indexName,
|
|
31999
|
+
filter: { thread_id: threadId }
|
|
32000
|
+
})));
|
|
32001
|
+
} catch (rollbackError) {
|
|
32002
|
+
this.logger.error(`Failed to rollback copied thread vectors after ${failedStep} failure`, rollbackError);
|
|
32003
|
+
}
|
|
32004
|
+
}
|
|
32005
|
+
static CLONE_EMBED_PAGE_SIZE = 100;
|
|
32006
|
+
async embedCopiedMessagesInBatches(memoryStore, copied, config) {
|
|
32007
|
+
const size = Memory.CLONE_EMBED_PAGE_SIZE;
|
|
32008
|
+
const copiedIds = Object.values(copied.messageIdMap ?? {});
|
|
32009
|
+
if (copiedIds.length > 0) {
|
|
32010
|
+
for (let i = 0; i < copiedIds.length; i += size) {
|
|
32011
|
+
const { messages } = await memoryStore.listMessagesById({ messageIds: copiedIds.slice(i, i + size) });
|
|
32012
|
+
if (messages.length > 0) await this.embedClonedMessages(messages, config);
|
|
32013
|
+
}
|
|
32014
|
+
return;
|
|
32015
|
+
}
|
|
32016
|
+
const { messages } = await memoryStore.listMessages({
|
|
32017
|
+
threadId: copied.thread.id,
|
|
32018
|
+
resourceId: copied.thread.resourceId,
|
|
32019
|
+
perPage: false,
|
|
32020
|
+
includeTotal: false
|
|
32021
|
+
});
|
|
32022
|
+
for (let i = 0; i < messages.length; i += size) await this.embedClonedMessages(messages.slice(i, i + size), config);
|
|
32023
|
+
}
|
|
32024
|
+
async updateThreadResourceId({ threadId, resourceId, memoryConfig }) {
|
|
32025
|
+
const memoryStore = await this.getMemoryStore();
|
|
32026
|
+
const config = this.getMergedThreadConfig(memoryConfig);
|
|
32027
|
+
const migratesVectors = Boolean(this.vector && this.embedder && config.semanticRecall);
|
|
32028
|
+
if (!migratesVectors) {
|
|
32029
|
+
const existing = await memoryStore.getThreadById({ threadId });
|
|
32030
|
+
if (existing && existing.resourceId === resourceId) return existing;
|
|
32031
|
+
}
|
|
32032
|
+
const thread = await memoryStore.updateThreadResourceId({
|
|
32033
|
+
threadId,
|
|
32034
|
+
resourceId
|
|
32035
|
+
});
|
|
32036
|
+
if (migratesVectors) try {
|
|
32037
|
+
const { messages } = await memoryStore.listMessages({
|
|
32038
|
+
threadId,
|
|
32039
|
+
perPage: false
|
|
32040
|
+
});
|
|
32041
|
+
const messageIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
|
|
32042
|
+
await Promise.all(messageIndexes.map(async (indexName) => {
|
|
32043
|
+
await this.vector.deleteVectors({
|
|
32044
|
+
indexName,
|
|
32045
|
+
filter: { thread_id: threadId }
|
|
32046
|
+
});
|
|
32047
|
+
}));
|
|
32048
|
+
if (messages.length > 0) await this.embedClonedMessages(messages, config);
|
|
32049
|
+
} catch (error) {
|
|
32050
|
+
this.logger.error("Failed to migrate semantic-recall vectors during thread transfer", {
|
|
32051
|
+
threadId,
|
|
32052
|
+
resourceId,
|
|
32053
|
+
error: error instanceof Error ? error.message : String(error)
|
|
32054
|
+
});
|
|
32055
|
+
throw new Error(`Thread "${threadId}" was transferred to resource "${resourceId}", but migrating its semantic-recall vectors failed. The thread's messages may not surface under resource-scoped recall until the vectors are re-indexed. Cause: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
32056
|
+
}
|
|
32057
|
+
return thread;
|
|
32058
|
+
}
|
|
32059
|
+
/**
|
|
31905
32060
|
* Clone observational memory records when cloning a thread.
|
|
31906
32061
|
* Thread-scoped: always cloned to the new thread.
|
|
31907
32062
|
* Resource-scoped: cloned only when the resourceId changes (same resourceId shares OM naturally).
|
|
@@ -32204,4 +32359,4 @@ Notes:
|
|
|
32204
32359
|
//#endregion
|
|
32205
32360
|
export { formatMessagesForObserver as A, OBSERVATION_CONTINUATION_HINT as B, SUMMARIZE_THREAD_DEFAULTS as C, buildObserverPrompt as D, OBSERVER_SYSTEM_PROMPT as E, parseAnchorId as F, ModelByInputTokens as G, KnowledgeSemanticIndexCoordinator as H, stripEphemeralAnchorIds as I, publishSubconsciousActivity as J, SUBCONSCIOUS_ACTIVITY_STATE_ID as K, OBSERVATIONAL_MEMORY_DEFAULTS as L, optimizeObservationsForContext as M, parseObserverOutput as N, buildObserverSystemPrompt as O, injectAnchorIds as P, OBSERVATION_CONTEXT_INSTRUCTIONS as R, WorkingMemoryExtractor as S, TokenCounter as T, StaleKnowledgeSemanticIndexError as U, Subconscious as V, SubconsciousRemindExtractor as W, Extractor as X, renderSubconsciousActivity as Y, wrapInObservationGroup as _, extractWorkingMemoryContent as a, WorkingMemoryStateProcessor as b, getObservationsAsOf as c, combineObservationGroupRanges as d, deriveObservationGroupProvenance as f, stripObservationGroups as g, renderObservationGroupsForReflection as h, WorkingMemory as i, hasCurrentTaskSection as j, extractCurrentTask as k, ObservationalMemoryProcessor as l, reconcileObservationGroupsFromReflection as m, MessageHistory$1 as n, extractWorkingMemoryTags as o, parseObservationGroups as p, buildSubconsciousActivitySnapshot as q, SemanticRecall as r, removeWorkingMemoryTags as s, Memory as t, ObservationalMemory as u, WORKING_MEMORY_STATE_ID as v, summarizeConversation as w, deepMergeWorkingMemory as x, WORKING_MEMORY_STATE_PROCESSOR_ID as y, OBSERVATION_CONTEXT_PROMPT as z };
|
|
32206
32361
|
|
|
32207
|
-
//# sourceMappingURL=src-
|
|
32362
|
+
//# sourceMappingURL=src-t3Mhge0m.js.map
|