@mastra/server 1.58.0-alpha.0 → 1.58.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.
Files changed (127) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/dist/_types/@mastra_schema-compat/dist/provider-compats/anthropic.d.ts +1 -1
  3. package/dist/{a2a-CnU9zaGR.js → a2a-8C4O2dVJ.js} +41 -5
  4. package/dist/a2a-8C4O2dVJ.js.map +1 -0
  5. package/dist/{a2a-DKnwIgiw.cjs → a2a-B6YkZ2i9.cjs} +872 -227
  6. package/dist/a2a-B6YkZ2i9.cjs.map +1 -0
  7. package/dist/{a2a-oM7aqLz4.cjs → a2a-MPoM5lzS.cjs} +41 -5
  8. package/dist/a2a-MPoM5lzS.cjs.map +1 -0
  9. package/dist/{a2a-uPi5sPwb.js → a2a-_D2EA4oa.js} +861 -228
  10. package/dist/a2a-_D2EA4oa.js.map +1 -0
  11. package/dist/{agent-builder-BDYN3r89.cjs → agent-builder-DAiJH1u2.cjs} +2 -2
  12. package/dist/{agent-builder-BDYN3r89.cjs.map → agent-builder-DAiJH1u2.cjs.map} +1 -1
  13. package/dist/{agent-builder-Dqy_qumV.js → agent-builder-gGFywDVq.js} +2 -2
  14. package/dist/{agent-builder-Dqy_qumV.js.map → agent-builder-gGFywDVq.js.map} +1 -1
  15. package/dist/{api-schema-manifest-7-NC9Dyc.cjs → api-schema-manifest-B3bC-D98.cjs} +2 -2
  16. package/dist/{api-schema-manifest-7-NC9Dyc.cjs.map → api-schema-manifest-B3bC-D98.cjs.map} +1 -1
  17. package/dist/{api-schema-manifest-C5hpdIE_.js → api-schema-manifest-B4J_QYOr.js} +2 -2
  18. package/dist/{api-schema-manifest-C5hpdIE_.js.map → api-schema-manifest-B4J_QYOr.js.map} +1 -1
  19. package/dist/{datasets-Cvix7Rms.cjs → datasets-BMeFvFwT.cjs} +43 -1
  20. package/dist/datasets-BMeFvFwT.cjs.map +1 -0
  21. package/dist/{datasets-dhXnHLAL.js → datasets-BeBH9Seg.js} +38 -2
  22. package/dist/datasets-BeBH9Seg.js.map +1 -0
  23. package/dist/{dist-DGqlUp0b.js → dist-BKRMiJcn.js} +215 -74
  24. package/dist/dist-BKRMiJcn.js.map +1 -0
  25. package/dist/{dist-COHIL6fR.cjs → dist-C2-SedDQ.cjs} +215 -74
  26. package/dist/dist-C2-SedDQ.cjs.map +1 -0
  27. package/dist/docs/SKILL.md +1 -1
  28. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  29. package/dist/docs/references/docs-agents-a2a.md +75 -2
  30. package/dist/docs/references/reference-server-routes.md +25 -11
  31. package/dist/route-builder-CIk5k35M.js.map +1 -1
  32. package/dist/route-builder-CgLVYL1c.cjs.map +1 -1
  33. package/dist/{routes-hSY4wTeS.cjs → routes-CZwPlO3-.cjs} +3 -2
  34. package/dist/routes-CZwPlO3-.cjs.map +1 -0
  35. package/dist/{routes-CRoTKPvQ.js → routes-HUaCyUb7.js} +4 -3
  36. package/dist/{routes-CRoTKPvQ.js.map → routes-HUaCyUb7.js.map} +1 -1
  37. package/dist/server/a2a/store.cjs +30 -2
  38. package/dist/server/a2a/store.cjs.map +1 -1
  39. package/dist/server/a2a/store.d.ts +21 -2
  40. package/dist/server/a2a/store.d.ts.map +1 -1
  41. package/dist/server/a2a/store.js +30 -3
  42. package/dist/server/a2a/store.js.map +1 -1
  43. package/dist/server/a2a/task-state.d.ts +4 -0
  44. package/dist/server/a2a/task-state.d.ts.map +1 -0
  45. package/dist/server/a2a/tasks.d.ts +1 -1
  46. package/dist/server/a2a/tasks.d.ts.map +1 -1
  47. package/dist/server/handlers/a2a.cjs +3 -1
  48. package/dist/server/handlers/a2a.d.ts +155 -12
  49. package/dist/server/handlers/a2a.d.ts.map +1 -1
  50. package/dist/server/handlers/a2a.js +2 -2
  51. package/dist/server/handlers/agent-builder.cjs +3 -3
  52. package/dist/server/handlers/agent-builder.js +3 -3
  53. package/dist/server/handlers/agent-controller.cjs +25 -6
  54. package/dist/server/handlers/agent-controller.cjs.map +1 -1
  55. package/dist/server/handlers/agent-controller.d.ts +4 -3
  56. package/dist/server/handlers/agent-controller.d.ts.map +1 -1
  57. package/dist/server/handlers/agent-controller.js +25 -6
  58. package/dist/server/handlers/agent-controller.js.map +1 -1
  59. package/dist/server/handlers/agent-versions.cjs +6 -0
  60. package/dist/server/handlers/agent-versions.cjs.map +1 -1
  61. package/dist/server/handlers/agent-versions.d.ts.map +1 -1
  62. package/dist/server/handlers/agent-versions.js +6 -0
  63. package/dist/server/handlers/agent-versions.js.map +1 -1
  64. package/dist/server/handlers/datasets.cjs +26 -11
  65. package/dist/server/handlers/datasets.cjs.map +1 -1
  66. package/dist/server/handlers/datasets.d.ts +136 -0
  67. package/dist/server/handlers/datasets.d.ts.map +1 -1
  68. package/dist/server/handlers/datasets.js +26 -11
  69. package/dist/server/handlers/datasets.js.map +1 -1
  70. package/dist/server/handlers/observability.cjs +20 -9
  71. package/dist/server/handlers/observability.cjs.map +1 -1
  72. package/dist/server/handlers/observability.d.ts.map +1 -1
  73. package/dist/server/handlers/observability.js +20 -9
  74. package/dist/server/handlers/observability.js.map +1 -1
  75. package/dist/server/handlers/stored-agents.cjs +16 -1
  76. package/dist/server/handlers/stored-agents.cjs.map +1 -1
  77. package/dist/server/handlers/stored-agents.d.ts.map +1 -1
  78. package/dist/server/handlers/stored-agents.js +16 -1
  79. package/dist/server/handlers/stored-agents.js.map +1 -1
  80. package/dist/server/handlers/system.cjs +1 -1
  81. package/dist/server/handlers/system.js +1 -1
  82. package/dist/server/handlers/validate-agent-instructions.cjs +52 -0
  83. package/dist/server/handlers/validate-agent-instructions.cjs.map +1 -0
  84. package/dist/server/handlers/validate-agent-instructions.d.ts +13 -0
  85. package/dist/server/handlers/validate-agent-instructions.d.ts.map +1 -0
  86. package/dist/server/handlers/validate-agent-instructions.js +51 -0
  87. package/dist/server/handlers/validate-agent-instructions.js.map +1 -0
  88. package/dist/server/handlers/workflows.cjs +105 -2
  89. package/dist/server/handlers/workflows.cjs.map +1 -1
  90. package/dist/server/handlers/workflows.d.ts +9 -0
  91. package/dist/server/handlers/workflows.d.ts.map +1 -1
  92. package/dist/server/handlers/workflows.js +104 -3
  93. package/dist/server/handlers/workflows.js.map +1 -1
  94. package/dist/server/handlers.cjs +1 -1
  95. package/dist/server/handlers.js +1 -1
  96. package/dist/server/schemas/a2a.d.ts +70 -6
  97. package/dist/server/schemas/a2a.d.ts.map +1 -1
  98. package/dist/server/schemas/datasets.d.ts +53 -0
  99. package/dist/server/schemas/datasets.d.ts.map +1 -1
  100. package/dist/server/schemas/index.cjs +5 -4
  101. package/dist/server/schemas/index.js +5 -5
  102. package/dist/server/schemas/workflows.d.ts +8 -0
  103. package/dist/server/schemas/workflows.d.ts.map +1 -1
  104. package/dist/server/server-adapter/index.cjs +1 -1
  105. package/dist/server/server-adapter/index.js +1 -1
  106. package/dist/server/server-adapter/routes/a2a.d.ts +116 -8
  107. package/dist/server/server-adapter/routes/a2a.d.ts.map +1 -1
  108. package/dist/server/server-adapter/routes/datasets.d.ts +136 -0
  109. package/dist/server/server-adapter/routes/datasets.d.ts.map +1 -1
  110. package/dist/server/server-adapter/routes/workflows.d.ts +7 -1
  111. package/dist/server/server-adapter/routes/workflows.d.ts.map +1 -1
  112. package/dist/{workflows-DPW6FrY0.js → workflows-CMU5dz_4.js} +7 -2
  113. package/dist/workflows-CMU5dz_4.js.map +1 -0
  114. package/dist/{workflows-XfiENvkF.cjs → workflows-Dzxr6cmf.cjs} +12 -1
  115. package/dist/workflows-Dzxr6cmf.cjs.map +1 -0
  116. package/package.json +8 -8
  117. package/dist/a2a-CnU9zaGR.js.map +0 -1
  118. package/dist/a2a-DKnwIgiw.cjs.map +0 -1
  119. package/dist/a2a-oM7aqLz4.cjs.map +0 -1
  120. package/dist/a2a-uPi5sPwb.js.map +0 -1
  121. package/dist/datasets-Cvix7Rms.cjs.map +0 -1
  122. package/dist/datasets-dhXnHLAL.js.map +0 -1
  123. package/dist/dist-COHIL6fR.cjs.map +0 -1
  124. package/dist/dist-DGqlUp0b.js.map +0 -1
  125. package/dist/routes-hSY4wTeS.cjs.map +0 -1
  126. package/dist/workflows-DPW6FrY0.js.map +0 -1
  127. package/dist/workflows-XfiENvkF.cjs.map +0 -1
