@mastra/memory 1.26.1-alpha.0 → 1.26.1-alpha.2

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.
@@ -18959,9 +18959,10 @@ async function listThreadsForResource({ memory, resourceId, currentThreadId, pag
18959
18959
  hasMore
18960
18960
  };
18961
18961
  }
18962
+ const SEARCH_NOT_CONFIGURED_MESSAGE = "Search is not configured. Enable it with `retrieval: { vector: true }` and configure a vector store and embedder on your Memory instance.";
18962
18963
  async function searchMessagesForResource({ memory, resourceId, currentThreadId, query, topK = 10, maxTokens = DEFAULT_MAX_RESULT_TOKENS, before, after, threadScope }) {
18963
18964
  if (!memory.searchMessages) return {
18964
- results: "Search is not configured. Enable it with `retrieval: { vector: true }` and configure a vector store and embedder on your Memory instance.",
18965
+ results: SEARCH_NOT_CONFIGURED_MESSAGE,
18965
18966
  count: 0
18966
18967
  };
18967
18968
  const MAX_TOPK = 20;
@@ -19507,9 +19508,16 @@ async function recallThreadFromStart({ memory, threadId, resourceId, page = 1, l
19507
19508
  }
19508
19509
  const recallTool = (_memoryConfig, options) => {
19509
19510
  const isResourceScope = (options?.retrievalScope ?? "thread") === "resource";
19511
+ const searchEnabled = options?.searchEnabled ?? true;
19512
+ const description = isResourceScope ? `Browse conversation history. Use mode="threads" to list all threads for the current user. Use mode="messages" (default) to browse messages in the current thread or pass threadId to browse another thread in the active resource. When mode="messages" has no cursor or threadId, it defaults to the current thread and says so at the top of the result. If you pass only a cursor, it must belong to the current thread.${searchEnabled ? " Use mode=\"search\" to find messages by content across all threads." : ""}` : `Browse conversation history in the current thread. Use mode="messages" (default) to page through messages near a cursor.${searchEnabled ? " Use mode=\"search\" to find messages by content in this thread." : ""} Use mode="threads" to get the current thread's ID and title.`;
19513
+ const modeEnum = searchEnabled ? [
19514
+ "messages",
19515
+ "threads",
19516
+ "search"
19517
+ ] : ["messages", "threads"];
19510
19518
  return createTool({
19511
19519
  id: "recall",
19512
- description: isResourceScope ? "Browse conversation history. Use mode=\"threads\" to list all threads for the current user. Use mode=\"messages\" (default) to browse messages in the current thread or pass threadId to browse another thread in the active resource. When mode=\"messages\" has no cursor or threadId, it defaults to the current thread and says so at the top of the result. If you pass only a cursor, it must belong to the current thread. Use mode=\"search\" to find messages by content across all threads." : "Browse conversation history in the current thread. Use mode=\"messages\" (default) to page through messages near a cursor. Use mode=\"search\" to find messages by content in this thread. Use mode=\"threads\" to get the current thread's ID and title.",
19520
+ description,
19513
19521
  inputSchema: {
19514
19522
  $schema: "http://json-schema.org/draft-07/schema#",
19515
19523
  type: "object",
@@ -19517,12 +19525,8 @@ const recallTool = (_memoryConfig, options) => {
19517
19525
  ...isResourceScope ? {
19518
19526
  mode: {
19519
19527
  type: "string",
19520
- enum: [
19521
- "messages",
19522
- "threads",
19523
- "search"
19524
- ],
19525
- description: "What to retrieve. \"messages\" (default) pages through message history. \"threads\" lists all threads for the current user. \"search\" finds messages by semantic similarity across all threads."
19528
+ enum: modeEnum,
19529
+ description: `What to retrieve. "messages" (default) pages through message history. "threads" lists all threads for the current user.${searchEnabled ? " \"search\" finds messages by semantic similarity across all threads." : ""}`
19526
19530
  },
19527
19531
  threadId: {
19528
19532
  type: "string",
@@ -19539,18 +19543,14 @@ const recallTool = (_memoryConfig, options) => {
19539
19543
  }
19540
19544
  } : { mode: {
19541
19545
  type: "string",
19542
- enum: [
19543
- "messages",
19544
- "threads",
19545
- "search"
19546
- ],
19547
- description: "What to retrieve. \"messages\" (default) pages through message history. \"threads\" returns info about the current thread. \"search\" finds messages by semantic similarity in this thread."
19546
+ enum: modeEnum,
19547
+ description: `What to retrieve. "messages" (default) pages through message history. "threads" returns info about the current thread.${searchEnabled ? " \"search\" finds messages by semantic similarity in this thread." : ""}`
19548
19548
  } },
19549
- query: {
19549
+ ...searchEnabled ? { query: {
19550
19550
  type: "string",
19551
19551
  minLength: 1,
19552
19552
  description: "Search query for mode=\"search\". Finds messages semantically similar to this text."
19553
- },
19553
+ } } : {},
19554
19554
  cursor: {
19555
19555
  type: "string",
19556
19556
  minLength: 1,
@@ -19611,6 +19611,10 @@ const recallTool = (_memoryConfig, options) => {
19611
19611
  if (!memory) throw new Error("Memory instance is required for recall");
19612
19612
  if (explicitThreadId === "current" && !currentThreadId) throw new Error("Could not resolve current thread.");
19613
19613
  if (mode === "search") {
19614
+ if (!searchEnabled) return {
19615
+ results: SEARCH_NOT_CONFIGURED_MESSAGE,
19616
+ count: 0
19617
+ };
19614
19618
  if (!query) throw new Error("query is required for mode=\"search\"");
19615
19619
  if (!resourceId) throw new Error("Resource ID is required for recall");
19616
19620
  return searchMessagesForResource({
@@ -20572,6 +20576,24 @@ function getUnobservedPartsPreservingToolCallPairs(message) {
20572
20576
  return preservedCalls.length > 0 ? [...preservedCalls, ...unobservedParts] : unobservedParts;
20573
20577
  }
20574
20578
  /**
20579
+ * Get the messages Observational Memory is allowed to work with.
20580
+ *
20581
+ * Messages supplied through the `context` option are per-run ephemeral input. Core's
20582
+ * persistence contract already treats them as never-persist: `MessageStateManager` routes
20583
+ * them into `userContextMessages`, and `drainUnsavedMessages` only drains input/response.
20584
+ *
20585
+ * OM builds its windows from `get.all.db()`, which includes context messages, and then
20586
+ * seals and persists candidates directly — turning ephemeral context into durable user
20587
+ * messages. Excluding them here keeps OM's window, sealing, persistence and token
20588
+ * accounting consistent with that contract.
20589
+ */
20590
+ function getObservableMessages(messageList) {
20591
+ const allMessages = messageList.get.all.db();
20592
+ const contextMessageIds = messageList.makeMessageSourceChecker().context;
20593
+ if (contextMessageIds.size === 0) return allMessages;
20594
+ return allMessages.filter((message) => !contextMessageIds.has(message.id));
20595
+ }
20596
+ /**
20575
20597
  * Safely extract buffered observation chunks from a record.
20576
20598
  * Handles both array and JSON-string formats, returning empty array if malformed.
20577
20599
  */
@@ -20584,7 +20606,7 @@ function getUnobservedPartsPreservingToolCallPairs(message) {
20584
20606
  */
20585
20607
  function filterObservedMessages(opts) {
20586
20608
  const { messageList, record } = opts;
20587
- const allMessages = messageList.get.all.db();
20609
+ const allMessages = getObservableMessages(messageList);
20588
20610
  const useMarkerBoundaryPruning = opts.useMarkerBoundaryPruning ?? true;
20589
20611
  const preserveMessageIds = opts.preserveMessageIds ?? /* @__PURE__ */ new Set();
20590
20612
  const observedIds = new Set(Array.isArray(record?.observedMessageIds) ? record.observedMessageIds : []);
@@ -21137,7 +21159,7 @@ var ObservationStrategy = class ObservationStrategy {
21137
21159
  */
21138
21160
  async persistMarkerToMessage(marker, messageList, threadId, resourceId) {
21139
21161
  if (!messageList) return false;
21140
- const allMsgs = messageList.get.all.db();
21162
+ const allMsgs = getObservableMessages(messageList);
21141
21163
  for (let i = allMsgs.length - 1; i >= 0; i--) {
21142
21164
  const msg = allMsgs[i];
21143
21165
  if (msg?.role === "assistant" && msg.content?.parts && Array.isArray(msg.content.parts)) {
@@ -22016,7 +22038,7 @@ var ObservationStep = class {
22016
22038
  let didThresholdCleanup = false;
22017
22039
  let observerExchange;
22018
22040
  if (this.stepNumber === 0) {
22019
- const step0Messages = messageList.get.all.db();
22041
+ const step0Messages = getObservableMessages(messageList);
22020
22042
  const activation = await om.activate({
22021
22043
  threadId,
22022
22044
  resourceId,
@@ -22048,7 +22070,7 @@ var ObservationStep = class {
22048
22070
  currentModel: this.turn.actorModelContext,
22049
22071
  requestContext: this.turn.requestContext,
22050
22072
  observabilityContext: this.turn.observabilityContext,
22051
- lastActivityAt: getLastActivityFromMessages(messageList.get.all.db()),
22073
+ lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
22052
22074
  reflectionHooks: om.composeHooks(void 0, {
22053
22075
  threadId,
22054
22076
  resourceId,
@@ -22058,7 +22080,7 @@ var ObservationStep = class {
22058
22080
  await this.turn.refreshRecord();
22059
22081
  if (this.turn.record.generationCount > preReflectGeneration) reflected = true;
22060
22082
  }
22061
- const allMsgsForToolCheck = messageList.get.all.db();
22083
+ const allMsgsForToolCheck = getObservableMessages(messageList);
22062
22084
  const lastMessage = allMsgsForToolCheck[allMsgsForToolCheck.length - 1];
22063
22085
  const pendingStepMessages = [...messageList.get.input.db(), ...messageList.get.response.db()];
22064
22086
  const latestStepParts = [...getLatestStepParts(lastMessage?.content?.parts ?? []), ...pendingStepMessages.flatMap((msg) => getLatestStepParts(msg.content?.parts ?? []))];
@@ -22067,10 +22089,10 @@ var ObservationStep = class {
22067
22089
  let statusSnapshot = await om.getStatus({
22068
22090
  threadId,
22069
22091
  resourceId,
22070
- messages: messageList.get.all.db()
22092
+ messages: getObservableMessages(messageList)
22071
22093
  });
22072
22094
  if (statusSnapshot.shouldBuffer && !hasIncompleteToolCalls) {
22073
- const allMessages = messageList.get.all.db();
22095
+ const allMessages = getObservableMessages(messageList);
22074
22096
  const unobservedMessages = om.getUnobservedMessages(allMessages, statusSnapshot.record);
22075
22097
  const candidates = om.getUnobservedMessages(unobservedMessages, statusSnapshot.record, { excludeBuffered: true });
22076
22098
  if (candidates.length > 0) {
@@ -22162,7 +22184,7 @@ var ObservationStep = class {
22162
22184
  statusSnapshot = await om.getStatus({
22163
22185
  threadId,
22164
22186
  resourceId,
22165
- messages: messageList.get.all.db()
22187
+ messages: getObservableMessages(messageList)
22166
22188
  });
22167
22189
  }
22168
22190
  const otherThreadsContext = await this.turn.refreshOtherThreadsContext();
@@ -22211,7 +22233,7 @@ var ObservationStep = class {
22211
22233
  const { threadId, resourceId, messageList } = this.turn;
22212
22234
  const om = this.turn.om;
22213
22235
  await om.waitForBuffering(threadId, resourceId);
22214
- const observableMessages = this.seededResponseMessage ? messageList.get.all.db().filter((msg) => msg.id !== this.turn.responseMessageId) : messageList.get.all.db();
22236
+ const observableMessages = this.seededResponseMessage ? getObservableMessages(messageList).filter((msg) => msg.id !== this.turn.responseMessageId) : getObservableMessages(messageList);
22215
22237
  const freshStatus = await om.getStatus({
22216
22238
  threadId,
22217
22239
  resourceId,
@@ -22241,7 +22263,7 @@ var ObservationStep = class {
22241
22263
  currentModel: this.turn.actorModelContext,
22242
22264
  requestContext: this.turn.requestContext,
22243
22265
  observabilityContext: this.turn.observabilityContext,
22244
- lastActivityAt: getLastActivityFromMessages(messageList.get.all.db()),
22266
+ lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
22245
22267
  reflectionHooks: om.composeHooks(void 0, {
22246
22268
  threadId,
22247
22269
  resourceId,
@@ -22267,7 +22289,7 @@ var ObservationStep = class {
22267
22289
  });
22268
22290
  if (obsResult.observed) {
22269
22291
  const observedMessageIds = new Set(obsResult.record.observedMessageIds ?? []);
22270
- const liveMessages = messageList.get.all.db();
22292
+ const liveMessages = getObservableMessages(messageList);
22271
22293
  let latestObservedIndex = -1;
22272
22294
  for (let i = liveMessages.length - 1; i >= 0; i--) {
22273
22295
  const message = liveMessages[i];
@@ -22442,7 +22464,7 @@ var ObservationTurn = class {
22442
22464
  const asyncObservationEnabled = this.om.buffering.isAsyncObservationEnabled();
22443
22465
  const bufferOnIdle = this.om.getObservationConfig().bufferOnIdle;
22444
22466
  if (asyncObservationEnabled && bufferOnIdle) {
22445
- const allMessages = this.messageList.get.all.db();
22467
+ const allMessages = getObservableMessages(this.messageList);
22446
22468
  const record = this._record;
22447
22469
  const unobservedMessages = this.om.getUnobservedMessages(allMessages, record);
22448
22470
  if (unobservedMessages.length > 0) this.om.buffer({
@@ -22812,7 +22834,7 @@ function getCurrentModel$1(model) {
22812
22834
  return formatModelContext$1(model?.provider, model?.modelId);
22813
22835
  }
22814
22836
  function getLastModelFromMessageList(messageList) {
22815
- const messages = messageList?.get.all.db();
22837
+ const messages = messageList ? getObservableMessages(messageList) : void 0;
22816
22838
  if (!messages) return void 0;
22817
22839
  for (let i = messages.length - 1; i >= 0; i--) {
22818
22840
  const message = messages[i];
@@ -24396,7 +24418,7 @@ var ObservationalMemory = class ObservationalMemory {
24396
24418
  */
24397
24419
  async persistMarkerToMessage(marker, messageList, threadId, resourceId) {
24398
24420
  if (!messageList) return;
24399
- const allMsgs = messageList.get.all.db();
24421
+ const allMsgs = getObservableMessages(messageList);
24400
24422
  for (let i = allMsgs.length - 1; i >= 0; i--) {
24401
24423
  const msg = allMsgs[i];
24402
24424
  if (msg?.role === "assistant" && msg.content?.parts && Array.isArray(msg.content.parts)) {
@@ -25074,7 +25096,7 @@ ${formattedMessages}
25074
25096
  async cleanupMessages(opts) {
25075
25097
  const { threadId, resourceId, observedMessageIds, retentionFloor, preserveMessageIds } = opts;
25076
25098
  const messageList = this.isMessageList(opts.messages) ? opts.messages : void 0;
25077
- const allMsgs = messageList ? messageList.get.all.db() : opts.messages;
25099
+ const allMsgs = messageList ? getObservableMessages(messageList) : opts.messages;
25078
25100
  let markerIdx = -1;
25079
25101
  let markerMsg = null;
25080
25102
  for (let i = allMsgs.length - 1; i >= 0; i--) {
@@ -26190,7 +26212,7 @@ function isTemporalGapMarkerForMessage(message, targetMessageId) {
26190
26212
  async function insertTemporalGapMarkers({ messageList, sendSignal }) {
26191
26213
  const latestInputMessage = messageList.get.input.db().filter((message) => Boolean(message)).at(-1);
26192
26214
  if (!latestInputMessage || isTemporalGapMarker(latestInputMessage)) return;
26193
- const allMessages = messageList.get.all.db().filter((message) => Boolean(message));
26215
+ const allMessages = getObservableMessages(messageList).filter((message) => Boolean(message));
26194
26216
  const latestInputIndex = allMessages.findIndex((message) => message.id === latestInputMessage.id);
26195
26217
  if (latestInputIndex <= 0) return;
26196
26218
  if (allMessages.some((message) => isTemporalGapMarkerForMessage(message, latestInputMessage.id))) return;
@@ -26414,7 +26436,7 @@ var ObservationalMemoryProcessor = class {
26414
26436
  threadId,
26415
26437
  resourceId
26416
26438
  });
26417
- const allDbMsgs = messageList.get.all.db();
26439
+ const allDbMsgs = getObservableMessages(messageList);
26418
26440
  const tokenCounter = this.engine.getTokenCounter();
26419
26441
  const contextTokens = await tokenCounter.countMessagesAsync(allDbMsgs);
26420
26442
  const otherThreadsContext = this.turn.context.otherThreadsContext;
@@ -26784,6 +26806,18 @@ var Memory = class extends MastraMemory {
26784
26806
  _omEngine;
26785
26807
  _omEngineInstance;
26786
26808
  _mastraInstance;
26809
+ /**
26810
+ * Every vector cleanup that deleteThread or deleteMessages started in the background.
26811
+ * Callers do not wait for the cleanup, so this handle is the only join point.
26812
+ */
26813
+ pendingVectorCleanup = Promise.resolve();
26814
+ /**
26815
+ * Adds a background vector cleanup to the join handle.
26816
+ * The handle keeps the earlier cleanups, so it settles only after all of them end.
26817
+ */
26818
+ trackVectorCleanup(cleanup) {
26819
+ this.pendingVectorCleanup = Promise.allSettled([this.pendingVectorCleanup, cleanup]).then(() => void 0);
26820
+ }
26787
26821
  /** The shared ObservationalMemory engine. Lazily created on first access. */
26788
26822
  get omEngine() {
26789
26823
  if (!this._omEngine) this._omEngine = this._initOMEngine().then((engine) => {
@@ -27048,26 +27082,40 @@ var Memory = class extends MastraMemory {
27048
27082
  const thread = await memoryStore.getThreadById({ threadId });
27049
27083
  await memoryStore.deleteThread({ threadId });
27050
27084
  if (thread?.resourceId && memoryStore.supportsObservationalMemory) await memoryStore.clearObservationalMemory(threadId, thread.resourceId);
27051
- if (this.vector) this.deleteThreadVectors(threadId);
27085
+ if (this.vector) this.trackVectorCleanup(this.deleteThreadVectors(threadId));
27052
27086
  }
27053
27087
  /**
27054
- * Lists all vector indexes that match the memory messages prefix.
27055
- * Handles separator differences across vector store backends (e.g. '_' vs '-').
27088
+ * Prefix shared by every message index. The index for the default embedding
27089
+ * dimension is named with the bare prefix; other dimensions add a suffix.
27056
27090
  */
27057
- async getMemoryVectorIndexes() {
27091
+ get messageIndexPrefix() {
27092
+ return this.getEmbeddingIndexName();
27093
+ }
27094
+ /**
27095
+ * Prefix shared by every observation index. Each observation index adds a dimension suffix.
27096
+ */
27097
+ get observationIndexPrefix() {
27098
+ return `memory${this.vector?.indexSeparator ?? "_"}observations`;
27099
+ }
27100
+ /**
27101
+ * Lists the vector indexes whose name starts with one of the given prefixes.
27102
+ * Index names can carry a dimension suffix, so discovery matches on the prefix.
27103
+ */
27104
+ async getMemoryVectorIndexes(prefixes) {
27058
27105
  if (!this.vector) return [];
27059
- const prefix = `memory${this.vector.indexSeparator ?? "_"}messages`;
27060
- return (await this.vector.listIndexes()).filter((name) => name.startsWith(prefix));
27106
+ return (await this.vector.listIndexes()).filter((name) => prefixes.some((prefix) => name.startsWith(prefix)));
27061
27107
  }
27062
27108
  /**
27063
27109
  * Deletes all vector embeddings associated with a thread.
27064
27110
  * This is called internally by deleteThread to clean up orphaned vectors.
27111
+ * Both message and observation vectors are removed, so no text of the deleted
27112
+ * thread stays reachable through resource-scoped retrieval.
27065
27113
  *
27066
27114
  * @param threadId - The ID of the thread whose vectors should be deleted
27067
27115
  */
27068
27116
  async deleteThreadVectors(threadId) {
27069
27117
  try {
27070
- const memoryIndexes = await this.getMemoryVectorIndexes();
27118
+ const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix, this.observationIndexPrefix]);
27071
27119
  await Promise.all(memoryIndexes.map(async (indexName) => {
27072
27120
  try {
27073
27121
  await this.vector.deleteVectors({
@@ -27075,14 +27123,14 @@ var Memory = class extends MastraMemory {
27075
27123
  filter: { thread_id: threadId }
27076
27124
  });
27077
27125
  } catch {
27078
- this.logger.debug("Failed to delete vectors for thread, skipping", {
27126
+ this.logger.warn("Failed to delete vectors of the deleted thread from index", {
27079
27127
  threadId,
27080
27128
  indexName
27081
27129
  });
27082
27130
  }
27083
27131
  }));
27084
27132
  } catch {
27085
- this.logger.debug("Failed to clean up vectors for thread", { threadId });
27133
+ this.logger.warn("Failed to clean up vectors of the deleted thread", { threadId });
27086
27134
  }
27087
27135
  }
27088
27136
  async updateWorkingMemory({ threadId, resourceId, workingMemory, memoryConfig, observabilityContext }) {
@@ -27755,7 +27803,7 @@ Notes:
27755
27803
  getObservationEmbeddingIndexName(dimensions) {
27756
27804
  const usedDimensions = dimensions ?? 384;
27757
27805
  const separator = this.vector?.indexSeparator ?? "_";
27758
- return `memory${separator}observations${separator}${usedDimensions}`;
27806
+ return `${this.observationIndexPrefix}${separator}${usedDimensions}`;
27759
27807
  }
27760
27808
  async createObservationEmbeddingIndex(dimensions) {
27761
27809
  const usedDimensions = dimensions ?? 384;
@@ -28001,7 +28049,10 @@ Notes:
28001
28049
  tools[name] = tool;
28002
28050
  }
28003
28051
  const omConfig = normalizeObservationalMemoryConfig(mergedConfig.observationalMemory);
28004
- if (omConfig?.retrieval) tools.recall = recallTool(mergedConfig, { retrievalScope: typeof omConfig.retrieval === "object" ? omConfig.retrieval.scope ?? "resource" : "resource" });
28052
+ if (omConfig?.retrieval) tools.recall = recallTool(mergedConfig, {
28053
+ retrievalScope: typeof omConfig.retrieval === "object" ? omConfig.retrieval.scope ?? "resource" : "resource",
28054
+ searchEnabled: this.hasRetrievalSearch(omConfig.retrieval)
28055
+ });
28005
28056
  return tools;
28006
28057
  }
28007
28058
  /**
@@ -28057,7 +28108,7 @@ Notes:
28057
28108
  }));
28058
28109
  const messageIdsNeedingDeletion = /* @__PURE__ */ new Set([...messageIdsWithClearedContent, ...messageIdsWithNewEmbeddings]);
28059
28110
  if (messageIdsNeedingDeletion.size > 0) try {
28060
- const memoryIndexes = await this.getMemoryVectorIndexes();
28111
+ const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
28061
28112
  const idsToDelete = [...messageIdsNeedingDeletion];
28062
28113
  await Promise.all(memoryIndexes.map(async (indexName) => {
28063
28114
  for (let i = 0; i < idsToDelete.length; i += VECTOR_DELETE_BATCH_SIZE) {
@@ -28116,7 +28167,7 @@ Notes:
28116
28167
  const span = this.createMemorySpan("delete", observabilityContext, void 0, { messageCount: messageIds.length });
28117
28168
  try {
28118
28169
  await (await this.getMemoryStore()).deleteMessages(messageIds);
28119
- if (this.vector) this.deleteMessageVectors(messageIds);
28170
+ if (this.vector) this.trackVectorCleanup(this.deleteMessageVectors(messageIds));
28120
28171
  span?.end({
28121
28172
  output: { success: true },
28122
28173
  attributes: { messageCount: messageIds.length }
@@ -28132,12 +28183,14 @@ Notes:
28132
28183
  /**
28133
28184
  * Deletes vector embeddings for specific messages.
28134
28185
  * This is called internally by deleteMessages to clean up orphaned vectors.
28186
+ * Only the message indexes are touched, because observation vectors can hold
28187
+ * text of other messages of the thread.
28135
28188
  *
28136
28189
  * @param messageIds - The IDs of the messages whose vectors should be deleted
28137
28190
  */
28138
28191
  async deleteMessageVectors(messageIds) {
28139
28192
  try {
28140
- const memoryIndexes = await this.getMemoryVectorIndexes();
28193
+ const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
28141
28194
  await Promise.all(memoryIndexes.map(async (indexName) => {
28142
28195
  for (let i = 0; i < messageIds.length; i += VECTOR_DELETE_BATCH_SIZE) {
28143
28196
  const batch = messageIds.slice(i, i + VECTOR_DELETE_BATCH_SIZE);
@@ -28531,4 +28584,4 @@ Notes:
28531
28584
  //#endregion
28532
28585
  export { extractCurrentTask as A, OBSERVATION_CONTEXT_INSTRUCTIONS as B, WorkingMemoryExtractor as C, OBSERVER_SYSTEM_PROMPT as D, TokenCounter as E, injectAnchorIds as F, OBSERVATION_CONTINUATION_HINT as H, parseAnchorId as I, stripEphemeralAnchorIds as L, hasCurrentTaskSection as M, optimizeObservationsForContext as N, buildObserverPrompt as O, parseObserverOutput as P, Extractor as R, deepMergeWorkingMemory as S, summarizeConversation as T, OBSERVATION_CONTEXT_PROMPT as V, reconcileObservationGroupsFromReflection as _, extractWorkingMemoryContent as a, wrapInObservationGroup as b, WORKING_MEMORY_STATE_ID as c, getObservationsAsOf as d, ObservationalMemoryProcessor as f, parseObservationGroups as g, deriveObservationGroupProvenance as h, WorkingMemory as i, formatMessagesForObserver as j, buildObserverSystemPrompt as k, WORKING_MEMORY_STATE_PROCESSOR_ID as l, combineObservationGroupRanges as m, MessageHistory$1 as n, extractWorkingMemoryTags as o, ObservationalMemory as p, SemanticRecall as r, removeWorkingMemoryTags as s, Memory as t, WorkingMemoryStateProcessor as u, renderObservationGroupsForReflection as v, SUMMARIZE_THREAD_DEFAULTS as w, ModelByInputTokens as x, stripObservationGroups as y, OBSERVATIONAL_MEMORY_DEFAULTS as z };
28533
28586
 
28534
- //# sourceMappingURL=src-Iw-V5CfD.js.map
28587
+ //# sourceMappingURL=src-CdqJP57F.js.map