@mastra/memory 1.18.0-alpha.3 → 1.18.0-alpha.4

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 (32) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/{chunk-XVVCS6R6.js → chunk-LPMZNXSF.js} +241 -104
  3. package/dist/chunk-LPMZNXSF.js.map +1 -0
  4. package/dist/{chunk-ET2TVAT3.cjs → chunk-NRYX4QWV.cjs} +241 -104
  5. package/dist/chunk-NRYX4QWV.cjs.map +1 -0
  6. package/dist/docs/SKILL.md +2 -1
  7. package/dist/docs/assets/SOURCE_MAP.json +39 -39
  8. package/dist/docs/references/reference-storage-dsql.md +428 -0
  9. package/dist/docs/references/reference-storage-dynamodb.md +1 -1
  10. package/dist/docs/references/reference-storage-libsql.md +1 -1
  11. package/dist/docs/references/reference-storage-postgresql.md +1 -1
  12. package/dist/docs/references/reference-storage-upstash.md +1 -1
  13. package/dist/index.cjs +97 -145
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +88 -136
  17. package/dist/index.js.map +1 -1
  18. package/dist/{observational-memory-2PRVG6BF.js → observational-memory-NL7AQHZV.js} +3 -3
  19. package/dist/{observational-memory-2PRVG6BF.js.map → observational-memory-NL7AQHZV.js.map} +1 -1
  20. package/dist/{observational-memory-UJUAQKJB.cjs → observational-memory-TZ67ZA32.cjs} +26 -26
  21. package/dist/{observational-memory-UJUAQKJB.cjs.map → observational-memory-TZ67ZA32.cjs.map} +1 -1
  22. package/dist/processors/index.cjs +24 -24
  23. package/dist/processors/index.js +1 -1
  24. package/dist/processors/observational-memory/observation-strategies/async-buffer.d.ts.map +1 -1
  25. package/dist/processors/observational-memory/observation-strategies/sync.d.ts.map +1 -1
  26. package/dist/processors/observational-memory/observer-runner.d.ts.map +1 -1
  27. package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -1
  28. package/dist/processors/observational-memory/retry.d.ts +63 -0
  29. package/dist/processors/observational-memory/retry.d.ts.map +1 -0
  30. package/package.json +4 -4
  31. package/dist/chunk-ET2TVAT3.cjs.map +0 -1
  32. package/dist/chunk-XVVCS6R6.js.map +0 -1
@@ -1020,8 +1020,6 @@ var ObservationStrategy = class _ObservationStrategy {
1020
1020
  this.scope = deps.scope;
1021
1021
  this.retrieval = deps.retrieval;
1022
1022
  }
1023
- deps;
1024
- opts;
1025
1023
  storage;
1026
1024
  messageHistory;
1027
1025
  tokenCounter;
@@ -2050,8 +2048,6 @@ var ObservationStep = class {
2050
2048
  this.turn = turn;
2051
2049
  this.stepNumber = stepNumber;
2052
2050
  }
2053
- turn;
2054
- stepNumber;
2055
2051
  _prepared = false;
2056
2052
  _context;
2057
2053
  /** Whether this step has been prepared. */
@@ -3798,6 +3794,135 @@ function optimizeObservationsForContext(observations) {
3798
3794
  optimized = optimized.replace(/\n{3,}/g, "\n\n");
3799
3795
  return optimized.trim();
3800
3796
  }