@@ -5959,7 +5959,7 @@ function splitLines(text) {
5959
5959
  return result;
5960
5960
  }
5961
5961
  //#endregion
5962
- //#region ../memory/dist/src-Cwt9gefz.js
5962
+ //#region ../memory/dist/src-CdqJP57F.js
5963
5963
  var __defProp$3 = Object.defineProperty;
5964
5964
  var __exportAll = (all, no_symbols) => {
5965
5965
  let target = {};
@@ -20722,6 +20722,7 @@ var Extractor = class Extractor {
20722
20722
  includePreviousExtraction;
20723
20723
  metadataKeyPath;
20724
20724
  onExtracted;
20725
+ retryStructuredExtractionOnEmptyObject;
20725
20726
  /** @internal */
20726
20727
  internal;
20727
20728
  instructionsConfig;
@@ -20744,6 +20745,7 @@ var Extractor = class Extractor {
20744
20745
  this.includePreviousExtraction = config.includePreviousExtraction ?? true;
20745
20746
  this.metadataKeyPath = config.metadataKeyPath ?? `extracted.${slug}`;
20746
20747
  this.onExtracted = config.onExtracted;
20748
+ this.retryStructuredExtractionOnEmptyObject = config.retryStructuredExtractionOnEmptyObject ?? false;
20747
20749
  this.internal = internal;
20748
20750
  }
20749
20751
  async resolve(context) {
@@ -20756,7 +20758,8 @@ var Extractor = class Extractor {
20756
20758
  ...schema ? { schema } : {},
20757
20759
  includePreviousExtraction: this.includePreviousExtraction,
20758
20760
  metadataKeyPath: this.metadataKeyPath,
20759
- onExtracted: this.onExtracted
20761
+ onExtracted: this.onExtracted,
20762
+ retryStructuredExtractionOnEmptyObject: this.retryStructuredExtractionOnEmptyObject
20760
20763
  }, this.internal);
20761
20764
  }
20762
20765
  };
