@mastra/server 1.79.0-alpha.4 → 1.79.0-alpha.5

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 (28) hide show
  1. package/dist/{dist-CSVQ5lzr.js → dist-CDWrMMfM.js} +94 -10
  2. package/dist/{dist-CSVQ5lzr.js.map → dist-CDWrMMfM.js.map} +1 -1
  3. package/dist/{dist-Bi2UyBDO.cjs → dist-DzR11T7C.cjs} +94 -10
  4. package/dist/{dist-Bi2UyBDO.cjs.map → dist-DzR11T7C.cjs.map} +1 -1
  5. package/dist/docs/SKILL.md +2 -2
  6. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  7. package/dist/docs/references/{reference-observability-tracing-trace-query.md → reference-observability-tracing-advanced-queries.md} +439 -149
  8. package/dist/server/handlers/agent-builder.cjs +1 -1
  9. package/dist/server/handlers/agent-builder.js +1 -1
  10. package/dist/server/handlers/mcp-client-versions.cjs +1 -1
  11. package/dist/server/handlers/mcp-client-versions.js +1 -1
  12. package/dist/server/handlers/prompt-block-versions.cjs +1 -1
  13. package/dist/server/handlers/prompt-block-versions.js +1 -1
  14. package/dist/server/handlers/scorer-versions.cjs +1 -1
  15. package/dist/server/handlers/scorer-versions.js +1 -1
  16. package/dist/server/handlers/stored-mcp-clients.cjs +1 -1
  17. package/dist/server/handlers/stored-mcp-clients.js +1 -1
  18. package/dist/server/handlers/stored-prompt-blocks.cjs +1 -1
  19. package/dist/server/handlers/stored-prompt-blocks.js +1 -1
  20. package/dist/server/handlers/stored-scorers.cjs +1 -1
  21. package/dist/server/handlers/stored-scorers.js +1 -1
  22. package/dist/server/handlers/stored-skill-favorites.cjs +1 -1
  23. package/dist/server/handlers/stored-skill-favorites.js +1 -1
  24. package/dist/server/handlers/stored-skills.cjs +1 -1
  25. package/dist/server/handlers/stored-skills.js +1 -1
  26. package/dist/server/schemas/index.cjs +1 -1
  27. package/dist/server/schemas/index.js +1 -1
  28. package/package.json +6 -6
@@ -4637,7 +4637,7 @@ function splitLines(text) {
4637
4637
  return result;
4638
4638
  }
4639
4639
  //#endregion
4640
- //#region ../memory/dist/src-BDhP0_OK.js
4640
+ //#region ../memory/dist/src-Dg8w4Ud-.js
4641
4641
  var __defProp$3 = Object.defineProperty;
