@mastra/memory 1.40.0-alpha.0 → 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.
Files changed (66) hide show
  1. package/dist/_types/@internal_ai-sdk-v4/dist/index.d.ts +1 -1
  2. package/dist/docs/SKILL.md +72 -0
  3. package/dist/docs/assets/SOURCE_MAP.json +230 -0
  4. package/dist/docs/references/docs-agents-human-in-the-loop.md +773 -0
  5. package/dist/docs/references/docs-agents-networks.md +186 -0
  6. package/dist/docs/references/docs-evals-evals-with-memory.md +151 -0
  7. package/dist/docs/references/docs-guides-context-engineering.md +304 -0
  8. package/dist/docs/references/docs-harness-background-tasks.md +492 -0
  9. package/dist/docs/references/docs-harness-goals.md +144 -0
  10. package/dist/docs/references/docs-memory-memory-processors.md +442 -0
  11. package/dist/docs/references/docs-memory-message-history.md +424 -0
  12. package/dist/docs/references/docs-memory-multi-user-threads.md +210 -0
  13. package/dist/docs/references/docs-memory-observational-memory.md +1054 -0
  14. package/dist/docs/references/docs-memory-overview.md +305 -0
  15. package/dist/docs/references/docs-memory-semantic-recall.md +485 -0
  16. package/dist/docs/references/docs-memory-working-memory.md +450 -0
  17. package/dist/docs/references/docs-signals-overview.md +94 -0
  18. package/dist/docs/references/docs-storage.md +224 -0
  19. package/dist/docs/references/docs-subagents.md +554 -0
  20. package/dist/docs/references/integrations-channels-github.md +156 -0
  21. package/dist/docs/references/integrations-databases-aurora-dsql.md +432 -0
  22. package/dist/docs/references/integrations-databases-dynamodb.md +286 -0
  23. package/dist/docs/references/integrations-databases-elasticsearch.md +158 -0
  24. package/dist/docs/references/integrations-databases-libsql.md +161 -0
  25. package/dist/docs/references/integrations-databases-mongodb.md +269 -0
  26. package/dist/docs/references/integrations-databases-oracledb.md +241 -0
  27. package/dist/docs/references/integrations-databases-postgresql.md +592 -0
  28. package/dist/docs/references/integrations-databases-redis.md +250 -0
  29. package/dist/docs/references/integrations-databases-upstash.md +164 -0
  30. package/dist/docs/references/integrations-databases-valkey.md +103 -0
  31. package/dist/docs/references/reference-core-getMemory.md +53 -0
  32. package/dist/docs/references/reference-core-listMemory.md +59 -0
  33. package/dist/docs/references/reference-file-based-agents-memory.md +60 -0
  34. package/dist/docs/references/reference-memory-clone-utilities.md +205 -0
  35. package/dist/docs/references/reference-memory-cloneThread.md +177 -0
  36. package/dist/docs/references/reference-memory-copyThread.md +65 -0
  37. package/dist/docs/references/reference-memory-createThread.md +72 -0
  38. package/dist/docs/references/reference-memory-getThreadById.md +28 -0
  39. package/dist/docs/references/reference-memory-listThreads.md +149 -0
  40. package/dist/docs/references/reference-memory-memory-class.md +237 -0
  41. package/dist/docs/references/reference-memory-observational-memory.md +978 -0
  42. package/dist/docs/references/reference-memory-settled.md +67 -0
  43. package/dist/docs/references/reference-memory-summarizeConversation.md +101 -0
  44. package/dist/docs/references/reference-memory-summarizeThread.md +95 -0
  45. package/dist/docs/references/reference-memory-updateThreadResourceId.md +46 -0
  46. package/dist/docs/references/reference-migrations-agentnetwork.md +102 -0
  47. package/dist/docs/references/reference-migrations-upgrade-to-v1-memory.md +290 -0
  48. package/dist/docs/references/reference-processors-token-limiter-processor.md +169 -0
  49. package/dist/index.cjs +1 -1
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +1 -1
  52. package/dist/processors/index.cjs +1 -1
  53. package/dist/processors/index.js +1 -1
  54. package/dist/processors/observational-memory/observation-strategies/async-buffer.d.ts.map +1 -1
  55. package/dist/processors/observational-memory/observation-strategies/base.d.ts +22 -12
  56. package/dist/processors/observational-memory/observation-strategies/base.d.ts.map +1 -1
  57. package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts +2 -0
  58. package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts.map +1 -1
  59. package/dist/processors/observational-memory/observation-strategies/sync.d.ts.map +1 -1
  60. package/dist/processors/observational-memory/observation-strategies/types.d.ts +13 -0
  61. package/dist/processors/observational-memory/observation-strategies/types.d.ts.map +1 -1
  62. package/dist/{src-BFJ_viw1.cjs → src-CaxT6Rpu.cjs} +80 -26
  63. package/dist/{src-BFJ_viw1.cjs.map → src-CaxT6Rpu.cjs.map} +1 -1
  64. package/dist/{src-tZXqilfm.js → src-RKBjZOzr.js} +80 -26
  65. package/dist/{src-tZXqilfm.js.map → src-RKBjZOzr.js.map} +1 -1
  66. package/package.json +9 -9