@@ -21075,6 +21078,9 @@ if (OM_DEBUG_LOG) {
21075
21078
  function isAbortError$1(error, abortSignal) {
21076
21079
  return abortSignal?.aborted === true || error instanceof DOMException && error.name === "AbortError" || error instanceof Error && error.name === "AbortError";
21077
21080
  }
21081
+ function shouldRetryEmptyStructuredObject(object, extractors) {
21082
+ return Object.keys(object).length === 0 && extractors.some((extractor) => extractor.retryStructuredExtractionOnEmptyObject);
21083
+ }
21078
21084
  async function extractStructuredValues(opts) {
21079
21085
  const structuredExtractors = (opts.extractors ?? []).filter((extractor) => extractor.mode === "structured");
21080
21086
  if (structuredExtractors.length === 0) return {
@@ -21111,8 +21117,10 @@ ${extractorInstructions}${priorLines.length > 0 ? `\n\n## Prior Extracted Values
21111
21117
  return output.object;
21112
21118
  };
21113
21119
  let object;
21120
+ let retryEmptyObject = false;
21114
21121
  try {
21115
21122
  object = await generateWithStructuredOutput();
21123
+ retryEmptyObject = shouldRetryEmptyStructuredObject(object, structuredExtractors);
21116
21124
  } catch (error) {
21117
21125
  if (isAbortError$1(error, opts.abortSignal)) throw error;
21118
21126
  try {
@@ -21129,6 +21137,19 @@ ${extractorInstructions}${priorLines.length > 0 ? `\n\n## Prior Extracted Values
21129
21137
  };
21130
21138
  }
21131
21139
  }
21140
+ if (retryEmptyObject) try {
21141
+ object = await generateWithStructuredOutput(coreFeatures.has("json-prompt-injection:inline") ? "inline" : true);
21142
+ } catch (fallbackError) {
21143
+ if (isAbortError$1(fallbackError, opts.abortSignal)) throw fallbackError;
21144
+ const message = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
21145
+ return {
21146
+ values,
21147
+ failures: structuredExtractors.map((extractor) => ({
21148
+ slug: extractor.slug,
21149
+ error: message
21150
+ }))
21151
+ };
21152
+ }
21132
21153
  for (const extractor of structuredExtractors) {
21133
21154
  const value = object[extractor.slug];
21134
21155
  if (value === void 0 || value === null || value === "") continue;
@@ -24412,6 +24433,17 @@ var TokenCounter = class TokenCounter {
24412
24433
  toolResultDelta
24413
24434
  };
24414
24435
  }
24436
+ if (invocation.state === "output-error") {
24437
+ toolResultDelta++;
24438
+ const errorText = invocation.errorText;
24439
+ const errorMessage = typeof errorText === "string" ? errorText : "Tool execution failed";
24440
+ tokens += this.readOrPersistPartEstimate(part, "tool-result-error", errorMessage);
24441
+ return {
24442
+ tokens,
24443
+ overheadDelta,
24444
+ toolResultDelta
24445
+ };
24446
+ }
24415
24447
  throw new Error(`Unhandled tool-invocation state '${part.toolInvocation?.state}' in token counting for part type '${part.type}'`);
24416
24448
  }