3797
+
3798
+ // src/processors/observational-memory/retry.ts
3799
+ var RETRY_CONFIG = {
3800
+ /** Maximum number of retry *attempts* (total tries = maxRetries + 1). */
3801
+ maxRetries: 8,
3802
+ /** Initial backoff delay in milliseconds. */
3803
+ initialDelayMs: 1e3,
3804
+ /** Multiplier applied to the delay after each failed attempt. */
3805
+ backoffFactor: 2,
3806
+ /** Cap on per-attempt delay (ms). */
3807
+ maxDelayMs: 12e4,
3808
+ /** Random jitter as a fraction of the computed delay (e.g. 0.2 = ±20%). */
3809
+ jitter: 0.2
3810
+ };
3811
+ var TRANSIENT_MESSAGE_SUBSTRINGS = [
3812
+ "terminated",
3813
+ "fetch failed",
3814
+ "econnreset",
3815
+ "econnrefused",
3816
+ "enotfound",
3817
+ "eai_again",
3818
+ "socket hang up",
3819
+ "network error",
3820
+ "request timed out",
3821
+ "request timeout",
3822
+ "connection reset",
3823
+ "connection closed"
3824
+ ];
3825
+ function isRecord2(value) {
3826
+ return typeof value === "object" && value !== null;
3827
+ }
3828
+ function isAbortError(error) {
3829
+ if (!isRecord2(error)) return false;
3830
+ if (error.name === "AbortError") return true;
3831
+ if (typeof error.code === "string" && error.code === "ABORT_ERR") return true;
3832
+ return false;
3833
+ }
3834
+ function hasTransientMessage(value) {
3835
+ if (!isRecord2(value)) return false;
3836
+ const message = typeof value.message === "string" ? value.message.toLowerCase() : "";
3837
+ if (message && TRANSIENT_MESSAGE_SUBSTRINGS.some((sub) => message.includes(sub))) return true;
3838
+ if (typeof value.code === "string" && value.code.toUpperCase().startsWith("UND_ERR_")) return true;
3839
+ return false;
3840
+ }
3841
+ function hasRetryableHttpStatus(value) {
3842
+ if (!isRecord2(value)) return false;
3843
+ const status = typeof value.statusCode === "number" ? value.statusCode : void 0;
3844
+ if (status === void 0) return false;
3845
+ if (status === 408 || status === 425 || status === 429) return true;
3846
+ if (status >= 500 && status <= 599) return true;
3847
+ return false;
3848
+ }
3849
+ function hasIsRetryableFlag(value) {
3850
+ if (!isRecord2(value)) return false;
3851
+ return value.isRetryable === true;
3852
+ }
3853
+ function isTransientLLMError(error) {
3854
+ if (isAbortError(error)) return false;
3855
+ const visited = /* @__PURE__ */ new WeakSet();
3856
+ function visit(candidate) {
3857
+ if (isRecord2(candidate)) {
3858
+ if (visited.has(candidate)) return false;
3859
+ visited.add(candidate);
3860
+ }
3861
+ if (hasTransientMessage(candidate)) return true;
3862
+ if (hasRetryableHttpStatus(candidate)) return true;
3863
+ if (hasIsRetryableFlag(candidate)) return true;
3864
+ if (isRecord2(candidate)) {
3865
+ if (visit(candidate.cause)) return true;
3866
+ if (visit(candidate.error)) return true;
3867
+ }
3868
+ return false;
3869
+ }
3870
+ return visit(error);
3871
+ }
3872
+ function computeDelay(attempt) {
3873
+ const base = RETRY_CONFIG.initialDelayMs * Math.pow(RETRY_CONFIG.backoffFactor, attempt);
3874
+ const capped = Math.min(base, RETRY_CONFIG.maxDelayMs);
3875
+ const jitterRange = capped * RETRY_CONFIG.jitter;
3876
+ const offset = (Math.random() * 2 - 1) * jitterRange;
3877
+ return Math.max(0, Math.round(capped + offset));
3878
+ }
3879
+ function sleep(ms, abortSignal) {
3880
+ if (ms <= 0) return Promise.resolve();
3881
+ return new Promise((resolve, reject) => {
3882
+ if (abortSignal?.aborted) {
3883
+ reject(new Error("The operation was aborted."));
3884
+ return;
3885
+ }
3886
+ const timer = setTimeout(() => {
3887
+ abortSignal?.removeEventListener("abort", onAbort);
3888
+ resolve();
3889
+ }, ms);
3890
+ const onAbort = () => {
3891
+ clearTimeout(timer);
3892
+ abortSignal?.removeEventListener("abort", onAbort);
3893
+ reject(new Error("The operation was aborted."));
3894
+ };
3895
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
3896
+ });
3897
+ }
3898
+ async function withRetry(fn, opts) {
3899
+ const { label, abortSignal } = opts;
3900
+ let attempt = 0;
3901
+ while (true) {
3902
+ if (abortSignal?.aborted) {
3903
+ throw new Error("The operation was aborted.");
3904
+ }
3905
+ try {
3906
+ return await fn();
3907
+ } catch (error) {
3908
+ if (isAbortError(error) || abortSignal?.aborted) throw error;
3909
+ if (attempt >= RETRY_CONFIG.maxRetries || !isTransientLLMError(error)) {
3910
+ if (attempt > 0) {
3911
+ omDebug(
3912
+ `[OM:retry:${label}] giving up after ${attempt} retry/retries: ${error instanceof Error ? error.message : String(error)}`
3913
+ );
3914
+ }
3915
+ throw error;
3916
+ }
3917
+ const delay = computeDelay(attempt);
3918
+ attempt++;
3919
+ omDebug(
3920
+ `[OM:retry:${label}] transient error on attempt ${attempt}, retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
3921
+ );
3922
+ await sleep(delay, abortSignal);
3923
+ }
3924
+ }
3925
+ }
3801
3926
  var PHASE_CONFIG = {
3802
3927
  observer: {
3803
3928
  name: "om.observer",
@@ -3908,32 +4033,35 @@ var ObserverRunner = class {
3908
4033
  buildObserverHistoryMessage(messagesToObserve)
3909
4034
  ];
3910
4035
  const doGenerate = async () => {
3911
- return withOmTracingSpan({
3912
- phase: "observer",
3913
- model: resolvedModel.model,
3914
- inputTokens,
3915
- requestContext: options?.requestContext,
3916
- observabilityContext: options?.observabilityContext,
3917
- metadata: {
3918
- omPreviousObserverTokens: this.observationConfig.previousObserverTokens,
3919
- omThreadTitleEnabled: this.observationConfig.threadTitle,
3920
- omSkipContinuationHints: options?.skipContinuationHints ?? false,
3921
- omWasTruncated: options?.wasTruncated ?? false,
3922
- ...resolvedModel.selectedThreshold !== void 0 ? { omSelectedThreshold: resolvedModel.selectedThreshold } : {},
3923
- ...resolvedModel.routingStrategy ? { omRoutingStrategy: resolvedModel.routingStrategy } : {},
3924
- ...resolvedModel.routingThresholds ? { omRoutingThresholds: resolvedModel.routingThresholds } : {}
3925
- },
3926
- callback: (childObservabilityContext) => this.withAbortCheck(async () => {
3927
- const streamResult = await agent.stream(observerMessages, {
3928
- modelSettings: { ...this.observationConfig.modelSettings },
3929
- providerOptions: this.observationConfig.providerOptions,
3930
- ...abortSignal ? { abortSignal } : {},
3931
- ...options?.requestContext ? { requestContext: options.requestContext } : {},
3932
- ...childObservabilityContext
3933
- });
3934
- return streamResult.getFullOutput();
3935
- }, abortSignal)
3936
- });
4036
+ return withRetry(
4037
+ () => withOmTracingSpan({
4038
+ phase: "observer",
4039
+ model: resolvedModel.model,
4040
+ inputTokens,
4041
+ requestContext: options?.requestContext,
4042
+ observabilityContext: options?.observabilityContext,
4043
+ metadata: {
4044
+ omPreviousObserverTokens: this.observationConfig.previousObserverTokens,
4045
+ omThreadTitleEnabled: this.observationConfig.threadTitle,
4046
+ omSkipContinuationHints: options?.skipContinuationHints ?? false,
4047
+ omWasTruncated: options?.wasTruncated ?? false,
4048
+ ...resolvedModel.selectedThreshold !== void 0 ? { omSelectedThreshold: resolvedModel.selectedThreshold } : {},
4049
+ ...resolvedModel.routingStrategy ? { omRoutingStrategy: resolvedModel.routingStrategy } : {},
4050
+ ...resolvedModel.routingThresholds ? { omRoutingThresholds: resolvedModel.routingThresholds } : {}
4051
+ },
4052
+ callback: (childObservabilityContext) => this.withAbortCheck(async () => {
4053
+ const streamResult = await agent.stream(observerMessages, {
4054
+ modelSettings: { ...this.observationConfig.modelSettings },
4055
+ providerOptions: this.observationConfig.providerOptions,
4056
+ ...abortSignal ? { abortSignal } : {},
4057
+ ...options?.requestContext ? { requestContext: options.requestContext } : {},
4058
+ ...childObservabilityContext
4059
+ });
4060
+ return streamResult.getFullOutput();
4061
+ }, abortSignal)
4062
+ }),
4063
+ { label: "observer", abortSignal }
4064
+ );
3937
4065
  };
3938
4066
  let result = await doGenerate();
3939
4067
  let parsed = parseObserverOutput(result.text);
@@ -4007,31 +4135,34 @@ var ObserverRunner = class {
4007
4135
  }
4008
4136
  }
4009
4137
  const doGenerate = async () => {
4010
- return withOmTracingSpan({
4011
- phase: "observer-multi-thread",
4012
- model: resolvedModel.model,
4013
- inputTokens,
4014
- requestContext,
4015
- observabilityContext,
4016
- metadata: {
4017
- omThreadCount: threadOrder.length,
4018
- omPreviousObserverTokens: this.observationConfig.previousObserverTokens,
4019
- omThreadTitleEnabled: this.observationConfig.threadTitle,
4020
- ...resolvedModel.selectedThreshold !== void 0 ? { omSelectedThreshold: resolvedModel.selectedThreshold } : {},
4021
- ...resolvedModel.routingStrategy ? { omRoutingStrategy: resolvedModel.routingStrategy } : {},
4022
- ...resolvedModel.routingThresholds ? { omRoutingThresholds: resolvedModel.routingThresholds } : {}
4023
- },
4024
- callback: (childObservabilityContext) => this.withAbortCheck(async () => {
4025
- const streamResult = await agent.stream(observerMessages, {
4026
- modelSettings: { ...this.observationConfig.modelSettings },
4027
- providerOptions: this.observationConfig.providerOptions,
4028
- ...abortSignal ? { abortSignal } : {},
4029
- ...requestContext ? { requestContext } : {},
4030
- ...childObservabilityContext
4031
- });
4032
- return streamResult.getFullOutput();
4033
- }, abortSignal)
4034
- });
4138
+ return withRetry(
4139
+ () => withOmTracingSpan({
4140
+ phase: "observer-multi-thread",
4141
+ model: resolvedModel.model,
4142
+ inputTokens,
4143
+ requestContext,
4144
+ observabilityContext,
4145
+ metadata: {
4146
+ omThreadCount: threadOrder.length,
4147
+ omPreviousObserverTokens: this.observationConfig.previousObserverTokens,
4148
+ omThreadTitleEnabled: this.observationConfig.threadTitle,
4149
+ ...resolvedModel.selectedThreshold !== void 0 ? { omSelectedThreshold: resolvedModel.selectedThreshold } : {},
4150
+ ...resolvedModel.routingStrategy ? { omRoutingStrategy: resolvedModel.routingStrategy } : {},
4151
+ ...resolvedModel.routingThresholds ? { omRoutingThresholds: resolvedModel.routingThresholds } : {}
4152
+ },
4153
+ callback: (childObservabilityContext) => this.withAbortCheck(async () => {
4154
+ const streamResult = await agent.stream(observerMessages, {
4155
+ modelSettings: { ...this.observationConfig.modelSettings },
4156
+ providerOptions: this.observationConfig.providerOptions,
4157
+ ...abortSignal ? { abortSignal } : {},
4158
+ ...requestContext ? { requestContext } : {},
4159
+ ...childObservabilityContext
4160
+ });
4161
+ return streamResult.getFullOutput();
4162
+ }, abortSignal)
4163
+ }),
4164
+ { label: "observer-multi-thread", abortSignal }
4165
+ );
4035
4166
  };
4036
4167
  let result = await doGenerate();
4037
4168
  let parsed = parseMultiThreadObserverOutput(result.text);
@@ -4475,54 +4606,60 @@ var ReflectorRunner = class {
4475
4606
  `[OM:callReflector] ${isRetry ? `retry #${attemptNumber - 1}` : "first attempt"}: level=${currentLevel}, originalTokens=${originalTokens}, targetThreshold=${targetThreshold}, promptLen=${prompt.length}, skipContinuationHints=${skipContinuationHints}`
4476
4607
  );
4477
4608
  let chunkCount = 0;
4478
- const result = await withOmTracingSpan({
4479
- phase: "reflector",
4480
- model: resolvedModel.model,
4481
- inputTokens: originalTokens,
4482
- requestContext,
4483
- observabilityContext,
4484
- metadata: {
4485
- omCompressionLevel: currentLevel,
4486
- omCompressionAttempt: attemptNumber,
4487
- omTargetThreshold: targetThreshold,
4488
- omSkipContinuationHints: skipContinuationHints ?? false,
4489
- ...resolvedModel.selectedThreshold !== void 0 ? { omSelectedThreshold: resolvedModel.selectedThreshold } : {},
4490
- ...resolvedModel.routingStrategy ? { omRoutingStrategy: resolvedModel.routingStrategy } : {},
4491
- ...resolvedModel.routingThresholds ? { omRoutingThresholds: resolvedModel.routingThresholds } : {}
4492
- },
4493
- callback: (childObservabilityContext) => withAbortCheck(async () => {
4494
- const streamResult = await agent.stream(prompt, {
4495
- modelSettings: {
4496
- ...this.reflectionConfig.modelSettings
4497
- },
4498
- providerOptions: this.reflectionConfig.providerOptions,
4499
- ...abortSignal ? { abortSignal } : {},
4500
- ...requestContext ? { requestContext } : {},
4501
- ...childObservabilityContext,
4502
- ...attemptNumber === 1 ? {
4503
- onChunk(chunk) {
4504
- chunkCount++;
4505
- if (chunkCount === 1 || chunkCount % 50 === 0) {
4506
- const preview = chunk.type === "text-delta" ? ` text="${chunk.textDelta?.slice(0, 80)}..."` : chunk.type === "tool-call" ? ` tool=${chunk.toolName}` : "";
4507
- omDebug(`[OM:callReflector] chunk#${chunkCount}: type=${chunk.type}${preview}`);
4508
- }
4509
- },
4510
- onFinish(event) {
4511
- omDebug(
4512
- `[OM:callReflector] onFinish: chunks=${chunkCount}, finishReason=${event.finishReason}, inputTokens=${event.usage?.inputTokens}, outputTokens=${event.usage?.outputTokens}, textLen=${event.text?.length}`
4513
- );
4514
- },
4515
- onAbort(event) {
4516
- omDebug(`[OM:callReflector] onAbort: chunks=${chunkCount}, reason=${event?.reason ?? "unknown"}`);
4609
+ const result = await withRetry(
4610
+ () => withOmTracingSpan({
4611
+ phase: "reflector",
4612
+ model: resolvedModel.model,
4613
+ inputTokens: originalTokens,
4614
+ requestContext,
4615
+ observabilityContext,
4616
+ metadata: {
4617
+ omCompressionLevel: currentLevel,
4618
+ omCompressionAttempt: attemptNumber,
4619
+ omTargetThreshold: targetThreshold,
4620
+ omSkipContinuationHints: skipContinuationHints ?? false,
4621
+ ...resolvedModel.selectedThreshold !== void 0 ? { omSelectedThreshold: resolvedModel.selectedThreshold } : {},
4622
+ ...resolvedModel.routingStrategy ? { omRoutingStrategy: resolvedModel.routingStrategy } : {},
4623
+ ...resolvedModel.routingThresholds ? { omRoutingThresholds: resolvedModel.routingThresholds } : {}
4624
+ },
4625
+ callback: (childObservabilityContext) => withAbortCheck(async () => {
4626
+ chunkCount = 0;
4627
+ const streamResult = await agent.stream(prompt, {
4628
+ modelSettings: {
4629
+ ...this.reflectionConfig.modelSettings
4517
4630
  },
4518
- onError({ error }) {
4519
- omError(`[OM:callReflector] onError after ${chunkCount} chunks`, error);
4520
- }
4521
- } : {}
4522
- });
4523
- return streamResult.getFullOutput();
4524
- }, abortSignal)
4525
- });
4631
+ providerOptions: this.reflectionConfig.providerOptions,
4632
+ ...abortSignal ? { abortSignal } : {},
4633
+ ...requestContext ? { requestContext } : {},
4634
+ ...childObservabilityContext,
4635
+ ...attemptNumber === 1 ? {
4636
+ onChunk(chunk) {
4637
+ chunkCount++;
4638
+ if (chunkCount === 1 || chunkCount % 50 === 0) {
4639
+ const preview = chunk.type === "text-delta" ? ` text="${chunk.textDelta?.slice(0, 80)}..."` : chunk.type === "tool-call" ? ` tool=${chunk.toolName}` : "";
4640
+ omDebug(`[OM:callReflector] chunk#${chunkCount}: type=${chunk.type}${preview}`);
4641
+ }
4642
+ },
4643
+ onFinish(event) {
4644
+ omDebug(
4645
+ `[OM:callReflector] onFinish: chunks=${chunkCount}, finishReason=${event.finishReason}, inputTokens=${event.usage?.inputTokens}, outputTokens=${event.usage?.outputTokens}, textLen=${event.text?.length}`
4646
+ );
4647
+ },
4648
+ onAbort(event) {
4649
+ omDebug(
4650
+ `[OM:callReflector] onAbort: chunks=${chunkCount}, reason=${event?.reason ?? "unknown"}`
4651
+ );
4652
+ },
4653
+ onError({ error }) {
4654
+ omError(`[OM:callReflector] onError after ${chunkCount} chunks`, error);
4655
+ }
4656
+ } : {}
4657
+ });
4658
+ return streamResult.getFullOutput();
4659
+ }, abortSignal)
4660
+ }),
4661
+ { label: "reflector", abortSignal }
4662
+ );
4526
4663
  omDebug(
4527
4664
  `[OM:callReflector] attempt #${attemptNumber} returned: textLen=${result.text?.length}, textPreview="${result.text?.slice(0, 120)}...", inputTokens=${result.usage?.inputTokens ?? result.totalUsage?.inputTokens}, outputTokens=${result.usage?.outputTokens ?? result.totalUsage?.outputTokens}`
4528
4665
  );
@@ -9528,5 +9665,5 @@ exports.stripEphemeralAnchorIds = stripEphemeralAnchorIds;
9528
9665
  exports.stripObservationGroups = stripObservationGroups;
9529
9666
  exports.truncateStringByTokens = truncateStringByTokens;
9530
9667
  exports.wrapInObservationGroup = wrapInObservationGroup;
9531
- //# sourceMappingURL=chunk-ET2TVAT3.cjs.map
9532
- //# sourceMappingURL=chunk-ET2TVAT3.cjs.map
9668
+ //# sourceMappingURL=chunk-NRYX4QWV.cjs.map
9669
+ //# sourceMappingURL=chunk-NRYX4QWV.cjs.map