@@ -35727,14 +35727,26 @@ var ObservationStrategy = class ObservationStrategy {
35727
35727
  * Wrap observations in a thread attribution tag.
35728
35728
  * In resource scope, thread IDs can be obscured via xxhash.
35729
35729
  */
35730
- async wrapWithThreadTag(threadId, observations, messageRange) {
35731
- const cleanObservations = stripThreadTags(observations);
35732
- const groupedObservations = this.retrieval && messageRange ? wrapInObservationGroup(cleanObservations, messageRange) : cleanObservations;
35730
+ async wrapWithThreadTag(threadId, observations, group) {
35731
+ const groupedObservations = group ? wrapInObservationGroup(group.content, group.range, group.id) : stripThreadTags(observations);
35733
35732
  let displayId = threadId;
35734
35733
  if (this.deps.obscureThreadIds) displayId = (await hasherPromise).h32ToString(threadId);
35735
35734
  return `<thread id="${displayId}">\n${groupedObservations}\n</thread>`;
35736
35735
  }
35737
35736
  /**
35737
+ * Build the observation group a cycle adds, or undefined when retrieval is off. The group is
35738
+ * what the cycle wraps into the observations and what it indexes, so both carry the same ID.
35739
+ */
35740
+ createObservationGroup(observations, range) {
35741
+ if (!this.retrieval) return void 0;
35742
+ const content = this.scope === "resource" ? stripThreadTags(observations) : observations;
35743
+ return {
35744
+ id: generateAnchorId(),
35745
+ range,
35746
+ content: content.trim()
35747
+ };
35748
+ }
35749
+ /**
35738
35750
  * Create a message boundary delimiter with an ISO 8601 date.
35739
35751
  * Used to separate observation chunks for cache stability.
35740
35752
  */
@@ -35744,13 +35756,14 @@ var ObservationStrategy = class ObservationStrategy {
35744
35756
  /**
35745
35757
  * Wrap raw observations — in resource scope, wraps with thread tag and merges;
35746
35758
  * in thread scope, simply appends with a message boundary delimiter.
35759
+ * `group` is the cycle's new observation group when retrieval is on.
35747
35760
  */
35748
- wrapObservations(rawObservations, existingObservations, threadId, lastObservedAt, messageRange) {
35761
+ wrapObservations(rawObservations, existingObservations, threadId, lastObservedAt, group) {
35749
35762
  if (this.scope === "resource") return (async () => {
35750
- const threadSection = await this.wrapWithThreadTag(threadId, rawObservations, messageRange);
35763
+ const threadSection = await this.wrapWithThreadTag(threadId, rawObservations, group);
35751
35764
  return this.replaceOrAppendThreadSection(existingObservations, threadId, threadSection, lastObservedAt);
35752
35765
  })();
35753
- const grouped = this.retrieval && messageRange ? wrapInObservationGroup(rawObservations, messageRange) : rawObservations;
35766
+ const grouped = group ? wrapInObservationGroup(group.content, group.range, group.id) : rawObservations;
35754
35767
  if (!existingObservations) return grouped;
35755
35768
  return `${existingObservations}${lastObservedAt ? ObservationStrategy.createMessageBoundary(lastObservedAt) : "\n\n"}${grouped}`;
35756
35769
  }
@@ -35777,10 +35790,13 @@ var ObservationStrategy = class ObservationStrategy {
35777
35790
  }
35778
35791
  }
35779
35792
  if (existingSection) {
35780
- const dateLineEnd = newThreadSection.indexOf("\n", newThreadSection.indexOf("Date:"));
35793
+ const dateIdx = newThreadSection.indexOf("Date:");
35794
+ const dateLineEnd = newThreadSection.indexOf("\n", dateIdx);
35781
35795
  const newCloseIdx = newThreadSection.lastIndexOf(threadClose);
35796
+ const groupIdx = newThreadSection.indexOf("<observation-group ");
35797
+ const contentStart = groupIdx !== -1 && groupIdx < dateIdx ? groupIdx : dateLineEnd + 1;
35782
35798
  if (dateLineEnd !== -1 && newCloseIdx !== -1) {
35783
- const newObsContent = newThreadSection.slice(dateLineEnd + 1, newCloseIdx).trim();
35799
+ const newObsContent = newThreadSection.slice(contentStart, newCloseIdx).trim();
35784
35800
  if (newObsContent) {
35785
35801
  const merged = `${existingSection.slice(0, existingSection.length - 9).trimEnd()}\n${newObsContent}\n${threadClose}`;
35786
35802
  return existingObservations.slice(0, existingSectionStart) + merged + existingObservations.slice(existingSectionEnd);
@@ -35837,7 +35853,8 @@ var ObservationStrategy = class ObservationStrategy {
35837
35853
  processed: {
35838
35854
  ...processed,
35839
35855
  observations: target.activeObservations ?? "",
35840
- observationTokens: target.observationTokenCount
35856
+ observationTokens: target.observationTokenCount,
35857
+ newObservationGroup: void 0
35841
35858
  },
35842
35859
  record: target,
35843
35860
  alreadyCovered: true
@@ -35863,11 +35880,24 @@ var ObservationStrategy = class ObservationStrategy {
35863
35880
  return op();
35864
35881
  }, { abortSignal: this.opts.abortSignal });
35865
35882
  }
35883
+ /** Index every group parsed out of `observations` (used for buffered chunks, which carry no producer group). */
35866
35884
  async indexObservationGroups(observations, threadId, resourceId, observedAt, recordId) {
35867
- if (!resourceId || !this.deps.onIndexObservations) return;
35868
- const groups = parseObservationGroups(observations);
35869
- if (groups.length === 0) return;
35870
- await Promise.all(groups.map((group) => withRetry(() => this.deps.onIndexObservations({
35885
+ const groups = parseObservationGroups(observations).map((group) => ({
35886
+ group,
35887
+ threadId,
35888
+ observedAt
35889
+ }));
35890
+ await this.indexNewObservationGroups(groups, resourceId, recordId);
35891
+ }
35892
+ /**
35893
+ * Write the vectors for the groups a commit added, once. Call this right after the commit. The
35894
+ * observations are already committed, so a failed write is logged and must not fail the cycle:
35895
+ * that would skip its end markers and reflection.
35896
+ */
35897
+ async indexNewObservationGroups(groups, resourceId, recordId) {
35898
+ const onIndexObservations = this.deps.onIndexObservations;
35899
+ if (!resourceId || !onIndexObservations || groups.length === 0) return;
35900
+ const failures = (await Promise.allSettled(groups.map(({ group, threadId, observedAt }) => withRetry(() => onIndexObservations({
35871
35901
  text: group.content,
35872
35902
  groupId: group.id,
35873
35903
  range: group.range,
@@ -35878,7 +35908,12 @@ var ObservationStrategy = class ObservationStrategy {
35878
35908
  }), {
35879
35909
  label: "index-observations",
35880
35910
  abortSignal: this.opts.abortSignal
35881
- })));
35911
+ })))).filter((result) => result.status === "rejected");
35912
+ if (failures.length > 0) {
35913
+ const reason = failures[0].reason;
35914
+ omError("[OM] Indexing committed observation groups failed", reason);
35915
+ console.warn(`[observational-memory] Storing observation vectors failed for ${failures.length} of ${groups.length} group(s) (${reason instanceof Error ? reason.message : String(reason)}).`);
35916
+ }
35882
35917
  }
35883
35918
  /**
35884
35919
  * Messages this cycle observed for `threadId`, or undefined when the strategy does not
@@ -36208,8 +36243,8 @@ var SyncObservationStrategy = class extends ObservationStrategy {
36208
36243
  async compose(output, existingObservations, baseRecord) {
36209
36244
  const { threadId, messages } = this.opts;
36210
36245
  const lastObservedAt = this.getMaxMessageTimestamp(messages);
36211
- const messageRange = this.retrieval ? buildMessageRange(messages) : void 0;
36212
- const newObservations = await this.wrapObservations(output.observations, existingObservations, threadId, lastObservedAt, messageRange);
36246
+ const newObservationGroup = this.createObservationGroup(output.observations, buildMessageRange(messages));
36247
+ const newObservations = await this.wrapObservations(output.observations, existingObservations, threadId, lastObservedAt, newObservationGroup);
36213
36248
  const observationTokens = this.tokenCounter.countObservations(newObservations);
36214
36249
  const cycleObservationTokens = this.tokenCounter.countObservations(output.observations);
36215
36250
  const newMessageIds = messages.map((m) => m.id);
@@ -36220,6 +36255,7 @@ var SyncObservationStrategy = class extends ObservationStrategy {
36220
36255
  cycleObservationTokens,
36221
36256
  observedMessageIds: [.../* @__PURE__ */ new Set([...Array.isArray(existingIds) ? existingIds : [], ...newMessageIds])],
36222
36257
  lastObservedAt,
36258
+ newObservationGroup,
36223
36259
  suggestedContinuation: output.suggestedContinuation,
36224
36260
  currentTask: output.currentTask,
36225
36261
  threadTitle: output.threadTitle,
@@ -36250,6 +36286,11 @@ var SyncObservationStrategy = class extends ObservationStrategy {
36250
36286
  reason: "the observational memory head kept changing during the commit"
36251
36287
  };
36252
36288
  processed = committed.processed;
36289
+ if (!committed.alreadyCovered && processed.newObservationGroup) await this.indexNewObservationGroups([{
36290
+ group: processed.newObservationGroup,
36291
+ threadId,
36292
+ observedAt: processed.lastObservedAt
36293
+ }], resourceId, committed.record.id);
36253
36294
  const thread = committed.alreadyCovered ? null : await this.storage.getThreadById({ threadId });
36254
36295
  if (thread) {
36255
36296
  const oldTitle = thread.title?.trim();
@@ -36280,7 +36321,6 @@ var SyncObservationStrategy = class extends ObservationStrategy {
36280
36321
  newTitle
36281
36322
  }));
36282
36323
  }
36283
- if (!committed.alreadyCovered) await this.indexObservationGroups(processed.observations, threadId, resourceId, processed.lastObservedAt, committed.record.id);
36284
36324
  return {
36285
36325
  status: "committed",
36286
36326
  processed,
@@ -36414,10 +36454,10 @@ var AsyncBufferObservationStrategy = class extends ObservationStrategy {
36414
36454
  lastObservedAt: /* @__PURE__ */ new Date()
36415
36455
  };
36416
36456
  }
36417
- const messageRange = this.retrieval ? buildMessageRange(messages) : void 0;
36457
+ const group = this.createObservationGroup(output.observations, buildMessageRange(messages));
36418
36458
  let newObservations;
36419
- if (this.scope === "resource") newObservations = await this.wrapWithThreadTag(threadId, output.observations, messageRange);
36420
- else newObservations = this.retrieval && messageRange ? wrapInObservationGroup(output.observations, messageRange) : output.observations;
36459
+ if (this.scope === "resource") newObservations = await this.wrapWithThreadTag(threadId, output.observations, group);
36460
+ else newObservations = group ? wrapInObservationGroup(group.content, group.range, group.id) : output.observations;
36421
36461
  const observationTokens = this.tokenCounter.countObservations(newObservations);
36422
36462
  const messageIds = messages.map((m) => m.id);
36423
36463
  const maxTs = this.getMaxMessageTimestamp(messages);
@@ -36510,7 +36550,7 @@ var AsyncBufferObservationStrategy = class extends ObservationStrategy {
36510
36550
  committedRecord = landedOn;
36511
36551
  }
36512
36552
  try {
36513
- await this.indexObservationGroups(processed.observations, threadId, resourceId, processed.lastObservedAt, this.persistedRecordId);
36553
+ await this.indexObservationGroups(processed.observations, threadId, resourceId, processed.lastObservedAt, committedRecord.id);
36514
36554
  const candidateTitle = processed.threadTitle?.trim();
36515
36555
  const hasValidThreadTitle = !!candidateTitle && candidateTitle.length >= 3;
36516
36556
  if (hasValidThreadTitle || processed.extractedValues) {
@@ -36623,6 +36663,8 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
36623
36663
  priorMetadataByThread = /* @__PURE__ */ new Map();
36624
36664
  /** Each observed thread's wrapped section from the last composition. */
36625
36665
  threadSections = /* @__PURE__ */ new Map();
36666
+ /** Each observed thread's new observation group, when retrieval is on. */
36667
+ newGroups = /* @__PURE__ */ new Map();
36626
36668
  /** Head text the processed observations were composed from (the commit's expected text). */
36627
36669
  composedFrom = "";
36628
36670
  constructor(deps, opts) {
@@ -36872,8 +36914,8 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
36872
36914
  const threadMetadataUpdates = [];
36873
36915
  for (const { threadId, threadMessages, result } of this.observationResults) {
36874
36916
  cycleObservationTokens += this.tokenCounter.countObservations(result.observations);
36875
- const messageRange = this.retrieval ? buildMessageRange(threadMessages) : void 0;
36876
- const threadSection = await this.wrapWithThreadTag(threadId, result.observations, messageRange);
36917
+ if (!this.newGroups.has(threadId)) this.newGroups.set(threadId, this.createObservationGroup(result.observations, buildMessageRange(threadMessages)));
36918
+ const threadSection = await this.wrapWithThreadTag(threadId, result.observations, this.newGroups.get(threadId));
36877
36919
  this.threadSections.set(threadId, threadSection);
36878
36920
  const threadLastObservedAt = this.getMaxMessageTimestamp(threadMessages);
36879
36921
  currentObservations = this.replaceOrAppendThreadSection(currentObservations, threadId, threadSection, threadLastObservedAt);
@@ -36923,6 +36965,17 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
36923
36965
  reason: "the observational memory head kept changing during the commit"
36924
36966
  };
36925
36967
  processed = committed.processed;
36968
+ if (!committed.alreadyCovered) {
36969
+ const added = this.observationResults.flatMap(({ threadId, threadMessages }) => {
36970
+ const group = this.newGroups.get(threadId);
36971
+ return group ? [{
36972
+ group,
36973
+ threadId,
36974
+ observedAt: this.getMaxMessageTimestamp(threadMessages)
36975
+ }] : [];
36976
+ });
36977
+ await this.indexNewObservationGroups(added, resourceId, committed.record.id);
36978
+ }
36926
36979
  const threadUpdateMarkers = [];
36927
36980
  if (processed.threadMetadataUpdates && !committed.alreadyCovered) for (const update of processed.threadMetadataUpdates) {
36928
36981
  const thread = await this.storage.getThreadById({ threadId: update.threadId });
@@ -36958,7 +37011,6 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
36958
37011
  }
36959
37012
  }
36960
37013
  for (const marker of threadUpdateMarkers) await this.streamMarker(marker);
36961
- 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)));
36962
37014
  return {
36963
37015
  status: "committed",
36964
37016
  processed,
@@ -43343,6 +43395,7 @@ var Memory = class Memory extends MastraMemory {
43343
43395
  const engine = this._omEngine ? await this._omEngine : this._omEngineInstance;
43344
43396
  if (engine && resourceId) await engine.waitForBuffering(threadId, resourceId, OM_DELETE_DRAIN_TIMEOUT_MS);
43345
43397
  await memoryStore.deleteThread({ threadId });
43398
+ if (typeof this.clearThreadStream === "function") this.clearThreadStream(threadId, resourceId);
43346
43399
  if (resourceId && memoryStore.supportsObservationalMemory) await memoryStore.clearObservationalMemory(threadId, resourceId);
43347
43400
  if (this.vector) this.trackVectorCleanup(this.deleteThreadVectors(threadId));
43348
43401
  }
@@ -44260,7 +44313,8 @@ Notes:
44260
44313
  if (typeof this.vector === `undefined`) throw new Error(`Tried to create observation embedding index but no vector db is attached to this Memory instance.`);
44261
44314
  await this.vector.createIndex({
44262
44315
  indexName,
44263
- dimension: usedDimensions
44316
+ dimension: usedDimensions,
44317
+ metadataIndexes: ["resource_id", "thread_id"]
44264
44318
  });
44265
44319
  return { indexName };
44266
44320
  }
@@ -45365,4 +45419,4 @@ Notes:
45365
45419
  };
45366
45420
  export { renderSubconsciousActivity as $, buildObserverSystemPrompt as A, OBSERVATION_CONTEXT_INSTRUCTIONS as B, WorkingMemoryExtractor as C, TokenCounter as D, summarizeConversation as E, parseObserverOutput as F, Subconscious as G, OBSERVATION_CONTEXT_PROMPT_THREAD as H, injectAnchorIds as I, SubconsciousRemindExtractor as J, KnowledgeSemanticIndexCoordinator as K, parseAnchorId as L, formatMessagesForObserver as M, hasCurrentTaskSection as N, OBSERVER_SYSTEM_PROMPT as O, optimizeObservationsForContext as P, publishSubconsciousActivity as Q, stripEphemeralAnchorIds as R, wrapInObservationGroup as S, SUMMARIZE_THREAD_DEFAULTS as T, OBSERVATION_CONTINUATION_HINT as U, OBSERVATION_CONTEXT_PROMPT as V, getObservationContextPrompt as W, SUBCONSCIOUS_ACTIVITY_STATE_ID as X, ModelByInputTokens as Y, buildSubconsciousActivitySnapshot as Z, deriveObservationGroupProvenance as _, extractWorkingMemoryContent as a, renderObservationGroupsForReflection as b, getObservationsAsOf as c, AUTO_MODEL_BY_PROVIDER as d, Extractor as et, resolveAutoModelId as f, combineObservationGroupRanges as g, WorkingMemoryStateProcessor as h, WorkingMemory as i, extractCurrentTask as j, buildObserverPrompt as k, ObservationalMemoryProcessor as l, WORKING_MEMORY_STATE_PROCESSOR_ID as m, MessageHistory$1 as n, extractWorkingMemoryTags as o, WORKING_MEMORY_STATE_ID as p, StaleKnowledgeSemanticIndexError as q, SemanticRecall as r, removeWorkingMemoryTags as s, Memory as t, ObservationalMemory as u, parseObservationGroups as v, deepMergeWorkingMemory as w, stripObservationGroups as x, reconcileObservationGroupsFromReflection as y, OBSERVATIONAL_MEMORY_DEFAULTS as z };
45367
45421
 
45368
- //# sourceMappingURL=src-tZXqilfm.js.map
45422
+ //# sourceMappingURL=src-RKBjZOzr.js.map