24417
24449
  if (typeof part.type === "string" && part.type.startsWith("data-")) return {
@@ -24633,6 +24665,7 @@ var WorkingMemoryExtractor = class extends Extractor {
24633
24665
  name: "Working Memory",
24634
24666
  includePreviousExtraction: false,
24635
24667
  metadataKeyPath: false,
24668
+ retryStructuredExtractionOnEmptyObject: true,
24636
24669
  instructions: async (context) => buildWorkingMemoryInstructions(await getWorkingMemoryDetails(context)),
24637
24670
  schema: async (context) => {
24638
24671
  return (await getWorkingMemoryDetails(context)).usesSchema ? z$2.union([z$2.record(z$2.string(), z$2.unknown()), z$2.null()]) : void 0;
@@ -24779,9 +24812,10 @@ async function listThreadsForResource({ memory, resourceId, currentThreadId, pag
24779
24812
  hasMore
24780
24813
  };
24781
24814
  }
24815
+ 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.";
24782
24816
  async function searchMessagesForResource({ memory, resourceId, currentThreadId, query, topK = 10, maxTokens = DEFAULT_MAX_RESULT_TOKENS, before, after, threadScope }) {
24783
24817
  if (!memory.searchMessages) return {
24784
- results: "Search is not configured. Enable it with `retrieval: { vector: true }` and configure a vector store and embedder on your Memory instance.",
24818
+ results: SEARCH_NOT_CONFIGURED_MESSAGE,
24785
24819
  count: 0
24786
24820
  };
24787
24821
  const MAX_TOPK = 20;
@@ -25327,9 +25361,16 @@ async function recallThreadFromStart({ memory, threadId, resourceId, page = 1, l
25327
25361
  }
25328
25362
  const recallTool = (_memoryConfig, options) => {
25329
25363
  const isResourceScope = (options?.retrievalScope ?? "thread") === "resource";
25364
+ const searchEnabled = options?.searchEnabled ?? true;
25365
+ 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.`;
25366
+ const modeEnum = searchEnabled ? [
25367
+ "messages",
25368
+ "threads",
25369
+ "search"
25370
+ ] : ["messages", "threads"];
25330
25371
  return createTool({
25331
25372
  id: "recall",
25332
- 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.",
25373
+ description,
25333
25374
  inputSchema: {
25334
25375
  $schema: "http://json-schema.org/draft-07/schema#",
25335
25376
  type: "object",
@@ -25337,12 +25378,8 @@ const recallTool = (_memoryConfig, options) => {
25337
25378
  ...isResourceScope ? {
25338
25379
  mode: {
25339
25380
  type: "string",
25340
- enum: [
25341
- "messages",
25342
- "threads",
25343
- "search"
25344
- ],
25345
- 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."
25381
+ enum: modeEnum,
25382
+ 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." : ""}`
25346
25383
  },
25347
25384
  threadId: {
25348
25385
  type: "string",
@@ -25359,18 +25396,14 @@ const recallTool = (_memoryConfig, options) => {
25359
25396
  }
25360
25397
  } : { mode: {
25361
25398
  type: "string",
25362
- enum: [
25363
- "messages",
25364
- "threads",
25365
- "search"
25366
- ],
25367
- 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."
25399
+ enum: modeEnum,
25400
+ 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." : ""}`
25368
25401
  } },
25369
- query: {
25402
+ ...searchEnabled ? { query: {
25370
25403
  type: "string",
25371
25404
  minLength: 1,
25372
25405
  description: "Search query for mode=\"search\". Finds messages semantically similar to this text."
25373
- },
25406
+ } } : {},
25374
25407
  cursor: {
25375
25408
  type: "string",
25376
25409
  minLength: 1,
@@ -25431,6 +25464,10 @@ const recallTool = (_memoryConfig, options) => {
25431
25464
  if (!memory) throw new Error("Memory instance is required for recall");
25432
25465
  if (explicitThreadId === "current" && !currentThreadId) throw new Error("Could not resolve current thread.");
25433
25466
  if (mode === "search") {
25467
+ if (!searchEnabled) return {
25468
+ results: SEARCH_NOT_CONFIGURED_MESSAGE,
25469
+ count: 0
25470
+ };
25434
25471
  if (!query) throw new Error("query is required for mode=\"search\"");
25435
25472
  if (!resourceId) throw new Error("Resource ID is required for recall");
25436
25473
  return searchMessagesForResource({
@@ -26374,6 +26411,24 @@ function getUnobservedPartsPreservingToolCallPairs(message) {
26374
26411
  return preservedCalls.length > 0 ? [...preservedCalls, ...unobservedParts] : unobservedParts;
26375
26412
  }
26376
26413
  /**
26414
+ * Get the messages Observational Memory is allowed to work with.
26415
+ *
26416
+ * Messages supplied through the `context` option are per-run ephemeral input. Core's
26417
+ * persistence contract already treats them as never-persist: `MessageStateManager` routes
26418
+ * them into `userContextMessages`, and `drainUnsavedMessages` only drains input/response.
26419
+ *
26420
+ * OM builds its windows from `get.all.db()`, which includes context messages, and then
26421
+ * seals and persists candidates directly — turning ephemeral context into durable user
26422
+ * messages. Excluding them here keeps OM's window, sealing, persistence and token
26423
+ * accounting consistent with that contract.
26424
+ */
26425
+ function getObservableMessages(messageList) {
26426
+ const allMessages = messageList.get.all.db();
26427
+ const contextMessageIds = messageList.makeMessageSourceChecker().context;
26428
+ if (contextMessageIds.size === 0) return allMessages;
26429
+ return allMessages.filter((message) => !contextMessageIds.has(message.id));
26430
+ }
26431
+ /**
26377
26432
  * Safely extract buffered observation chunks from a record.
26378
26433
  * Handles both array and JSON-string formats, returning empty array if malformed.
26379
26434
  */
@@ -26386,7 +26441,7 @@ function getUnobservedPartsPreservingToolCallPairs(message) {
26386
26441
  */
26387
26442
  function filterObservedMessages(opts) {
26388
26443
  const { messageList, record } = opts;
26389
- const allMessages = messageList.get.all.db();
26444
+ const allMessages = getObservableMessages(messageList);
26390
26445
  const useMarkerBoundaryPruning = opts.useMarkerBoundaryPruning ?? true;
26391
26446
  const preserveMessageIds = opts.preserveMessageIds ?? /* @__PURE__ */ new Set();
26392
26447
  const observedIds = new Set(Array.isArray(record?.observedMessageIds) ? record.observedMessageIds : []);
@@ -26798,7 +26853,7 @@ var ObservationStrategy = class ObservationStrategy {
26798
26853
  transient: true
26799
26854
  }).catch(() => {});
26800
26855
  const markerThreadId = marker.data?.threadId ?? this.opts.threadId;
26801
- await this.persistMarkerToStorage(marker, markerThreadId, this.opts.resourceId);
26856
+ if (!await this.persistMarkerToMessage(marker, this.opts.messageList, markerThreadId, this.opts.resourceId)) await this.persistMarkerToStorage(marker, markerThreadId, this.opts.resourceId);
26802
26857
  }
26803
26858
  getObservationMarkerConfig() {
26804
26859
  return {
@@ -26926,10 +26981,14 @@ var ObservationStrategy = class ObservationStrategy {
26926
26981
  /**
26927
26982
  * Persist a marker part on the last assistant message in a MessageList
26928
26983
  * AND save the updated message to the DB.
26984
+ *
26985
+ * @returns true when a marker was placed on an assistant message, false when
26986
+ * no list was provided or the list contains no assistant message (caller
26987
+ * should fall back to `persistMarkerToStorage`).
26929
26988
  */
26930
26989
  async persistMarkerToMessage(marker, messageList, threadId, resourceId) {
26931
- if (!messageList) return;
26932
- const allMsgs = messageList.get.all.db();
26990
+ if (!messageList) return false;
26991
+ const allMsgs = getObservableMessages(messageList);
26933
26992
  for (let i = allMsgs.length - 1; i >= 0; i--) {
26934
26993
  const msg = allMsgs[i];
26935
26994
  if (msg?.role === "assistant" && msg.content?.parts && Array.isArray(msg.content.parts)) {
@@ -26944,9 +27003,10 @@ var ObservationStrategy = class ObservationStrategy {
26944
27003
  } catch (e) {
26945
27004
  omDebug(`[OM:persistMarker] failed to save marker to DB: ${e}`);
26946
27005
  }
26947
- return;
27006
+ return true;
26948
27007
  }
26949
27008
  }
27009
+ return false;
26950
27010
  }
26951
27011
  };
26952
27012
  var SyncObservationStrategy = class extends ObservationStrategy {
@@ -27743,6 +27803,12 @@ var ObservationStep = class {
27743
27803
  stepNumber;
27744
27804
  _prepared = false;
27745
27805
  _context;
27806
+ /**
27807
+ * True when this step seeded an empty assistant response message for a step-0
27808
+ * observation. While set, the response-id rotation hook must NOT run — rotating
27809
+ * would orphan the seed (markers would sit on a message the agent never streams into).
27810
+ */
27811
+ seededResponseMessage = false;
27746
27812
  constructor(turn, stepNumber) {
27747
27813
  this.turn = turn;
27748
27814
  this.stepNumber = stepNumber;
@@ -27789,7 +27855,7 @@ var ObservationStep = class {
27789
27855
  let didThresholdCleanup = false;
27790
27856
  let observerExchange;
27791
27857
  if (this.stepNumber === 0) {
27792
- const step0Messages = messageList.get.all.db();
27858
+ const step0Messages = getObservableMessages(messageList);
27793
27859
  const activation = await om.activate({
27794
27860
  threadId,
27795
27861
  resourceId,
@@ -27821,7 +27887,7 @@ var ObservationStep = class {
27821
27887
  currentModel: this.turn.actorModelContext,
27822
27888
  requestContext: this.turn.requestContext,
27823
27889
  observabilityContext: this.turn.observabilityContext,
27824
- lastActivityAt: getLastActivityFromMessages(messageList.get.all.db()),
27890
+ lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
27825
27891
  reflectionHooks: om.composeHooks(void 0, {
27826
27892
  threadId,
27827
27893
  resourceId,
@@ -27831,7 +27897,7 @@ var ObservationStep = class {
27831
27897
  await this.turn.refreshRecord();
27832
27898
  if (this.turn.record.generationCount > preReflectGeneration) reflected = true;
27833
27899
  }
27834
- const allMsgsForToolCheck = messageList.get.all.db();
27900
+ const allMsgsForToolCheck = getObservableMessages(messageList);
27835
27901
  const lastMessage = allMsgsForToolCheck[allMsgsForToolCheck.length - 1];
27836
27902
  const pendingStepMessages = [...messageList.get.input.db(), ...messageList.get.response.db()];
27837
27903
  const latestStepParts = [...getLatestStepParts(lastMessage?.content?.parts ?? []), ...pendingStepMessages.flatMap((msg) => getLatestStepParts(msg.content?.parts ?? []))];
@@ -27840,10 +27906,10 @@ var ObservationStep = class {
27840
27906
  let statusSnapshot = await om.getStatus({
27841
27907
  threadId,
27842
27908
  resourceId,
27843
- messages: messageList.get.all.db()
27909
+ messages: getObservableMessages(messageList)
27844
27910
  });
27845
27911
  if (statusSnapshot.shouldBuffer && !hasIncompleteToolCalls) {
27846
- const allMessages = messageList.get.all.db();
27912
+ const allMessages = getObservableMessages(messageList);
27847
27913
  const unobservedMessages = om.getUnobservedMessages(allMessages, statusSnapshot.record);
27848
27914
  const candidates = om.getUnobservedMessages(unobservedMessages, statusSnapshot.record, { excludeBuffered: true });
27849
27915
  if (candidates.length > 0) {
@@ -27871,15 +27937,41 @@ var ObservationStep = class {
27871
27937
  });
27872
27938
  buffered = true;
27873
27939
  }
27874
- if (this.stepNumber > 0) {
27875
- const newInput = messageList.clear.input.db();
27876
- const newOutput = messageList.clear.response.db();
27877
- const messagesToSave = [...newInput, ...newOutput];
27878
- if (messagesToSave.length > 0) {
27879
- await om.persistMessages(messagesToSave, threadId, resourceId);
27880
- for (const msg of messagesToSave) messageList.add(msg, "memory");
27940
+ const willObserveNow = statusSnapshot.shouldObserve && !hasIncompleteToolCalls;
27941
+ /** In-flight message ids the step-0 cleanup must never remove from live context. */
27942
+ let step0PreserveIds;
27943
+ if (this.stepNumber > 0 || willObserveNow) {
27944
+ if (this.stepNumber > 0) {
27945
+ const newInput = messageList.clear.input.db();
27946
+ const newOutput = messageList.clear.response.db();
27947
+ const messagesToSave = [...newInput, ...newOutput];
27948
+ if (messagesToSave.length > 0) {
27949
+ await om.persistMessages(messagesToSave, threadId, resourceId);
27950
+ for (const msg of messagesToSave) messageList.add(msg, "memory");
27951
+ }
27952
+ } else {
27953
+ const pending = [...messageList.get.input.db(), ...messageList.get.response.db()];
27954
+ if (pending.length > 0) await om.persistMessages(pending, threadId, resourceId);
27955
+ step0PreserveIds = pending.map((msg) => msg.id);
27956
+ }
27957
+ if (this.stepNumber === 0 && willObserveNow && this.turn.responseMessageId) {
27958
+ const seed = {
27959
+ id: this.turn.responseMessageId,
27960
+ role: "assistant",
27961
+ content: {
27962
+ format: 2,
27963
+ parts: []
27964
+ },
27965
+ type: "text",
27966
+ createdAt: /* @__PURE__ */ new Date(),
27967
+ threadId,
27968
+ resourceId
27969
+ };
27970
+ messageList.add(seed, "response");
27971
+ this.seededResponseMessage = true;
27972
+ omDebug(`[OM:step0] seeded response message ${seed.id} for step-0 observation markers`);
27881
27973
  }
27882
- if (statusSnapshot.shouldObserve && !hasIncompleteToolCalls) {
27974
+ if (willObserveNow) {
27883
27975
  const preObsGeneration = this.turn.record.generationCount;
27884
27976
  const obsResult = await this.runThresholdObservation();
27885
27977
  observerExchange = obsResult.observerExchange;
@@ -27893,7 +27985,8 @@ var ObservationStep = class {
27893
27985
  resourceId,
27894
27986
  messages: messageList,
27895
27987
  observedMessageIds: observedIds,
27896
- retentionFloor: minRemaining
27988
+ retentionFloor: minRemaining,
27989
+ preserveMessageIds: step0PreserveIds
27897
27990
  });
27898
27991
  if (statusSnapshot.asyncObservationEnabled) await om.resetBufferingState({
27899
27992
  threadId,
@@ -27908,7 +28001,7 @@ var ObservationStep = class {
27908
28001
  statusSnapshot = await om.getStatus({
27909
28002
  threadId,
27910
28003
  resourceId,
27911
- messages: messageList.get.all.db()
28004
+ messages: getObservableMessages(messageList)
27912
28005
  });
27913
28006
  }
27914
28007
  const otherThreadsContext = await this.turn.refreshOtherThreadsContext();
@@ -27957,10 +28050,11 @@ var ObservationStep = class {
27957
28050
  const { threadId, resourceId, messageList } = this.turn;
27958
28051
  const om = this.turn.om;
27959
28052
  await om.waitForBuffering(threadId, resourceId);
28053
+ const observableMessages = this.seededResponseMessage ? getObservableMessages(messageList).filter((msg) => msg.id !== this.turn.responseMessageId) : getObservableMessages(messageList);
27960
28054
  const freshStatus = await om.getStatus({
27961
28055
  threadId,
27962
28056
  resourceId,
27963
- messages: messageList.get.all.db()
28057
+ messages: observableMessages
27964
28058
  });
27965
28059
  if (!freshStatus.shouldObserve) return {
27966
28060
  succeeded: false,
@@ -27970,7 +28064,7 @@ var ObservationStep = class {
27970
28064
  const activation = await om.activate({
27971
28065
  threadId,
27972
28066
  resourceId,
27973
- messages: messageList.get.all.db(),
28067
+ messages: observableMessages,
27974
28068
  currentModel: this.turn.actorModelContext,
27975
28069
  writer: this.turn.writer,
27976
28070
  messageList
@@ -27986,7 +28080,7 @@ var ObservationStep = class {
27986
28080
  currentModel: this.turn.actorModelContext,
27987
28081
  requestContext: this.turn.requestContext,
27988
28082
  observabilityContext: this.turn.observabilityContext,
27989
- lastActivityAt: getLastActivityFromMessages(messageList.get.all.db()),
28083
+ lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
27990
28084
  reflectionHooks: om.composeHooks(void 0, {
27991
28085
  threadId,
27992
28086
  resourceId,
@@ -28003,7 +28097,8 @@ var ObservationStep = class {
28003
28097
  const obsResult = await om.observe({
28004
28098
  threadId,
28005
28099
  resourceId,
28006
- messages: messageList.get.all.db(),
28100
+ messages: observableMessages,
28101
+ messageList,
28007
28102
  trigger: "turn-sync",
28008
28103
  requestContext: this.turn.requestContext,
28009
28104
  writer: this.turn.writer,
@@ -28011,7 +28106,7 @@ var ObservationStep = class {
28011
28106
  });
28012
28107
  if (obsResult.observed) {
28013
28108
  const observedMessageIds = new Set(obsResult.record.observedMessageIds ?? []);
28014
- const liveMessages = messageList.get.all.db();
28109
+ const liveMessages = getObservableMessages(messageList);
28015
28110
  let latestObservedIndex = -1;
28016
28111
  for (let i = liveMessages.length - 1; i >= 0; i--) {
28017
28112
  const message = liveMessages[i];
@@ -28020,10 +28115,12 @@ var ObservationStep = class {
28020
28115
  break;
28021
28116
  }
28022
28117
  }
28023
- const messageToSeal = latestObservedIndex >= 0 ? liveMessages[latestObservedIndex] : void 0;
28118
+ let messageToSeal = latestObservedIndex >= 0 ? liveMessages[latestObservedIndex] : void 0;
28119
+ if (this.stepNumber === 0 && messageToSeal?.role !== "assistant") messageToSeal = void 0;
28024
28120
  const messagesToSeal = messageToSeal ? [messageToSeal] : [];
28025
28121
  om.sealMessagesForBuffering(messagesToSeal);
28026
- try {
28122
+ if (this.seededResponseMessage) omDebug("[OM:observe] skipping response-id rotation — step-0 seeded response message holds the active id");
28123
+ else try {
28027
28124
  await this.turn.hooks?.onSyncObservationComplete?.();
28028
28125
  } catch (error) {
28029
28126
  omDebug(`[OM:observe] onSyncObservationComplete hook failed: ${error instanceof Error ? error.message : String(error)}`);
@@ -28082,6 +28179,8 @@ var ObservationTurn = class {
28082
28179
  sendSignal;
28083
28180
  /** Current actor model for this step. Updated by the processor before prepare(). */
28084
28181
  actorModelContext;
28182
+ /** The active assistant response message ID for this step. Updated by the processor before prepare(). */
28183
+ responseMessageId;
28085
28184
  /** Processor-provided hooks for turn/step lifecycle integration. */
28086
28185
  hooks;
28087
28186
  constructor(opts) {
@@ -28180,7 +28279,7 @@ var ObservationTurn = class {
28180
28279
  const asyncObservationEnabled = this.om.buffering.isAsyncObservationEnabled();
28181
28280
  const bufferOnIdle = this.om.getObservationConfig().bufferOnIdle;
28182
28281
  if (asyncObservationEnabled && bufferOnIdle) {
28183
- const allMessages = this.messageList.get.all.db();
28282
+ const allMessages = getObservableMessages(this.messageList);
28184
28283
  const record = this._record;
28185
28284
  const unobservedMessages = this.om.getUnobservedMessages(allMessages, record);
28186
28285
  if (unobservedMessages.length > 0) this.om.buffer({
@@ -28546,7 +28645,7 @@ function getCurrentModel$1(model) {
28546
28645
  return formatModelContext$1(model?.provider, model?.modelId);
28547
28646
  }
28548
28647
  function getLastModelFromMessageList(messageList) {
28549
- const messages = messageList?.get.all.db();
28648
+ const messages = messageList ? getObservableMessages(messageList) : void 0;
28550
28649
  if (!messages) return void 0;
28551
28650
  for (let i = messages.length - 1; i >= 0; i--) {
28552
28651
  const message = messages[i];
@@ -30126,7 +30225,7 @@ var ObservationalMemory = class ObservationalMemory {
30126
30225
  */
30127
30226
  async persistMarkerToMessage(marker, messageList, threadId, resourceId) {
30128
30227
  if (!messageList) return;
30129
- const allMsgs = messageList.get.all.db();
30228
+ const allMsgs = getObservableMessages(messageList);
30130
30229
  for (let i = allMsgs.length - 1; i >= 0; i--) {
30131
30230
  const msg = allMsgs[i];
30132
30231
  if (msg?.role === "assistant" && msg.content?.parts && Array.isArray(msg.content.parts)) {
@@ -30742,6 +30841,7 @@ ${formattedMessages}
30742
30841
  */
30743
30842
  async getObservedMessageIdsForCleanup(opts) {
30744
30843
  const { threadId, resourceId, messages, observedMessageIds, retentionFloor } = opts;
30844
+ const preserveSet = opts.preserveMessageIds?.length ? new Set(opts.preserveMessageIds) : null;
30745
30845
  const record = await this.getOrCreateRecord(threadId, resourceId);
30746
30846
  const effectiveObservedIds = observedMessageIds && observedMessageIds.length > 0 ? observedMessageIds : Array.isArray(record.observedMessageIds) ? record.observedMessageIds : [];
30747
30847
  if (effectiveObservedIds.length === 0) return [];
@@ -30753,6 +30853,10 @@ ${formattedMessages}
30753
30853
  const retentionCounter = typeof retentionFloor === "number" ? new TokenCounter() : null;
30754
30854
  for (const msg of messages) {
30755
30855
  if (!msg?.id || msg.id === "om-continuation" || !observedSet.has(msg.id)) continue;
30856
+ if (preserveSet?.has(msg.id)) {
30857
+ skipped += 1;
30858
+ continue;
30859
+ }
30756
30860
  const unobservedParts = getUnobservedParts(msg);
30757
30861
  const totalParts = msg.content?.parts?.length ?? 0;
30758
30862
  if (unobservedParts.length > 0 && unobservedParts.length < totalParts) {
@@ -30797,9 +30901,9 @@ ${formattedMessages}
30797
30901
  */
30798
30902
  /** @internal Used by ObservationStep. */
30799
30903
  async cleanupMessages(opts) {
30800
- const { threadId, resourceId, observedMessageIds, retentionFloor } = opts;
30904
+ const { threadId, resourceId, observedMessageIds, retentionFloor, preserveMessageIds } = opts;
30801
30905
  const messageList = this.isMessageList(opts.messages) ? opts.messages : void 0;
30802
- const allMsgs = messageList ? messageList.get.all.db() : opts.messages;
30906
+ const allMsgs = messageList ? getObservableMessages(messageList) : opts.messages;
30803
30907
  let markerIdx = -1;
30804
30908
  let markerMsg = null;
30805
30909
  for (let i = allMsgs.length - 1; i >= 0; i--) {
@@ -30818,7 +30922,8 @@ ${formattedMessages}
30818
30922
  resourceId,
30819
30923
  messages: allMsgs,
30820
30924
  observedMessageIds,
30821
- retentionFloor
30925
+ retentionFloor,
30926
+ preserveMessageIds
30822
30927
  });
30823
30928
  if (messageList) {
30824
30929
  if (idsToRemoveList.length > 0) messageList.removeByIds(idsToRemoveList);
@@ -30830,18 +30935,21 @@ ${formattedMessages}
30830
30935
  if (markerMsg && markerIdx !== -1) {
30831
30936
  const idsToRemove = [];
30832
30937
  const messagesToSave = [];
30938
+ const preserveSet = preserveMessageIds?.length ? new Set(preserveMessageIds) : null;
30833
30939
  for (let i = 0; i < markerIdx; i++) {
30834
30940
  const msg = allMsgs[i];
30835
- if (msg?.id && msg.id !== "om-continuation") {
30941
+ if (msg?.id && msg.id !== "om-continuation" && !preserveSet?.has(msg.id)) {
30836
30942
  idsToRemove.push(msg.id);
30837
30943
  messagesToSave.push(msg);
30838
30944
  }
30839
30945
  }
30840
30946
  messagesToSave.push(markerMsg);
30841
- const unobservedParts = getUnobservedParts(markerMsg);
30842
- if (unobservedParts.length === 0) {
30843
- if (markerMsg.id) idsToRemove.push(markerMsg.id);
30844
- } else if (unobservedParts.length < (markerMsg.content?.parts?.length ?? 0)) markerMsg.content.parts = unobservedParts;
30947
+ if (!Boolean(markerMsg.id && preserveSet?.has(markerMsg.id))) {
30948
+ const unobservedParts = getUnobservedParts(markerMsg);
30949
+ if (unobservedParts.length === 0) {
30950
+ if (markerMsg.id) idsToRemove.push(markerMsg.id);
30951
+ } else if (unobservedParts.length < (markerMsg.content?.parts?.length ?? 0)) markerMsg.content.parts = unobservedParts;
30952
+ }
30845
30953
  if (messageList) {
30846
30954
  if (idsToRemove.length > 0) messageList.removeByIds(idsToRemove);
30847
30955
  if (messagesToSave.length > 0) await this.persistMessages(messagesToSave, threadId, resourceId);
@@ -31628,6 +31736,7 @@ ${formattedMessages}
31628
31736
  threadId,
31629
31737
  resourceId,
31630
31738
  messages: unobservedMessages,
31739
+ messageList: opts.messageList,
31631
31740
  reflectionHooks,
31632
31741
  agent: opts.agent,
31633
31742
  requestContext,
@@ -31908,7 +32017,7 @@ function isTemporalGapMarkerForMessage(message, targetMessageId) {
31908
32017
  async function insertTemporalGapMarkers({ messageList, sendSignal }) {
31909
32018
  const latestInputMessage = messageList.get.input.db().filter((message) => Boolean(message)).at(-1);
31910
32019
  if (!latestInputMessage || isTemporalGapMarker(latestInputMessage)) return;
31911
- const allMessages = messageList.get.all.db().filter((message) => Boolean(message));
32020
+ const allMessages = getObservableMessages(messageList).filter((message) => Boolean(message));
31912
32021
  const latestInputIndex = allMessages.findIndex((message) => message.id === latestInputMessage.id);
31913
32022
  if (latestInputIndex <= 0) return;
31914
32023
  if (allMessages.some((message) => isTemporalGapMarkerForMessage(message, latestInputMessage.id))) return;
@@ -32013,7 +32122,7 @@ var ObservationalMemoryProcessor = class {
32013
32122
  this.temporalMarkers = options?.temporalMarkers ?? false;
32014
32123
  }
32015
32124
  async processInputStep(args) {
32016
- const { messageList, requestContext, stepNumber, state: _state, writer, model, abortSignal, abort, rotateResponseMessageId } = args;
32125
+ const { messageList, requestContext, stepNumber, state: _state, writer, model, abortSignal, abort, messageId, rotateResponseMessageId } = args;
32017
32126
  const state = _state ?? {};
32018
32127
  omDebug(`[OM:processInputStep:ENTER] step=${stepNumber}, hasMastraMemory=${!!requestContext?.get("MastraMemory")}, hasMemoryInfo=${!!messageList?.serialize()?.memoryInfo?.threadId}`);
32019
32128
  const context = this.engine.getThreadContext(requestContext, messageList);
@@ -32099,6 +32208,7 @@ var ObservationalMemoryProcessor = class {
32099
32208
  state.__omObservabilityContext = observabilityContext;
32100
32209
  this.turn.observabilityContext = observabilityContext;
32101
32210
  this.turn.actorModelContext = actorModelContext;
32211
+ this.turn.responseMessageId = messageId;
32102
32212
  {
32103
32213
  const step = this.turn.step(stepNumber);
32104
32214
  let ctx;
@@ -32129,7 +32239,7 @@ var ObservationalMemoryProcessor = class {
32129
32239
  threadId,
32130
32240
  resourceId
32131
32241
  });
32132
- const allDbMsgs = messageList.get.all.db();
32242
+ const allDbMsgs = getObservableMessages(messageList);
32133
32243
  const tokenCounter = this.engine.getTokenCounter();
32134
32244
  const contextTokens = await tokenCounter.countMessagesAsync(allDbMsgs);
32135
32245
  const otherThreadsContext = this.turn.context.otherThreadsContext;
@@ -32476,6 +32586,18 @@ var Memory = class extends MastraMemory {
32476
32586
  _omEngine;
32477
32587
  _omEngineInstance;
32478
32588
  _mastraInstance;
32589
+ /**
32590
+ * Every vector cleanup that deleteThread or deleteMessages started in the background.
32591
+ * Callers do not wait for the cleanup, so this handle is the only join point.
32592
+ */
32593
+ pendingVectorCleanup = Promise.resolve();
32594
+ /**
32595
+ * Adds a background vector cleanup to the join handle.
32596
+ * The handle keeps the earlier cleanups, so it settles only after all of them end.
32597
+ */
32598
+ trackVectorCleanup(cleanup) {
32599
+ this.pendingVectorCleanup = Promise.allSettled([this.pendingVectorCleanup, cleanup]).then(() => void 0);
32600
+ }
32479
32601
  /** The shared ObservationalMemory engine. Lazily created on first access. */
32480
32602
  get omEngine() {
32481
32603
  if (!this._omEngine) this._omEngine = this._initOMEngine().then((engine) => {
@@ -32740,26 +32862,40 @@ var Memory = class extends MastraMemory {
32740
32862
  const thread = await memoryStore.getThreadById({ threadId });
32741
32863
  await memoryStore.deleteThread({ threadId });
32742
32864
  if (thread?.resourceId && memoryStore.supportsObservationalMemory) await memoryStore.clearObservationalMemory(threadId, thread.resourceId);
32743
- if (this.vector) this.deleteThreadVectors(threadId);
32865
+ if (this.vector) this.trackVectorCleanup(this.deleteThreadVectors(threadId));
32744
32866
  }
32745
32867
  /**
32746
- * Lists all vector indexes that match the memory messages prefix.
32747
- * Handles separator differences across vector store backends (e.g. '_' vs '-').
32868
+ * Prefix shared by every message index. The index for the default embedding
32869
+ * dimension is named with the bare prefix; other dimensions add a suffix.
32748
32870
  */
32749
- async getMemoryVectorIndexes() {
32871
+ get messageIndexPrefix() {
32872
+ return this.getEmbeddingIndexName();
32873
+ }
32874
+ /**
32875
+ * Prefix shared by every observation index. Each observation index adds a dimension suffix.
32876
+ */
32877
+ get observationIndexPrefix() {
32878
+ return `memory${this.vector?.indexSeparator ?? "_"}observations`;
32879
+ }
32880
+ /**
32881
+ * Lists the vector indexes whose name starts with one of the given prefixes.
32882
+ * Index names can carry a dimension suffix, so discovery matches on the prefix.
32883
+ */
32884
+ async getMemoryVectorIndexes(prefixes) {
32750
32885
  if (!this.vector) return [];
32751
- const prefix = `memory${this.vector.indexSeparator ?? "_"}messages`;
32752
- return (await this.vector.listIndexes()).filter((name) => name.startsWith(prefix));
32886
+ return (await this.vector.listIndexes()).filter((name) => prefixes.some((prefix) => name.startsWith(prefix)));
32753
32887
  }
32754
32888
  /**
32755
32889
  * Deletes all vector embeddings associated with a thread.
32756
32890
  * This is called internally by deleteThread to clean up orphaned vectors.
32891
+ * Both message and observation vectors are removed, so no text of the deleted
32892
+ * thread stays reachable through resource-scoped retrieval.
32757
32893
  *
32758
32894
  * @param threadId - The ID of the thread whose vectors should be deleted
32759
32895
  */
32760
32896
  async deleteThreadVectors(threadId) {
32761
32897
  try {
32762
- const memoryIndexes = await this.getMemoryVectorIndexes();
32898
+ const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix, this.observationIndexPrefix]);
32763
32899
  await Promise.all(memoryIndexes.map(async (indexName) => {
32764
32900
  try {
32765
32901
  await this.vector.deleteVectors({
@@ -32767,14 +32903,14 @@ var Memory = class extends MastraMemory {
32767
32903
  filter: { thread_id: threadId }
32768
32904
  });
32769
32905
  } catch {
32770
- this.logger.debug("Failed to delete vectors for thread, skipping", {
32906
+ this.logger.warn("Failed to delete vectors of the deleted thread from index", {
32771
32907
  threadId,
32772
32908
  indexName
32773
32909
  });
32774
32910
  }
32775
32911
  }));
32776
32912
  } catch {
32777
- this.logger.debug("Failed to clean up vectors for thread", { threadId });
32913
+ this.logger.warn("Failed to clean up vectors of the deleted thread", { threadId });
32778
32914
  }
32779
32915
  }
32780
32916
  async updateWorkingMemory({ threadId, resourceId, workingMemory, memoryConfig, observabilityContext }) {
@@ -33447,7 +33583,7 @@ Notes:
33447
33583
  getObservationEmbeddingIndexName(dimensions) {
33448
33584
  const usedDimensions = dimensions ?? 384;
33449
33585
  const separator = this.vector?.indexSeparator ?? "_";
33450
- return `memory${separator}observations${separator}${usedDimensions}`;
33586
+ return `${this.observationIndexPrefix}${separator}${usedDimensions}`;
33451
33587
  }
33452
33588
  async createObservationEmbeddingIndex(dimensions) {
33453
33589
  const usedDimensions = dimensions ?? 384;
@@ -33693,7 +33829,10 @@ Notes:
33693
33829
  tools[name] = tool;
33694
33830
  }
33695
33831
  const omConfig = normalizeObservationalMemoryConfig(mergedConfig.observationalMemory);
33696
- if (omConfig?.retrieval) tools.recall = recallTool(mergedConfig, { retrievalScope: typeof omConfig.retrieval === "object" ? omConfig.retrieval.scope ?? "resource" : "resource" });
33832
+ if (omConfig?.retrieval) tools.recall = recallTool(mergedConfig, {
33833
+ retrievalScope: typeof omConfig.retrieval === "object" ? omConfig.retrieval.scope ?? "resource" : "resource",
33834
+ searchEnabled: this.hasRetrievalSearch(omConfig.retrieval)
33835
+ });
33697
33836
  return tools;
33698
33837
  }
33699
33838
  /**
@@ -33749,7 +33888,7 @@ Notes:
33749
33888
  }));
33750
33889
  const messageIdsNeedingDeletion = /* @__PURE__ */ new Set([...messageIdsWithClearedContent, ...messageIdsWithNewEmbeddings]);
33751
33890
  if (messageIdsNeedingDeletion.size > 0) try {
33752
- const memoryIndexes = await this.getMemoryVectorIndexes();
33891
+ const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
33753
33892
  const idsToDelete = [...messageIdsNeedingDeletion];
33754
33893
  await Promise.all(memoryIndexes.map(async (indexName) => {
33755
33894
  for (let i = 0; i < idsToDelete.length; i += VECTOR_DELETE_BATCH_SIZE) {
@@ -33808,7 +33947,7 @@ Notes:
33808
33947
  const span = this.createMemorySpan("delete", observabilityContext, void 0, { messageCount: messageIds.length });
33809
33948
  try {
33810
33949
  await (await this.getMemoryStore()).deleteMessages(messageIds);
33811
- if (this.vector) this.deleteMessageVectors(messageIds);
33950
+ if (this.vector) this.trackVectorCleanup(this.deleteMessageVectors(messageIds));
33812
33951
  span?.end({
33813
33952
  output: { success: true },
33814
33953
  attributes: { messageCount: messageIds.length }
@@ -33824,12 +33963,14 @@ Notes:
33824
33963
  /**
33825
33964
  * Deletes vector embeddings for specific messages.
33826
33965
  * This is called internally by deleteMessages to clean up orphaned vectors.
33966
+ * Only the message indexes are touched, because observation vectors can hold
33967
+ * text of other messages of the thread.
33827
33968
  *
33828
33969
  * @param messageIds - The IDs of the messages whose vectors should be deleted
33829
33970
  */
33830
33971
  async deleteMessageVectors(messageIds) {
33831
33972
  try {
33832
- const memoryIndexes = await this.getMemoryVectorIndexes();
33973
+ const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
33833
33974
  await Promise.all(memoryIndexes.map(async (indexName) => {
33834
33975
  for (let i = 0; i < messageIds.length; i += VECTOR_DELETE_BATCH_SIZE) {
33835
33976
  const batch = messageIds.slice(i, i + VECTOR_DELETE_BATCH_SIZE);
@@ -44602,4 +44743,4 @@ const agentBuilderWorkflows = {
44602
44743
  //#endregion
44603
44744
  export { agentBuilderWorkflows };
44604
44745
 
44605
- //# sourceMappingURL=dist-DGqlUp0b.js.map
44746
+ //# sourceMappingURL=dist-BKRMiJcn.js.map