4642
4642
  var __exportAll = (all, no_symbols) => {
4643
4643
  let target = {};
@@ -33015,6 +33015,7 @@ var ObservationStep = class {
33015
33015
  let observerExchange;
33016
33016
  const step0Messages = this.stepNumber === 0 ? getObservableMessages(messageList) : [];
33017
33017
  if (this.stepNumber === 0) {
33018
+ this.turn.inputMessageIds = messageList.get.input.db().map((msg) => msg.id);
33018
33019
  const activation = await om.activate({
33019
33020
  threadId,
33020
33021
  resourceId,
@@ -33122,13 +33123,27 @@ var ObservationStep = class {
33122
33123
  }
33123
33124
  const bandDefersObservation = statusSnapshot.inAsyncObservationBand && !statusSnapshot.canActivate;
33124
33125
  const willObserveNow = statusSnapshot.shouldObserve && !hasIncompleteToolCalls && !bandDefersObservation;
33125
- /** In-flight message ids the step-0 cleanup must never remove from live context. */
33126
- let step0PreserveIds;
33126
+ /**
33127
+ * In-flight message ids cleanup must never remove from live context: the turn's own
33128
+ * request, plus whatever the model has not read yet (the pending messages at step 0, the
33129
+ * previous step's output — e.g. a tool result — at step > 0).
33130
+ */
33131
+ let inFlightIds;
33127
33132
  if (this.stepNumber > 0 || willObserveNow) {
33128
33133
  if (this.stepNumber > 0) {
33129
33134
  const newInput = messageList.clear.input.db();
33130
33135
  const newOutput = messageList.clear.response.db();
33131
33136
  const messagesToSave = [...newInput, ...newOutput];
33137
+ const drainedIds = new Set(messagesToSave.map((msg) => msg.id));
33138
+ const updatedEarlier = messageList.get.all.db().filter((msg) => !drainedIds.has(msg.id) && this.turn.drainedPartKeys.has(msg.id));
33139
+ const drainedKeys = /* @__PURE__ */ new Map();
33140
+ const unreadIds = [...messagesToSave, ...updatedEarlier].filter((msg) => {
33141
+ const keys = getPartKeys(msg);
33142
+ const seen = this.turn.drainedPartKeys.get(msg.id);
33143
+ drainedKeys.set(msg.id, /* @__PURE__ */ new Set([...seen ?? [], ...keys]));
33144
+ return !seen || keys.some((key) => !seen.has(key));
33145
+ }).map((msg) => msg.id);
33146
+ inFlightIds = [.../* @__PURE__ */ new Set([...this.turn.inputMessageIds, ...unreadIds])];
33132
33147
  if (messagesToSave.length > 0) {
33133
33148
  for (const msg of messagesToSave) messageList.add(msg, "memory");
33134
33149
  try {
@@ -33139,10 +33154,11 @@ var ObservationStep = class {
33139
33154
  throw error;
33140
33155
  }
33141
33156
  }
33157
+ for (const [id, keys] of drainedKeys) this.turn.drainedPartKeys.set(id, keys);
33142
33158
  } else {
33143
33159
  const pending = [...messageList.get.input.db(), ...messageList.get.response.db()];
33144
33160
  if (pending.length > 0) await om.persistMessages(pending, threadId, resourceId);
33145
- step0PreserveIds = pending.map((msg) => msg.id);
33161
+ inFlightIds = pending.map((msg) => msg.id);
33146
33162
  }
33147
33163
  if (this.stepNumber === 0 && willObserveNow && this.turn.responseMessageId) {
33148
33164
  const seed = {
@@ -33176,7 +33192,7 @@ var ObservationStep = class {
33176
33192
  messages: messageList,
33177
33193
  observedMessageIds: observedIds,
33178
33194
  retentionFloor: minRemaining,
33179
- preserveMessageIds: step0PreserveIds
33195
+ preserveMessageIds: [...inFlightIds ?? [], ...this.changedSinceDrain(messageList)]
33180
33196
  });
33181
33197
  if (statusSnapshot.asyncObservationEnabled) await om.resetBufferingState({
33182
33198
  threadId,
@@ -33204,7 +33220,7 @@ var ObservationStep = class {
33204
33220
  });
33205
33221
  if (!didThresholdCleanup) {
33206
33222
  const fallbackCursor = this.turn.record.threadId ? (0, _mastra_core_memory.getThreadOMMetadata)((await om.getStorage().getThreadById({ threadId: this.turn.record.threadId }))?.metadata)?.lastObservedMessageCursor : void 0;
33207
- const pendingMessageIds = new Set([...messageList.get.input.db(), ...messageList.get.response.db()].map((msg) => msg.id).filter(Boolean));
33223
+ const pendingMessageIds = new Set([...messageList.get.input.db(), ...messageList.get.response.db()].map((msg) => msg.id).concat(inFlightIds ?? [], this.turn.inputMessageIds, this.changedSinceDrain(messageList)).filter(Boolean));
33208
33224
  filterObservedMessages({
33209
33225
  messageList,
33210
33226
  record: this.turn.record,
@@ -33233,6 +33249,13 @@ var ObservationStep = class {
33233
33249
  this._prepared = true;
33234
33250
  return this._context;
33235
33251
  }
33252
+ /** Ids of already-drained messages that now hold parts the model has not been sent. */
33253
+ changedSinceDrain(messageList) {
33254
+ return messageList.get.all.db().filter((msg) => {
33255
+ const seen = this.turn.drainedPartKeys.get(msg.id);
33256
+ return seen !== void 0 && getPartKeys(msg).some((key) => !seen.has(key));
33257
+ }).map((msg) => msg.id);
33258
+ }
33236
33259
  /**
33237
33260
  * Run the full threshold observation pipeline:
33238
33261
  * waitForBuffering → re-check → activate buffered chunks → reflect → observe
@@ -33406,6 +33429,49 @@ function restoreDrainedMessages(messageList, drained, source) {
33406
33429
  for (const msg of messageList.removeByIds(ids)) messageList.add(msg, source, { merge: false });
33407
33430
  }
33408
33431
  /**
33432
+ * Identity keys of a message's non-marker parts. Tool parts are keyed by call id, state and result,
33433
+ * so a result merged in place into an existing tool-invocation part yields a new key. Bookkeeping
33434
+ * fields that change when a part is re-stamped are not part of the identity.
33435
+ */
33436
+ function getPartKeys(msg) {
33437
+ const seen = /* @__PURE__ */ new Map();
33438
+ return (msg.content.parts ?? []).flatMap((part) => {
33439
+ if (part.type.startsWith("data-om-")) return [];
33440
+ let identity;
33441
+ if (part.type === "tool-invocation") identity = toolPartIdentity(part.toolInvocation);
33442
+ else {
33443
+ const { providerMetadata: _providerMetadata, createdAt: _createdAt, updatedAt: _updatedAt, ...rest } = part;
33444
+ identity = JSON.stringify(rest);
33445
+ }
33446
+ const ordinal = seen.get(identity) ?? 0;
33447
+ seen.set(identity, ordinal + 1);
33448
+ return [`${identity}#${ordinal}`];
33449
+ });
33450
+ }
33451
+ /**
33452
+ * Serializing a tool result on every step is quadratic in turn length (each step rescans every drained
33453
+ * message), so the identity is cached per invocation object and reused while its state and result
33454
+ * reference are unchanged. A result merged in place replaces that reference and is re-serialized.
33455
+ */
33456
+ const toolPartIdentityCache = /* @__PURE__ */ new WeakMap();
33457
+ function toolPartIdentity(invocation) {
33458
+ const result = invocation.state === "result" ? invocation.result : null;
33459
+ const cached = toolPartIdentityCache.get(invocation);
33460
+ if (cached && cached.state === invocation.state && cached.result === result) return cached.identity;
33461
+ const identity = JSON.stringify([
33462
+ "tool-invocation",
33463
+ invocation.toolCallId,
33464
+ invocation.state,
33465
+ result
33466
+ ]);
33467
+ toolPartIdentityCache.set(invocation, {
33468
+ state: invocation.state,
33469
+ result,
33470
+ identity
33471
+ });
33472
+ return identity;
33473
+ }
33474
+ /**
33409
33475
  * Represents a single turn in the agent conversation — one user message → agent response cycle.
33410
33476
  *
33411
33477
  * The turn manages record caching, context loading, and step lifecycle.
@@ -33436,6 +33502,19 @@ var ObservationTurn = class {
33436
33502
  _ended = false;
33437
33503
  /** Generation count at turn start — used to detect if reflection happened during the turn. */
33438
33504
  _generationCountAtStart = -1;
33505
+ /**
33506
+ * Ids of the messages this turn was started with (the user's request). Mid-turn
33507
+ * observation may record them, but they stay in the live prompt until the turn ends.
33508
+ * @internal Set by step 0.
33509
+ */
33510
+ inputMessageIds = [];
33511
+ /**
33512
+ * Fingerprints of the non-marker parts each message had when a step last drained it. A message
33513
+ * is unread step output only if it gained a part the model has not seen — including a tool result
33514
+ * merged in place into an existing tool-invocation part — not when it only gained OM markers.
33515
+ * @internal
33516
+ */
33517
+ drainedPartKeys = /* @__PURE__ */ new Map();
33439
33518
  /** Memory context provider — set via start(). Used by steps for beforeBuffer persistence. */
33440
33519
  memory;
33441
33520
  /** Optional stream writer for emitting markers. */
@@ -34029,6 +34108,7 @@ var ReflectorRunner = class {
34029
34108
  * number per active thread/resource key and live for the runner's lifetime.
34030
34109
  */
34031
34110
  syncReflectionSuppression = /* @__PURE__ */ new Map();
34111
+ trackBackgroundWork;
34032
34112
  constructor(opts) {
34033
34113
  this.reflectionConfig = opts.reflectionConfig;
34034
34114
  this.observationConfig = opts.observationConfig;
@@ -34045,6 +34125,7 @@ var ReflectorRunner = class {
34045
34125
  this.memory = opts.memory;
34046
34126
  this.onReflectionCommitted = opts.onReflectionCommitted;
34047
34127
  this.hooks = opts.hooks;
34128
+ this.trackBackgroundWork = opts.trackBackgroundWork;
34048
34129
  }
34049
34130
  __registerMastra(mastra) {
34050
34131
  this.mastra = mastra;
@@ -34302,10 +34383,11 @@ var ReflectorRunner = class {
34302
34383
  if (this.buffering.isAsyncBufferingInProgress(bufferKey)) return;
34303
34384
  BufferingCoordinator.lastBufferedBoundary.set(bufferKey, observationTokens);
34304
34385
  registerOp(record.id, "bufferingReflection");
34305
- this.storage.setBufferingReflectionFlag(record.id, true).catch((err) => {
34386
+ const flagSet = this.storage.setBufferingReflectionFlag(record.id, true).catch((err) => {
34306
34387
  omError("[OM] Failed to set buffering reflection flag", err);
34307
34388
  });
34308
34389
  const asyncOp = (async () => {
34390
+ await flagSet;
34309
34391
  let outcome;
34310
34392
  let reflectionError;
34311
34393
  try {
@@ -34346,12 +34428,13 @@ var ReflectorRunner = class {
34346
34428
  }
34347
34429
  BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
34348
34430
  unregisterOp(record.id, "bufferingReflection");
34349
- this.storage.setBufferingReflectionFlag(record.id, false).catch((err) => {
34431
+ await this.storage.setBufferingReflectionFlag(record.id, false).catch((err) => {
34350
34432
  omError("[OM] Failed to clear buffering reflection flag", err);
34351
34433
  });
34352
34434
  }
34353
34435
  })();
34354
34436
  BufferingCoordinator.asyncBufferingOps.set(bufferKey, asyncOp);
34437
+ this.trackBackgroundWork?.(asyncOp);
34355
34438
  }
34356
34439
  /**
34357
34440
  * Perform async buffered reflection — reflects observations and stores to bufferedReflection.
@@ -35556,7 +35639,8 @@ var ObservationalMemory = class ObservationalMemory {
35556
35639
  mastra: config.mastra,
35557
35640
  memory: this.memory,
35558
35641
  onReflectionCommitted: config.onReflectionCommitted,
35559
- hooks: this.hooks
35642
+ hooks: this.hooks,
35643
+ trackBackgroundWork: (work) => this.trackBackgroundWork(work)
35560
35644
  });
35561
35645
  this.validateBufferConfig();
35562
35646
  if (this.scope === "resource" && !hasWarnedResourceScopeDeprecation) {
@@ -51613,4 +51697,4 @@ const agentBuilderWorkflows = {
51613
51697
  //#endregion
51614
51698
  exports.agentBuilderWorkflows = agentBuilderWorkflows;
51615
51699
 
51616
- //# sourceMappingURL=dist-Bi2UyBDO.cjs.map
51700
+ //# sourceMappingURL=dist-DzR11T7C.cjs.map