@mastra/memory 1.40.0-alpha.1 → 1.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +56 -56
- package/dist/docs/references/docs-memory-semantic-recall.md +2 -0
- package/dist/index.cjs +1 -1
- 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/observation-strategies/async-buffer.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/base.d.ts +22 -12
- package/dist/processors/observational-memory/observation-strategies/base.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts +2 -0
- package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/sync.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/types.d.ts +13 -0
- package/dist/processors/observational-memory/observation-strategies/types.d.ts.map +1 -1
- package/dist/{src-DZnFu-zL.cjs → src-CaxT6Rpu.cjs} +79 -26
- package/dist/{src-DZnFu-zL.cjs.map → src-CaxT6Rpu.cjs.map} +1 -1
- package/dist/{src-DhDMOGBn.js → src-RKBjZOzr.js} +79 -26
- package/dist/{src-DhDMOGBn.js.map → src-RKBjZOzr.js.map} +1 -1
- package/package.json +8 -8
|
@@ -35748,14 +35748,26 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
35748
35748
|
* Wrap observations in a thread attribution tag.
|
|
35749
35749
|
* In resource scope, thread IDs can be obscured via xxhash.
|
|
35750
35750
|
*/
|
|
35751
|
-
async wrapWithThreadTag(threadId, observations,
|
|
35752
|
-
const
|
|
35753
|
-
const groupedObservations = this.retrieval && messageRange ? wrapInObservationGroup(cleanObservations, messageRange) : cleanObservations;
|
|
35751
|
+
async wrapWithThreadTag(threadId, observations, group) {
|
|
35752
|
+
const groupedObservations = group ? wrapInObservationGroup(group.content, group.range, group.id) : stripThreadTags(observations);
|
|
35754
35753
|
let displayId = threadId;
|
|
35755
35754
|
if (this.deps.obscureThreadIds) displayId = (await hasherPromise).h32ToString(threadId);
|
|
35756
35755
|
return `<thread id="${displayId}">\n${groupedObservations}\n</thread>`;
|
|
35757
35756
|
}
|
|
35758
35757
|
/**
|
|
35758
|
+
* Build the observation group a cycle adds, or undefined when retrieval is off. The group is
|
|
35759
|
+
* what the cycle wraps into the observations and what it indexes, so both carry the same ID.
|
|
35760
|
+
*/
|
|
35761
|
+
createObservationGroup(observations, range) {
|
|
35762
|
+
if (!this.retrieval) return void 0;
|
|
35763
|
+
const content = this.scope === "resource" ? stripThreadTags(observations) : observations;
|
|
35764
|
+
return {
|
|
35765
|
+
id: generateAnchorId(),
|
|
35766
|
+
range,
|
|
35767
|
+
content: content.trim()
|
|
35768
|
+
};
|
|
35769
|
+
}
|
|
35770
|
+
/**
|
|
35759
35771
|
* Create a message boundary delimiter with an ISO 8601 date.
|
|
35760
35772
|
* Used to separate observation chunks for cache stability.
|
|
35761
35773
|
*/
|
|
@@ -35765,13 +35777,14 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
35765
35777
|
/**
|
|
35766
35778
|
* Wrap raw observations — in resource scope, wraps with thread tag and merges;
|
|
35767
35779
|
* in thread scope, simply appends with a message boundary delimiter.
|
|
35780
|
+
* `group` is the cycle's new observation group when retrieval is on.
|
|
35768
35781
|
*/
|
|
35769
|
-
wrapObservations(rawObservations, existingObservations, threadId, lastObservedAt,
|
|
35782
|
+
wrapObservations(rawObservations, existingObservations, threadId, lastObservedAt, group) {
|
|
35770
35783
|
if (this.scope === "resource") return (async () => {
|
|
35771
|
-
const threadSection = await this.wrapWithThreadTag(threadId, rawObservations,
|
|
35784
|
+
const threadSection = await this.wrapWithThreadTag(threadId, rawObservations, group);
|
|
35772
35785
|
return this.replaceOrAppendThreadSection(existingObservations, threadId, threadSection, lastObservedAt);
|
|
35773
35786
|
})();
|
|
35774
|
-
const grouped =
|
|
35787
|
+
const grouped = group ? wrapInObservationGroup(group.content, group.range, group.id) : rawObservations;
|
|
35775
35788
|
if (!existingObservations) return grouped;
|
|
35776
35789
|
return `${existingObservations}${lastObservedAt ? ObservationStrategy.createMessageBoundary(lastObservedAt) : "\n\n"}${grouped}`;
|
|
35777
35790
|
}
|
|
@@ -35798,10 +35811,13 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
35798
35811
|
}
|
|
35799
35812
|
}
|
|
35800
35813
|
if (existingSection) {
|
|
35801
|
-
const
|
|
35814
|
+
const dateIdx = newThreadSection.indexOf("Date:");
|
|
35815
|
+
const dateLineEnd = newThreadSection.indexOf("\n", dateIdx);
|
|
35802
35816
|
const newCloseIdx = newThreadSection.lastIndexOf(threadClose);
|
|
35817
|
+
const groupIdx = newThreadSection.indexOf("<observation-group ");
|
|
35818
|
+
const contentStart = groupIdx !== -1 && groupIdx < dateIdx ? groupIdx : dateLineEnd + 1;
|
|
35803
35819
|
if (dateLineEnd !== -1 && newCloseIdx !== -1) {
|
|
35804
|
-
const newObsContent = newThreadSection.slice(
|
|
35820
|
+
const newObsContent = newThreadSection.slice(contentStart, newCloseIdx).trim();
|
|
35805
35821
|
if (newObsContent) {
|
|
35806
35822
|
const merged = `${existingSection.slice(0, existingSection.length - 9).trimEnd()}\n${newObsContent}\n${threadClose}`;
|
|
35807
35823
|
return existingObservations.slice(0, existingSectionStart) + merged + existingObservations.slice(existingSectionEnd);
|
|
@@ -35858,7 +35874,8 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
35858
35874
|
processed: {
|
|
35859
35875
|
...processed,
|
|
35860
35876
|
observations: target.activeObservations ?? "",
|
|
35861
|
-
observationTokens: target.observationTokenCount
|
|
35877
|
+
observationTokens: target.observationTokenCount,
|
|
35878
|
+
newObservationGroup: void 0
|
|
35862
35879
|
},
|
|
35863
35880
|
record: target,
|
|
35864
35881
|
alreadyCovered: true
|
|
@@ -35884,11 +35901,24 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
35884
35901
|
return op();
|
|
35885
35902
|
}, { abortSignal: this.opts.abortSignal });
|
|
35886
35903
|
}
|
|
35904
|
+
/** Index every group parsed out of `observations` (used for buffered chunks, which carry no producer group). */
|
|
35887
35905
|
async indexObservationGroups(observations, threadId, resourceId, observedAt, recordId) {
|
|
35888
|
-
|
|
35889
|
-
|
|
35890
|
-
|
|
35891
|
-
|
|
35906
|
+
const groups = parseObservationGroups(observations).map((group) => ({
|
|
35907
|
+
group,
|
|
35908
|
+
threadId,
|
|
35909
|
+
observedAt
|
|
35910
|
+
}));
|
|
35911
|
+
await this.indexNewObservationGroups(groups, resourceId, recordId);
|
|
35912
|
+
}
|
|
35913
|
+
/**
|
|
35914
|
+
* Write the vectors for the groups a commit added, once. Call this right after the commit. The
|
|
35915
|
+
* observations are already committed, so a failed write is logged and must not fail the cycle:
|
|
35916
|
+
* that would skip its end markers and reflection.
|
|
35917
|
+
*/
|
|
35918
|
+
async indexNewObservationGroups(groups, resourceId, recordId) {
|
|
35919
|
+
const onIndexObservations = this.deps.onIndexObservations;
|
|
35920
|
+
if (!resourceId || !onIndexObservations || groups.length === 0) return;
|
|
35921
|
+
const failures = (await Promise.allSettled(groups.map(({ group, threadId, observedAt }) => withRetry(() => onIndexObservations({
|
|
35892
35922
|
text: group.content,
|
|
35893
35923
|
groupId: group.id,
|
|
35894
35924
|
range: group.range,
|
|
@@ -35899,7 +35929,12 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
35899
35929
|
}), {
|
|
35900
35930
|
label: "index-observations",
|
|
35901
35931
|
abortSignal: this.opts.abortSignal
|
|
35902
|
-
})));
|
|
35932
|
+
})))).filter((result) => result.status === "rejected");
|
|
35933
|
+
if (failures.length > 0) {
|
|
35934
|
+
const reason = failures[0].reason;
|
|
35935
|
+
omError("[OM] Indexing committed observation groups failed", reason);
|
|
35936
|
+
console.warn(`[observational-memory] Storing observation vectors failed for ${failures.length} of ${groups.length} group(s) (${reason instanceof Error ? reason.message : String(reason)}).`);
|
|
35937
|
+
}
|
|
35903
35938
|
}
|
|
35904
35939
|
/**
|
|
35905
35940
|
* Messages this cycle observed for `threadId`, or undefined when the strategy does not
|
|
@@ -36229,8 +36264,8 @@ var SyncObservationStrategy = class extends ObservationStrategy {
|
|
|
36229
36264
|
async compose(output, existingObservations, baseRecord) {
|
|
36230
36265
|
const { threadId, messages } = this.opts;
|
|
36231
36266
|
const lastObservedAt = this.getMaxMessageTimestamp(messages);
|
|
36232
|
-
const
|
|
36233
|
-
const newObservations = await this.wrapObservations(output.observations, existingObservations, threadId, lastObservedAt,
|
|
36267
|
+
const newObservationGroup = this.createObservationGroup(output.observations, buildMessageRange(messages));
|
|
36268
|
+
const newObservations = await this.wrapObservations(output.observations, existingObservations, threadId, lastObservedAt, newObservationGroup);
|
|
36234
36269
|
const observationTokens = this.tokenCounter.countObservations(newObservations);
|
|
36235
36270
|
const cycleObservationTokens = this.tokenCounter.countObservations(output.observations);
|
|
36236
36271
|
const newMessageIds = messages.map((m) => m.id);
|
|
@@ -36241,6 +36276,7 @@ var SyncObservationStrategy = class extends ObservationStrategy {
|
|
|
36241
36276
|
cycleObservationTokens,
|
|
36242
36277
|
observedMessageIds: [.../* @__PURE__ */ new Set([...Array.isArray(existingIds) ? existingIds : [], ...newMessageIds])],
|
|
36243
36278
|
lastObservedAt,
|
|
36279
|
+
newObservationGroup,
|
|
36244
36280
|
suggestedContinuation: output.suggestedContinuation,
|
|
36245
36281
|
currentTask: output.currentTask,
|
|
36246
36282
|
threadTitle: output.threadTitle,
|
|
@@ -36271,6 +36307,11 @@ var SyncObservationStrategy = class extends ObservationStrategy {
|
|
|
36271
36307
|
reason: "the observational memory head kept changing during the commit"
|
|
36272
36308
|
};
|
|
36273
36309
|
processed = committed.processed;
|
|
36310
|
+
if (!committed.alreadyCovered && processed.newObservationGroup) await this.indexNewObservationGroups([{
|
|
36311
|
+
group: processed.newObservationGroup,
|
|
36312
|
+
threadId,
|
|
36313
|
+
observedAt: processed.lastObservedAt
|
|
36314
|
+
}], resourceId, committed.record.id);
|
|
36274
36315
|
const thread = committed.alreadyCovered ? null : await this.storage.getThreadById({ threadId });
|
|
36275
36316
|
if (thread) {
|
|
36276
36317
|
const oldTitle = thread.title?.trim();
|
|
@@ -36301,7 +36342,6 @@ var SyncObservationStrategy = class extends ObservationStrategy {
|
|
|
36301
36342
|
newTitle
|
|
36302
36343
|
}));
|
|
36303
36344
|
}
|
|
36304
|
-
if (!committed.alreadyCovered) await this.indexObservationGroups(processed.observations, threadId, resourceId, processed.lastObservedAt, committed.record.id);
|
|
36305
36345
|
return {
|
|
36306
36346
|
status: "committed",
|
|
36307
36347
|
processed,
|
|
@@ -36435,10 +36475,10 @@ var AsyncBufferObservationStrategy = class extends ObservationStrategy {
|
|
|
36435
36475
|
lastObservedAt: /* @__PURE__ */ new Date()
|
|
36436
36476
|
};
|
|
36437
36477
|
}
|
|
36438
|
-
const
|
|
36478
|
+
const group = this.createObservationGroup(output.observations, buildMessageRange(messages));
|
|
36439
36479
|
let newObservations;
|
|
36440
|
-
if (this.scope === "resource") newObservations = await this.wrapWithThreadTag(threadId, output.observations,
|
|
36441
|
-
else newObservations =
|
|
36480
|
+
if (this.scope === "resource") newObservations = await this.wrapWithThreadTag(threadId, output.observations, group);
|
|
36481
|
+
else newObservations = group ? wrapInObservationGroup(group.content, group.range, group.id) : output.observations;
|
|
36442
36482
|
const observationTokens = this.tokenCounter.countObservations(newObservations);
|
|
36443
36483
|
const messageIds = messages.map((m) => m.id);
|
|
36444
36484
|
const maxTs = this.getMaxMessageTimestamp(messages);
|
|
@@ -36531,7 +36571,7 @@ var AsyncBufferObservationStrategy = class extends ObservationStrategy {
|
|
|
36531
36571
|
committedRecord = landedOn;
|
|
36532
36572
|
}
|
|
36533
36573
|
try {
|
|
36534
|
-
await this.indexObservationGroups(processed.observations, threadId, resourceId, processed.lastObservedAt,
|
|
36574
|
+
await this.indexObservationGroups(processed.observations, threadId, resourceId, processed.lastObservedAt, committedRecord.id);
|
|
36535
36575
|
const candidateTitle = processed.threadTitle?.trim();
|
|
36536
36576
|
const hasValidThreadTitle = !!candidateTitle && candidateTitle.length >= 3;
|
|
36537
36577
|
if (hasValidThreadTitle || processed.extractedValues) {
|
|
@@ -36644,6 +36684,8 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
|
|
|
36644
36684
|
priorMetadataByThread = /* @__PURE__ */ new Map();
|
|
36645
36685
|
/** Each observed thread's wrapped section from the last composition. */
|
|
36646
36686
|
threadSections = /* @__PURE__ */ new Map();
|
|
36687
|
+
/** Each observed thread's new observation group, when retrieval is on. */
|
|
36688
|
+
newGroups = /* @__PURE__ */ new Map();
|
|
36647
36689
|
/** Head text the processed observations were composed from (the commit's expected text). */
|
|
36648
36690
|
composedFrom = "";
|
|
36649
36691
|
constructor(deps, opts) {
|
|
@@ -36893,8 +36935,8 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
|
|
|
36893
36935
|
const threadMetadataUpdates = [];
|
|
36894
36936
|
for (const { threadId, threadMessages, result } of this.observationResults) {
|
|
36895
36937
|
cycleObservationTokens += this.tokenCounter.countObservations(result.observations);
|
|
36896
|
-
|
|
36897
|
-
const threadSection = await this.wrapWithThreadTag(threadId, result.observations,
|
|
36938
|
+
if (!this.newGroups.has(threadId)) this.newGroups.set(threadId, this.createObservationGroup(result.observations, buildMessageRange(threadMessages)));
|
|
36939
|
+
const threadSection = await this.wrapWithThreadTag(threadId, result.observations, this.newGroups.get(threadId));
|
|
36898
36940
|
this.threadSections.set(threadId, threadSection);
|
|
36899
36941
|
const threadLastObservedAt = this.getMaxMessageTimestamp(threadMessages);
|
|
36900
36942
|
currentObservations = this.replaceOrAppendThreadSection(currentObservations, threadId, threadSection, threadLastObservedAt);
|
|
@@ -36944,6 +36986,17 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
|
|
|
36944
36986
|
reason: "the observational memory head kept changing during the commit"
|
|
36945
36987
|
};
|
|
36946
36988
|
processed = committed.processed;
|
|
36989
|
+
if (!committed.alreadyCovered) {
|
|
36990
|
+
const added = this.observationResults.flatMap(({ threadId, threadMessages }) => {
|
|
36991
|
+
const group = this.newGroups.get(threadId);
|
|
36992
|
+
return group ? [{
|
|
36993
|
+
group,
|
|
36994
|
+
threadId,
|
|
36995
|
+
observedAt: this.getMaxMessageTimestamp(threadMessages)
|
|
36996
|
+
}] : [];
|
|
36997
|
+
});
|
|
36998
|
+
await this.indexNewObservationGroups(added, resourceId, committed.record.id);
|
|
36999
|
+
}
|
|
36947
37000
|
const threadUpdateMarkers = [];
|
|
36948
37001
|
if (processed.threadMetadataUpdates && !committed.alreadyCovered) for (const update of processed.threadMetadataUpdates) {
|
|
36949
37002
|
const thread = await this.storage.getThreadById({ threadId: update.threadId });
|
|
@@ -36979,7 +37032,6 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
|
|
|
36979
37032
|
}
|
|
36980
37033
|
}
|
|
36981
37034
|
for (const marker of threadUpdateMarkers) await this.streamMarker(marker);
|
|
36982
|
-
if (resourceId && !committed.alreadyCovered) await Promise.all(this.observationResults.map(({ threadId, threadMessages, result }) => this.indexObservationGroups(result.observations, threadId, resourceId, this.getMaxMessageTimestamp(threadMessages), committed.record.id)));
|
|
36983
37035
|
return {
|
|
36984
37036
|
status: "committed",
|
|
36985
37037
|
processed,
|
|
@@ -44282,7 +44334,8 @@ Notes:
|
|
|
44282
44334
|
if (typeof this.vector === `undefined`) throw new Error(`Tried to create observation embedding index but no vector db is attached to this Memory instance.`);
|
|
44283
44335
|
await this.vector.createIndex({
|
|
44284
44336
|
indexName,
|
|
44285
|
-
dimension: usedDimensions
|
|
44337
|
+
dimension: usedDimensions,
|
|
44338
|
+
metadataIndexes: ["resource_id", "thread_id"]
|
|
44286
44339
|
});
|
|
44287
44340
|
return { indexName };
|
|
44288
44341
|
}
|
|
@@ -45692,4 +45745,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
|
|
|
45692
45745
|
}
|
|
45693
45746
|
});
|
|
45694
45747
|
|
|
45695
|
-
//# sourceMappingURL=src-
|
|
45748
|
+
//# sourceMappingURL=src-CaxT6Rpu.cjs.map
|