@mastra/memory 1.28.3 → 1.29.0-alpha.1
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.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-message-history.md +1 -1
- package/dist/docs/references/docs-memory-multi-user-threads.md +1 -1
- package/dist/docs/references/docs-memory-observational-memory.md +41 -1
- package/dist/docs/references/docs-memory-overview.md +4 -4
- package/dist/docs/references/reference-memory-observational-memory.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/processors/index.cjs +1 -1
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/error.d.ts +3 -0
- package/dist/processors/observational-memory/error.d.ts.map +1 -0
- package/dist/processors/observational-memory/index.d.ts +1 -1
- package/dist/processors/observational-memory/index.d.ts.map +1 -1
- package/dist/processors/observational-memory/markers.d.ts +2 -2
- package/dist/processors/observational-memory/markers.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/async-buffer.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/base.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/sync.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/types.d.ts +3 -1
- package/dist/processors/observational-memory/observation-strategies/types.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -1
- package/dist/processors/observational-memory/observational-memory.d.ts +3 -3
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/observer-runner.d.ts +60 -46
- package/dist/processors/observational-memory/observer-runner.d.ts.map +1 -1
- package/dist/processors/observational-memory/processor.d.ts.map +1 -1
- package/dist/processors/observational-memory/reflector-runner.d.ts +5 -1
- package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -1
- package/dist/processors/observational-memory/transform-hooks.d.ts +15 -0
- package/dist/processors/observational-memory/transform-hooks.d.ts.map +1 -0
- package/dist/processors/observational-memory/types.d.ts +71 -2
- package/dist/processors/observational-memory/types.d.ts.map +1 -1
- package/dist/{src-BFP4tRqs.js → src-BNB8ko_o.js} +193 -45
- package/dist/src-BNB8ko_o.js.map +1 -0
- package/dist/{src-D4Wm6M4v.cjs → src-DjCR8GJe.cjs} +193 -45
- package/dist/src-DjCR8GJe.cjs.map +1 -0
- package/package.json +4 -4
- package/dist/src-BFP4tRqs.js.map +0 -1
- package/dist/src-D4Wm6M4v.cjs.map +0 -1
|
@@ -18914,11 +18914,11 @@ function formatObserverAttachmentPlaceholder(part, counter) {
|
|
|
18914
18914
|
const label = resolveObserverAttachmentLabel(part);
|
|
18915
18915
|
return label ? `[${attachmentType} #${attachmentId}: ${label}]` : `[${attachmentType} #${attachmentId}]`;
|
|
18916
18916
|
}
|
|
18917
|
-
function isRecord$
|
|
18917
|
+
function isRecord$4(value) {
|
|
18918
18918
|
return !!value && typeof value === "object";
|
|
18919
18919
|
}
|
|
18920
18920
|
function mapToolResultBlockToAttachment(block) {
|
|
18921
|
-
if (!isRecord$
|
|
18921
|
+
if (!isRecord$4(block) || typeof block.type !== "string") return;
|
|
18922
18922
|
const mediaType = typeof block.mediaType === "string" ? block.mediaType : void 0;
|
|
18923
18923
|
const filename = typeof block.filename === "string" ? block.filename : void 0;
|
|
18924
18924
|
switch (block.type) {
|
|
@@ -18979,7 +18979,7 @@ function mapToolResultBlockToAttachment(block) {
|
|
|
18979
18979
|
}
|
|
18980
18980
|
}
|
|
18981
18981
|
function extractToolResultAttachments(result, counter, attachmentFilter) {
|
|
18982
|
-
if (!isRecord$
|
|
18982
|
+
if (!isRecord$4(result) || result.type !== "content" || !Array.isArray(result.value)) return {
|
|
18983
18983
|
resultWithoutAttachments: result,
|
|
18984
18984
|
attachments: []
|
|
18985
18985
|
};
|
|
@@ -18993,7 +18993,7 @@ function extractToolResultAttachments(result, counter, attachmentFilter) {
|
|
|
18993
18993
|
if (shouldIncludeObserverAttachment(attachment, attachmentFilter)) attachments.push(toObserverInputAttachmentPart(attachment));
|
|
18994
18994
|
const placeholder = formatObserverAttachmentPlaceholder(attachment, counter);
|
|
18995
18995
|
return {
|
|
18996
|
-
type: isRecord$
|
|
18996
|
+
type: isRecord$4(block) ? block.type : void 0,
|
|
18997
18997
|
placeholder
|
|
18998
18998
|
};
|
|
18999
18999
|
});
|
|
@@ -19614,17 +19614,17 @@ const TRANSIENT_MESSAGE_SUBSTRINGS = [
|
|
|
19614
19614
|
"connection reset",
|
|
19615
19615
|
"connection closed"
|
|
19616
19616
|
];
|
|
19617
|
-
function isRecord$
|
|
19617
|
+
function isRecord$3(value) {
|
|
19618
19618
|
return typeof value === "object" && value !== null;
|
|
19619
19619
|
}
|
|
19620
19620
|
function isAbortError(error) {
|
|
19621
|
-
if (!isRecord$
|
|
19621
|
+
if (!isRecord$3(error)) return false;
|
|
19622
19622
|
if (error.name === "AbortError") return true;
|
|
19623
19623
|
if (typeof error.code === "string" && error.code === "ABORT_ERR") return true;
|
|
19624
19624
|
return false;
|
|
19625
19625
|
}
|
|
19626
19626
|
function hasTransientMessage(value) {
|
|
19627
|
-
if (!isRecord$
|
|
19627
|
+
if (!isRecord$3(value)) return false;
|
|
19628
19628
|
const message = typeof value.message === "string" ? value.message.toLowerCase() : "";
|
|
19629
19629
|
if (message && TRANSIENT_MESSAGE_SUBSTRINGS.some((sub) => message.includes(sub))) return true;
|
|
19630
19630
|
if (typeof value.code === "string" && value.code.toUpperCase().startsWith("UND_ERR_")) return true;
|
|
@@ -19635,13 +19635,13 @@ function isRetryableHttpStatus(status) {
|
|
|
19635
19635
|
return status >= 500 && status <= 599;
|
|
19636
19636
|
}
|
|
19637
19637
|
function hasRetryableHttpStatus(value) {
|
|
19638
|
-
if (!isRecord$
|
|
19638
|
+
if (!isRecord$3(value)) return false;
|
|
19639
19639
|
if (typeof value.statusCode === "number" && isRetryableHttpStatus(value.statusCode)) return true;
|
|
19640
19640
|
if (typeof value.code === "number" && isRetryableHttpStatus(value.code)) return true;
|
|
19641
19641
|
return false;
|
|
19642
19642
|
}
|
|
19643
19643
|
function hasIsRetryableFlag(value) {
|
|
19644
|
-
if (!isRecord$
|
|
19644
|
+
if (!isRecord$3(value)) return false;
|
|
19645
19645
|
return value.isRetryable === true;
|
|
19646
19646
|
}
|
|
19647
19647
|
/**
|
|
@@ -19659,14 +19659,14 @@ function isTransientLLMError(error) {
|
|
|
19659
19659
|
if (isAbortError(error)) return false;
|
|
19660
19660
|
const visited = /* @__PURE__ */ new WeakSet();
|
|
19661
19661
|
function visit(candidate) {
|
|
19662
|
-
if (isRecord$
|
|
19662
|
+
if (isRecord$3(candidate)) {
|
|
19663
19663
|
if (visited.has(candidate)) return false;
|
|
19664
19664
|
visited.add(candidate);
|
|
19665
19665
|
}
|
|
19666
19666
|
if (hasTransientMessage(candidate)) return true;
|
|
19667
19667
|
if (hasRetryableHttpStatus(candidate)) return true;
|
|
19668
19668
|
if (hasIsRetryableFlag(candidate)) return true;
|
|
19669
|
-
if (isRecord$
|
|
19669
|
+
if (isRecord$3(candidate)) {
|
|
19670
19670
|
if (visit(candidate.cause)) return true;
|
|
19671
19671
|
if (visit(candidate.error)) return true;
|
|
19672
19672
|
}
|
|
@@ -19811,6 +19811,37 @@ async function withOmTracingSpan({ phase, model, inputTokens, requestContext, ob
|
|
|
19811
19811
|
});
|
|
19812
19812
|
}
|
|
19813
19813
|
//#endregion
|
|
19814
|
+
//#region src/processors/observational-memory/transform-hooks.ts
|
|
19815
|
+
/**
|
|
19816
|
+
* Run the `beforeObservation` transform hook. Returns the (possibly replaced)
|
|
19817
|
+
* message array; `undefined` from the hook means passthrough.
|
|
19818
|
+
*/
|
|
19819
|
+
async function applyBeforeObservation(hooks, messages, context) {
|
|
19820
|
+
if (!hooks?.beforeObservation) return messages;
|
|
19821
|
+
const result = await hooks.beforeObservation({
|
|
19822
|
+
...context,
|
|
19823
|
+
messages
|
|
19824
|
+
});
|
|
19825
|
+
if (!result) return messages;
|
|
19826
|
+
omDebug(`[OM:hooks] beforeObservation replaced messages: ${messages.length} -> ${result.messages.length}`);
|
|
19827
|
+
return result.messages;
|
|
19828
|
+
}
|
|
19829
|
+
/**
|
|
19830
|
+
* Run one of the text transform hooks. Returns the (possibly replaced)
|
|
19831
|
+
* observation text; `undefined` from the hook means passthrough.
|
|
19832
|
+
*/
|
|
19833
|
+
async function applyTextTransform(hooks, name, observations, context) {
|
|
19834
|
+
const hook = hooks?.[name];
|
|
19835
|
+
if (!hook) return observations;
|
|
19836
|
+
const result = await hook({
|
|
19837
|
+
...context,
|
|
19838
|
+
observations
|
|
19839
|
+
});
|
|
19840
|
+
if (!result) return observations;
|
|
19841
|
+
omDebug(`[OM:hooks] ${name} replaced observations: ${observations.length} -> ${result.observations.length} chars`);
|
|
19842
|
+
return result.observations;
|
|
19843
|
+
}
|
|
19844
|
+
//#endregion
|
|
19814
19845
|
//#region src/processors/observational-memory/observer-runner.ts
|
|
19815
19846
|
function filterObserverExtractors(extractors, skipContinuationHints) {
|
|
19816
19847
|
const configuredExtractors = extractors ?? [];
|
|
@@ -19823,6 +19854,7 @@ var ObserverRunner = class {
|
|
|
19823
19854
|
resolveModel;
|
|
19824
19855
|
tokenCounter;
|
|
19825
19856
|
memory;
|
|
19857
|
+
hooks;
|
|
19826
19858
|
mastra;
|
|
19827
19859
|
/** Captured prompt/response from the last observer call (for repro capture). */
|
|
19828
19860
|
lastExchange;
|
|
@@ -19833,6 +19865,7 @@ var ObserverRunner = class {
|
|
|
19833
19865
|
this.tokenCounter = opts.tokenCounter;
|
|
19834
19866
|
this.mastra = opts.mastra;
|
|
19835
19867
|
this.memory = opts.memory;
|
|
19868
|
+
this.hooks = opts.hooks;
|
|
19836
19869
|
}
|
|
19837
19870
|
__registerMastra(mastra) {
|
|
19838
19871
|
this.mastra = mastra;
|
|
@@ -19886,9 +19919,25 @@ var ObserverRunner = class {
|
|
|
19886
19919
|
return result;
|
|
19887
19920
|
}
|
|
19888
19921
|
/**
|
|
19889
|
-
* Call the Observer agent for a single thread
|
|
19922
|
+
* Call the Observer agent for a single thread, running the config-level
|
|
19923
|
+
* `beforeObservation` / `afterObservation` transform hooks around it.
|
|
19890
19924
|
*/
|
|
19891
19925
|
async call(existingObservations, messagesToObserve, abortSignal, options) {
|
|
19926
|
+
const context = {
|
|
19927
|
+
threadId: options?.threadId ?? messagesToObserve[0]?.threadId,
|
|
19928
|
+
resourceId: options?.resourceId,
|
|
19929
|
+
trigger: options?.trigger
|
|
19930
|
+
};
|
|
19931
|
+
const messages = await applyBeforeObservation(this.hooks, messagesToObserve, context);
|
|
19932
|
+
if (messages.length === 0) {
|
|
19933
|
+
omDebug("[OM:callObserver] beforeObservation returned no messages, skipping observer call");
|
|
19934
|
+
return { observations: "" };
|
|
19935
|
+
}
|
|
19936
|
+
const result = await this.callObserver(existingObservations, messages, abortSignal, options);
|
|
19937
|
+
result.observations = await applyTextTransform(this.hooks, "afterObservation", result.observations, context);
|
|
19938
|
+
return result;
|
|
19939
|
+
}
|
|
19940
|
+
async callObserver(existingObservations, messagesToObserve, abortSignal, options) {
|
|
19892
19941
|
const inputTokens = this.tokenCounter.countMessages(messagesToObserve);
|
|
19893
19942
|
const resolvedModel = options?.model ? { model: options.model } : this.resolveModel(inputTokens);
|
|
19894
19943
|
const activeExtractors = await resolveExtractors(filterObserverExtractors(this.observationConfig.extractors, options?.skipContinuationHints), {
|
|
@@ -20007,7 +20056,30 @@ var ObserverRunner = class {
|
|
|
20007
20056
|
/**
|
|
20008
20057
|
* Call the Observer agent for multiple threads in a single batched request.
|
|
20009
20058
|
*/
|
|
20010
|
-
async callMultiThread(existingObservations,
|
|
20059
|
+
async callMultiThread(existingObservations, allMessagesByThread, allThreadOrder, abortSignal, requestContext, priorMetadataByThread, observabilityContext, model, hookContext) {
|
|
20060
|
+
const contextFor = (threadId) => ({
|
|
20061
|
+
threadId,
|
|
20062
|
+
...hookContext
|
|
20063
|
+
});
|
|
20064
|
+
const messagesByThread = /* @__PURE__ */ new Map();
|
|
20065
|
+
for (const threadId of allThreadOrder) {
|
|
20066
|
+
const filtered = await applyBeforeObservation(this.hooks, allMessagesByThread.get(threadId) ?? [], contextFor(threadId));
|
|
20067
|
+
if (filtered.length > 0) messagesByThread.set(threadId, filtered);
|
|
20068
|
+
}
|
|
20069
|
+
const threadOrder = allThreadOrder.filter((threadId) => messagesByThread.has(threadId));
|
|
20070
|
+
const output = await this.callMultiThreadObserver(existingObservations, messagesByThread, threadOrder, abortSignal, requestContext, priorMetadataByThread, observabilityContext, model);
|
|
20071
|
+
for (const threadId of allThreadOrder) {
|
|
20072
|
+
const threadResult = output.results.get(threadId);
|
|
20073
|
+
if (!threadResult) {
|
|
20074
|
+
output.results.set(threadId, { observations: "" });
|
|
20075
|
+
continue;
|
|
20076
|
+
}
|
|
20077
|
+
threadResult.observations = await applyTextTransform(this.hooks, "afterObservation", threadResult.observations, contextFor(threadId));
|
|
20078
|
+
}
|
|
20079
|
+
return output;
|
|
20080
|
+
}
|
|
20081
|
+
async callMultiThreadObserver(existingObservations, messagesByThread, threadOrder, abortSignal, requestContext, priorMetadataByThread, observabilityContext, model) {
|
|
20082
|
+
if (threadOrder.length === 0) return { results: /* @__PURE__ */ new Map() };
|
|
20011
20083
|
const inputTokens = Array.from(messagesByThread.values()).reduce((total, messages) => total + this.tokenCounter.countMessages(messages), 0);
|
|
20012
20084
|
const resolvedModel = model ? { model } : this.resolveModel(inputTokens);
|
|
20013
20085
|
const firstThreadMessages = messagesByThread.get(threadOrder[0] ?? "") ?? [];
|
|
@@ -20026,7 +20098,7 @@ var ObserverRunner = class {
|
|
|
20026
20098
|
totalTokens: 0
|
|
20027
20099
|
};
|
|
20028
20100
|
for (const threadId of threadOrder) {
|
|
20029
|
-
const threadResult = await this.
|
|
20101
|
+
const threadResult = await this.callObserver(existingObservations, messagesByThread.get(threadId) ?? [], abortSignal, {
|
|
20030
20102
|
requestContext,
|
|
20031
20103
|
observabilityContext,
|
|
20032
20104
|
priorCurrentTask: priorMetadataByThread?.get(threadId)?.currentTask,
|
|
@@ -23359,6 +23431,45 @@ function didProviderChange(actorModel, lastModel) {
|
|
|
23359
23431
|
return false;
|
|
23360
23432
|
}
|
|
23361
23433
|
//#endregion
|
|
23434
|
+
//#region src/processors/observational-memory/error.ts
|
|
23435
|
+
function isRecord$2(value) {
|
|
23436
|
+
return typeof value === "object" && value !== null;
|
|
23437
|
+
}
|
|
23438
|
+
/** Keep provider diagnostics in streamed/persisted markers, not whole API request/response objects. */
|
|
23439
|
+
function formatOmError(error) {
|
|
23440
|
+
const details = /* @__PURE__ */ new Set();
|
|
23441
|
+
const visited = /* @__PURE__ */ new Set();
|
|
23442
|
+
const add = (value) => {
|
|
23443
|
+
if (typeof value === "string" && value.trim()) details.add(value.trim().slice(0, 2e3));
|
|
23444
|
+
};
|
|
23445
|
+
function collectErrorDetails(value, depth) {
|
|
23446
|
+
if (depth > 5) return;
|
|
23447
|
+
if (!isRecord$2(value)) {
|
|
23448
|
+
if (value !== void 0) add(String(value));
|
|
23449
|
+
return;
|
|
23450
|
+
}
|
|
23451
|
+
if (visited.has(value)) return;
|
|
23452
|
+
visited.add(value);
|
|
23453
|
+
add(value.message);
|
|
23454
|
+
if (typeof value.statusCode === "number") add(`HTTP ${value.statusCode}`);
|
|
23455
|
+
if (typeof value.responseBody === "string") try {
|
|
23456
|
+
const body = JSON.parse(value.responseBody);
|
|
23457
|
+
if (isRecord$2(body)) {
|
|
23458
|
+
add(body.message);
|
|
23459
|
+
if (isRecord$2(body.error)) add(body.error.message);
|
|
23460
|
+
else add(body.error);
|
|
23461
|
+
}
|
|
23462
|
+
} catch {}
|
|
23463
|
+
if (value.cause !== void 0) collectErrorDetails(value.cause, depth + 1);
|
|
23464
|
+
if (value.error !== void 0) collectErrorDetails(value.error, depth + 1);
|
|
23465
|
+
}
|
|
23466
|
+
try {
|
|
23467
|
+
collectErrorDetails(error, 0);
|
|
23468
|
+
} catch {}
|
|
23469
|
+
const message = [...details].join(": ") || "Unknown error";
|
|
23470
|
+
return message.length > 2e3 ? `${message.slice(0, 1997)}...` : message;
|
|
23471
|
+
}
|
|
23472
|
+
//#endregion
|
|
23362
23473
|
//#region src/processors/observational-memory/markers.ts
|
|
23363
23474
|
/**
|
|
23364
23475
|
* Create a start marker for when observation begins.
|
|
@@ -23417,7 +23528,7 @@ function createObservationFailedMarker(params) {
|
|
|
23417
23528
|
failedAt,
|
|
23418
23529
|
durationMs,
|
|
23419
23530
|
tokensAttempted: params.tokensAttempted,
|
|
23420
|
-
error: params.error,
|
|
23531
|
+
error: formatOmError(params.error),
|
|
23421
23532
|
recordId: params.recordId,
|
|
23422
23533
|
threadId: params.threadId
|
|
23423
23534
|
}
|
|
@@ -23478,7 +23589,7 @@ function createBufferingFailedMarker(params) {
|
|
|
23478
23589
|
failedAt,
|
|
23479
23590
|
durationMs,
|
|
23480
23591
|
tokensAttempted: params.tokensAttempted,
|
|
23481
|
-
error: params.error,
|
|
23592
|
+
error: formatOmError(params.error),
|
|
23482
23593
|
recordId: params.recordId,
|
|
23483
23594
|
threadId: params.threadId
|
|
23484
23595
|
}
|
|
@@ -24083,6 +24194,7 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
24083
24194
|
sendSignal: this.opts.sendSignal,
|
|
24084
24195
|
sendStateSignal: this.opts.sendStateSignal,
|
|
24085
24196
|
reflectionHooks,
|
|
24197
|
+
trigger: this.opts.trigger,
|
|
24086
24198
|
requestContext,
|
|
24087
24199
|
observabilityContext: this.opts.observabilityContext
|
|
24088
24200
|
});
|
|
@@ -24100,7 +24212,7 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
24100
24212
|
cycleId,
|
|
24101
24213
|
operationType: "observation",
|
|
24102
24214
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24103
|
-
error:
|
|
24215
|
+
error: formatOmError(error),
|
|
24104
24216
|
recordId: record.id,
|
|
24105
24217
|
threadId
|
|
24106
24218
|
}
|
|
@@ -24363,7 +24475,9 @@ var SyncObservationStrategy = class extends ObservationStrategy {
|
|
|
24363
24475
|
priorSuggestedResponse: omMeta?.suggestedResponse,
|
|
24364
24476
|
priorThreadTitle: omMeta?.threadTitle,
|
|
24365
24477
|
priorExtractedValues: this.priorExtractedValues,
|
|
24478
|
+
threadId: this.opts.threadId,
|
|
24366
24479
|
resourceId: this.opts.resourceId,
|
|
24480
|
+
trigger: this.opts.trigger,
|
|
24367
24481
|
mainAgent: this.opts.agent
|
|
24368
24482
|
});
|
|
24369
24483
|
const hookedValues = await applyExtractorHooks({
|
|
@@ -24499,7 +24613,7 @@ var SyncObservationStrategy = class extends ObservationStrategy {
|
|
|
24499
24613
|
operationType: "observation",
|
|
24500
24614
|
startedAt: this.startedAt,
|
|
24501
24615
|
tokensAttempted: this.tokensToObserve,
|
|
24502
|
-
error
|
|
24616
|
+
error,
|
|
24503
24617
|
recordId: this.opts.record.id,
|
|
24504
24618
|
threadId: this.opts.threadId
|
|
24505
24619
|
});
|
|
@@ -24548,7 +24662,9 @@ var AsyncBufferObservationStrategy = class extends ObservationStrategy {
|
|
|
24548
24662
|
requestContext: this.opts.requestContext,
|
|
24549
24663
|
observabilityContext: this.opts.observabilityContext,
|
|
24550
24664
|
priorExtractedValues: this.priorExtractedValues,
|
|
24665
|
+
threadId: this.opts.threadId,
|
|
24551
24666
|
resourceId: this.opts.resourceId,
|
|
24667
|
+
trigger: this.opts.trigger,
|
|
24552
24668
|
mainAgent: this.opts.agent
|
|
24553
24669
|
});
|
|
24554
24670
|
const hookedValues = await applyExtractorHooks({
|
|
@@ -24698,7 +24814,7 @@ var AsyncBufferObservationStrategy = class extends ObservationStrategy {
|
|
|
24698
24814
|
operationType: "observation",
|
|
24699
24815
|
startedAt: this.startedAt,
|
|
24700
24816
|
tokensAttempted,
|
|
24701
|
-
error
|
|
24817
|
+
error,
|
|
24702
24818
|
recordId: record.id,
|
|
24703
24819
|
threadId
|
|
24704
24820
|
});
|
|
@@ -24872,7 +24988,10 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
|
|
|
24872
24988
|
}
|
|
24873
24989
|
if (currentBatch.threadIds.length > 0) batches.push(currentBatch);
|
|
24874
24990
|
const batchResults = await Promise.all(batches.map(async (batch) => {
|
|
24875
|
-
return this.deps.observer.callMultiThread(_existingObservations, batch.threadMap, batch.threadIds, this.opts.abortSignal, this.opts.requestContext, this.priorMetadataByThread, this.opts.observabilityContext
|
|
24991
|
+
return this.deps.observer.callMultiThread(_existingObservations, batch.threadMap, batch.threadIds, this.opts.abortSignal, this.opts.requestContext, this.priorMetadataByThread, this.opts.observabilityContext, void 0, {
|
|
24992
|
+
resourceId: this.opts.resourceId,
|
|
24993
|
+
trigger: this.opts.trigger
|
|
24994
|
+
});
|
|
24876
24995
|
}));
|
|
24877
24996
|
for (const batchResult of batchResults) {
|
|
24878
24997
|
for (const [threadId, result] of batchResult.results) this.multiThreadResults.set(threadId, result);
|
|
@@ -25063,7 +25182,7 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
|
|
|
25063
25182
|
operationType: "observation",
|
|
25064
25183
|
startedAt: this.startedAt,
|
|
25065
25184
|
tokensAttempted,
|
|
25066
|
-
error
|
|
25185
|
+
error,
|
|
25067
25186
|
recordId: this.opts.record.id,
|
|
25068
25187
|
threadId
|
|
25069
25188
|
});
|
|
@@ -25210,7 +25329,8 @@ var ObservationStep = class {
|
|
|
25210
25329
|
threadId,
|
|
25211
25330
|
resourceId,
|
|
25212
25331
|
trigger: "turn-sync"
|
|
25213
|
-
})
|
|
25332
|
+
}),
|
|
25333
|
+
trigger: "turn-sync"
|
|
25214
25334
|
});
|
|
25215
25335
|
await this.turn.refreshRecord();
|
|
25216
25336
|
if (this.turn.record.generationCount > preReflectGeneration) reflected = true;
|
|
@@ -25413,7 +25533,8 @@ var ObservationStep = class {
|
|
|
25413
25533
|
threadId,
|
|
25414
25534
|
resourceId,
|
|
25415
25535
|
trigger: "turn-sync"
|
|
25416
|
-
})
|
|
25536
|
+
}),
|
|
25537
|
+
trigger: "turn-sync"
|
|
25417
25538
|
});
|
|
25418
25539
|
return {
|
|
25419
25540
|
succeeded: true,
|
|
@@ -26050,6 +26171,7 @@ var ReflectorRunner = class {
|
|
|
26050
26171
|
getCompressionStartLevel;
|
|
26051
26172
|
memory;
|
|
26052
26173
|
onReflectionCommitted;
|
|
26174
|
+
hooks;
|
|
26053
26175
|
mastra;
|
|
26054
26176
|
/**
|
|
26055
26177
|
* Per-lock-key observation-token count of the last unproductive synchronous
|
|
@@ -26081,6 +26203,7 @@ var ReflectorRunner = class {
|
|
|
26081
26203
|
this.mastra = opts.mastra;
|
|
26082
26204
|
this.memory = opts.memory;
|
|
26083
26205
|
this.onReflectionCommitted = opts.onReflectionCommitted;
|
|
26206
|
+
this.hooks = opts.hooks;
|
|
26084
26207
|
}
|
|
26085
26208
|
__registerMastra(mastra) {
|
|
26086
26209
|
this.mastra = mastra;
|
|
@@ -26303,7 +26426,7 @@ var ReflectorRunner = class {
|
|
|
26303
26426
|
/**
|
|
26304
26427
|
* Start an async buffered reflection in the background.
|
|
26305
26428
|
*/
|
|
26306
|
-
startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext, observabilityContext, reflectionHooks, priorExtractedValues, mainAgent, sendSignal) {
|
|
26429
|
+
startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext, observabilityContext, reflectionHooks, priorExtractedValues, mainAgent, sendSignal, trigger) {
|
|
26307
26430
|
const bufferKey = this.buffering.getReflectionBufferKey(lockKey);
|
|
26308
26431
|
if (this.buffering.isAsyncBufferingInProgress(bufferKey)) return;
|
|
26309
26432
|
BufferingCoordinator.lastBufferedBoundary.set(bufferKey, observationTokens);
|
|
@@ -26316,7 +26439,7 @@ var ReflectorRunner = class {
|
|
|
26316
26439
|
let reflectionError;
|
|
26317
26440
|
try {
|
|
26318
26441
|
await reflectionHooks?.onReflectionStart?.();
|
|
26319
|
-
outcome = await this.doAsyncBufferedReflection(record, bufferKey, writer, requestContext, observabilityContext, priorExtractedValues, mainAgent, sendSignal);
|
|
26442
|
+
outcome = await this.doAsyncBufferedReflection(record, bufferKey, writer, requestContext, observabilityContext, priorExtractedValues, mainAgent, sendSignal, trigger);
|
|
26320
26443
|
} catch (error) {
|
|
26321
26444
|
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
26322
26445
|
if (writer) try {
|
|
@@ -26325,7 +26448,7 @@ var ReflectorRunner = class {
|
|
|
26325
26448
|
operationType: "reflection",
|
|
26326
26449
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26327
26450
|
tokensAttempted: observationTokens,
|
|
26328
|
-
error
|
|
26451
|
+
error,
|
|
26329
26452
|
recordId: record.id,
|
|
26330
26453
|
threadId: record.threadId ?? ""
|
|
26331
26454
|
});
|
|
@@ -26362,7 +26485,7 @@ var ReflectorRunner = class {
|
|
|
26362
26485
|
* Perform async buffered reflection — reflects observations and stores to bufferedReflection.
|
|
26363
26486
|
* Does NOT create a new generation or update activeObservations.
|
|
26364
26487
|
*/
|
|
26365
|
-
async doAsyncBufferedReflection(record, _bufferKey, writer, requestContext, observabilityContext, priorExtractedValues, mainAgent, sendSignal) {
|
|
26488
|
+
async doAsyncBufferedReflection(record, _bufferKey, writer, requestContext, observabilityContext, priorExtractedValues, mainAgent, sendSignal, trigger) {
|
|
26366
26489
|
const currentRecord = await this.storage.getObservationalMemory(record.threadId, record.resourceId) ?? record;
|
|
26367
26490
|
const observationTokens = currentRecord.observationTokenCount ?? 0;
|
|
26368
26491
|
const reflectThreshold = getMaxThreshold(this.getEffectiveReflectionTokens(currentRecord));
|
|
@@ -26375,7 +26498,12 @@ var ReflectorRunner = class {
|
|
|
26375
26498
|
const avgTokensPerLine = totalLines > 0 ? observationTokens / totalLines : 0;
|
|
26376
26499
|
const activationPointTokens = reflectThreshold * bufferActivation;
|
|
26377
26500
|
const linesToReflect = avgTokensPerLine > 0 ? Math.min(Math.floor(activationPointTokens / avgTokensPerLine), totalLines) : totalLines;
|
|
26378
|
-
const
|
|
26501
|
+
const hookContext = {
|
|
26502
|
+
threadId: currentRecord.threadId ?? void 0,
|
|
26503
|
+
resourceId: currentRecord.resourceId ?? void 0,
|
|
26504
|
+
trigger
|
|
26505
|
+
};
|
|
26506
|
+
const activeObservations = await applyTextTransform(this.hooks, "beforeReflection", allLines.slice(0, linesToReflect).join("\n"), hookContext);
|
|
26379
26507
|
const reflectedObservationLineCount = linesToReflect;
|
|
26380
26508
|
const sliceTokenEstimate = Math.round(avgTokensPerLine * linesToReflect);
|
|
26381
26509
|
const compressionTarget = Math.round(sliceTokenEstimate * .75);
|
|
@@ -26399,6 +26527,7 @@ var ReflectorRunner = class {
|
|
|
26399
26527
|
}
|
|
26400
26528
|
const compressionStartLevel = await this.getCompressionStartLevel(requestContext);
|
|
26401
26529
|
const reflectResult = await this.call(activeObservations, void 0, void 0, compressionTarget, void 0, true, compressionStartLevel, requestContext, priorExtractedValues, observabilityContext, void 0, mainAgent, sendSignal);
|
|
26530
|
+
reflectResult.observations = await applyTextTransform(this.hooks, "afterReflection", reflectResult.observations, hookContext);
|
|
26402
26531
|
await persistThreadExtractedValues(this.storage, this.reflectionConfig.extractors, currentRecord.threadId ?? void 0, reflectResult.extractedValues);
|
|
26403
26532
|
const reflectionTokenCount = this.tokenCounter.countObservations(reflectResult.observations);
|
|
26404
26533
|
omDebug(`[OM:reflect] doAsyncBufferedReflection: reflector returned ${reflectionTokenCount} tokens (${reflectResult.observations?.length} chars), saving to recordId=${currentRecord.id}`);
|
|
@@ -26545,7 +26674,7 @@ var ReflectorRunner = class {
|
|
|
26545
26674
|
* @internal Used by observation strategies. Do not call directly.
|
|
26546
26675
|
*/
|
|
26547
26676
|
async maybeReflect(opts) {
|
|
26548
|
-
const { record, observationTokens, writer, abortSignal, mainAgent, sendSignal, sendStateSignal, messageList, currentModel, reflectionHooks, requestContext, observabilityContext, lastActivityAt, threadId: requestedThreadId } = opts;
|
|
26677
|
+
const { record, observationTokens, writer, abortSignal, mainAgent, sendSignal, sendStateSignal, messageList, currentModel, reflectionHooks, trigger, requestContext, observabilityContext, lastActivityAt, threadId: requestedThreadId } = opts;
|
|
26549
26678
|
const lockKey = this.buffering.getLockKey(record.threadId, record.resourceId);
|
|
26550
26679
|
const reflectThreshold = getMaxThreshold(this.getEffectiveReflectionTokens(record));
|
|
26551
26680
|
const priorExtractedValues = await getThreadExtractedValues(this.storage, this.reflectionConfig.extractors, requestedThreadId ?? record.threadId);
|
|
@@ -26563,7 +26692,7 @@ var ReflectorRunner = class {
|
|
|
26563
26692
|
if (record.bufferedReflection) return false;
|
|
26564
26693
|
const activationPoint = reflectThreshold * this.reflectionConfig.bufferActivation;
|
|
26565
26694
|
return observationTokens >= activationPoint;
|
|
26566
|
-
})()) this.startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext, observabilityContext, reflectionHooks, priorExtractedValues, mainAgent, sendSignal);
|
|
26695
|
+
})()) this.startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext, observabilityContext, reflectionHooks, priorExtractedValues, mainAgent, sendSignal, trigger);
|
|
26567
26696
|
}
|
|
26568
26697
|
const activateAfterIdle = resolveActivationTTL(this.reflectionConfig.activateAfterIdle, currentModel);
|
|
26569
26698
|
const ttlExpiredMs = activateAfterIdle !== void 0 && lastActivityAt !== void 0 ? Date.now() - lastActivityAt : void 0;
|
|
@@ -26612,7 +26741,7 @@ var ReflectorRunner = class {
|
|
|
26612
26741
|
return;
|
|
26613
26742
|
}
|
|
26614
26743
|
omDebug(`[OM:reflect] async activation failed, no blockAfter or below it (obsTokens=${observationTokens}, blockAfter=${this.reflectionConfig.blockAfter}) — starting background reflection`);
|
|
26615
|
-
this.startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext, observabilityContext, reflectionHooks, priorExtractedValues, mainAgent, sendSignal);
|
|
26744
|
+
this.startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext, observabilityContext, reflectionHooks, priorExtractedValues, mainAgent, sendSignal, trigger);
|
|
26616
26745
|
return;
|
|
26617
26746
|
}
|
|
26618
26747
|
}
|
|
@@ -26673,7 +26802,13 @@ var ReflectorRunner = class {
|
|
|
26673
26802
|
throw error;
|
|
26674
26803
|
}
|
|
26675
26804
|
const compressionStartLevel = await this.getCompressionStartLevel(requestContext);
|
|
26676
|
-
const
|
|
26805
|
+
const hookContext = {
|
|
26806
|
+
threadId: requestedThreadId ?? record.threadId ?? void 0,
|
|
26807
|
+
resourceId: record.resourceId ?? void 0,
|
|
26808
|
+
trigger
|
|
26809
|
+
};
|
|
26810
|
+
const reflectResult = await this.call(await applyTextTransform(this.hooks, "beforeReflection", record.activeObservations, hookContext), void 0, streamContext, reflectThreshold, abortSignal, void 0, compressionStartLevel, requestContext, priorExtractedValues, observabilityContext, void 0, mainAgent, sendSignal);
|
|
26811
|
+
reflectResult.observations = await applyTextTransform(this.hooks, "afterReflection", reflectResult.observations, hookContext);
|
|
26677
26812
|
reflectionUsage = reflectResult.usage;
|
|
26678
26813
|
reflectionProviderMetadata = reflectResult.providerMetadata;
|
|
26679
26814
|
await persistThreadExtractedValues(this.storage, this.reflectionConfig.extractors, record.threadId ?? void 0, reflectResult.extractedValues);
|
|
@@ -26732,7 +26867,7 @@ var ReflectorRunner = class {
|
|
|
26732
26867
|
operationType: "reflection",
|
|
26733
26868
|
startedAt: streamContext.startedAt,
|
|
26734
26869
|
tokensAttempted: observationTokens,
|
|
26735
|
-
error
|
|
26870
|
+
error,
|
|
26736
26871
|
recordId: record.id,
|
|
26737
26872
|
threadId
|
|
26738
26873
|
});
|
|
@@ -27424,7 +27559,8 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
27424
27559
|
resolveModel: (inputTokens) => this.resolveObservationModel(inputTokens),
|
|
27425
27560
|
tokenCounter: this.tokenCounter,
|
|
27426
27561
|
mastra: config.mastra,
|
|
27427
|
-
memory: this.memory
|
|
27562
|
+
memory: this.memory,
|
|
27563
|
+
hooks: this.hooks
|
|
27428
27564
|
});
|
|
27429
27565
|
this.buffering = new BufferingCoordinator({
|
|
27430
27566
|
observationConfig: this.observationConfig,
|
|
@@ -27445,7 +27581,8 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
27445
27581
|
resolveModel: (inputTokens) => this.resolveReflectionModel(inputTokens),
|
|
27446
27582
|
mastra: config.mastra,
|
|
27447
27583
|
memory: this.memory,
|
|
27448
|
-
onReflectionCommitted: config.onReflectionCommitted
|
|
27584
|
+
onReflectionCommitted: config.onReflectionCommitted,
|
|
27585
|
+
hooks: this.hooks
|
|
27449
27586
|
});
|
|
27450
27587
|
this.validateBufferConfig();
|
|
27451
27588
|
omDebug(`[OM:init] new ObservationalMemory instance created — scope=${this.scope}, messageTokens=${JSON.stringify(this.observationConfig.messageTokens)}, obsAsyncEnabled=${this.buffering.isAsyncObservationEnabled()}, bufferTokens=${this.observationConfig.bufferTokens}, bufferActivation=${this.observationConfig.bufferActivation}, blockAfter=${this.observationConfig.blockAfter}, reflectionTokens=${this.reflectionConfig.observationTokens}, refAsyncEnabled=${this.buffering.isAsyncReflectionEnabled()}, refAsyncActivation=${this.reflectionConfig.bufferActivation}, refBlockAfter=${this.reflectionConfig.blockAfter}`);
|
|
@@ -28301,7 +28438,8 @@ ${formattedMessages}
|
|
|
28301
28438
|
startedAt,
|
|
28302
28439
|
writer,
|
|
28303
28440
|
requestContext,
|
|
28304
|
-
observabilityContext
|
|
28441
|
+
observabilityContext,
|
|
28442
|
+
trigger: "async-buffer"
|
|
28305
28443
|
}).run());
|
|
28306
28444
|
const maxTs = this.getMaxMessageTimestamp(messagesToBuffer);
|
|
28307
28445
|
const cursor = new Date(maxTs.getTime() + 1);
|
|
@@ -28922,7 +29060,8 @@ ${formattedMessages}
|
|
|
28922
29060
|
sendStateSignal: opts.sendStateSignal,
|
|
28923
29061
|
requestContext,
|
|
28924
29062
|
currentModel: opts.currentModel,
|
|
28925
|
-
observabilityContext
|
|
29063
|
+
observabilityContext,
|
|
29064
|
+
trigger: "async-buffer"
|
|
28926
29065
|
}).run());
|
|
28927
29066
|
if (isOmReproCaptureEnabled()) writeObserverExchangeReproCapture({
|
|
28928
29067
|
threadId,
|
|
@@ -29236,10 +29375,11 @@ ${formattedMessages}
|
|
|
29236
29375
|
async observe(opts) {
|
|
29237
29376
|
const { threadId, resourceId, messages, requestContext } = opts;
|
|
29238
29377
|
const lockKey = this.buffering.getLockKey(threadId, resourceId);
|
|
29378
|
+
const trigger = opts.trigger ?? "manual";
|
|
29239
29379
|
const hooks = this.composeHooks(opts.hooks, {
|
|
29240
29380
|
threadId,
|
|
29241
29381
|
resourceId,
|
|
29242
|
-
trigger
|
|
29382
|
+
trigger
|
|
29243
29383
|
});
|
|
29244
29384
|
const reflectionHooks = hooks ? {
|
|
29245
29385
|
onReflectionStart: hooks.onReflectionStart,
|
|
@@ -29270,6 +29410,7 @@ ${formattedMessages}
|
|
|
29270
29410
|
messages: unobservedMessages,
|
|
29271
29411
|
messageList: opts.messageList,
|
|
29272
29412
|
reflectionHooks,
|
|
29413
|
+
trigger,
|
|
29273
29414
|
agent: opts.agent,
|
|
29274
29415
|
sendSignal: opts.sendSignal,
|
|
29275
29416
|
sendStateSignal: opts.sendStateSignal,
|
|
@@ -29336,11 +29477,12 @@ ${formattedMessages}
|
|
|
29336
29477
|
}
|
|
29337
29478
|
await this.storage.setReflectingFlag(record.id, true);
|
|
29338
29479
|
registerOp(record.id, "reflecting");
|
|
29339
|
-
const
|
|
29480
|
+
const hookContext = {
|
|
29340
29481
|
threadId,
|
|
29341
29482
|
resourceId,
|
|
29342
29483
|
trigger: "manual"
|
|
29343
|
-
}
|
|
29484
|
+
};
|
|
29485
|
+
const hooks = this.composeHooks(void 0, hookContext);
|
|
29344
29486
|
let reflectionUsage;
|
|
29345
29487
|
let reflectionProviderMetadata;
|
|
29346
29488
|
let reflectionError;
|
|
@@ -29357,7 +29499,8 @@ ${formattedMessages}
|
|
|
29357
29499
|
const previousOmMetadata = (0, _mastra_core_memory.getThreadOMMetadata)(thread?.metadata);
|
|
29358
29500
|
const priorExtractedValues = getPriorExtractedValues(previousOmMetadata, this.reflectionConfig.extractors);
|
|
29359
29501
|
const reflectThreshold = getMaxThreshold(this.getEffectiveReflectionTokens(record));
|
|
29360
|
-
const reflectResult = await this.reflector.call(record.activeObservations, prompt, void 0, reflectThreshold, void 0, void 0, void 0, requestContext, priorExtractedValues, observabilityContext, void 0);
|
|
29502
|
+
const reflectResult = await this.reflector.call(await applyTextTransform(this.hooks, "beforeReflection", record.activeObservations, hookContext), prompt, void 0, reflectThreshold, void 0, void 0, void 0, requestContext, priorExtractedValues, observabilityContext, void 0);
|
|
29503
|
+
reflectResult.observations = await applyTextTransform(this.hooks, "afterReflection", reflectResult.observations, hookContext);
|
|
29361
29504
|
const reflectionTokenCount = this.tokenCounter.countObservations(reflectResult.observations);
|
|
29362
29505
|
await this.storage.createReflectionGeneration({
|
|
29363
29506
|
currentRecord: record,
|
|
@@ -30255,7 +30398,7 @@ var Memory = class Memory extends _mastra_core_memory.MastraMemory {
|
|
|
30255
30398
|
});
|
|
30256
30399
|
}
|
|
30257
30400
|
async recall(args) {
|
|
30258
|
-
const { threadId, resourceId, perPage: perPageArg, page, orderBy, threadConfig, vectorSearchString, includeSystemReminders, filter } = args;
|
|
30401
|
+
const { threadId, resourceId, perPage: perPageArg, page, orderBy, threadConfig, vectorSearchString, includeSystemReminders, filter, includeTotal } = args;
|
|
30259
30402
|
const config = this.getMergedThreadConfig(threadConfig || {});
|
|
30260
30403
|
const semanticRecallEnabled = Boolean(config.semanticRecall);
|
|
30261
30404
|
const span = this.createMemorySpan("recall", args.observabilityContext, {
|
|
@@ -30342,6 +30485,7 @@ var Memory = class Memory extends _mastra_core_memory.MastraMemory {
|
|
|
30342
30485
|
page,
|
|
30343
30486
|
orderBy: effectiveOrderBy,
|
|
30344
30487
|
filter,
|
|
30488
|
+
...includeTotal !== void 0 ? { includeTotal } : {},
|
|
30345
30489
|
...filteredVectorResults?.length ? { include: filteredVectorResults.map((r) => ({
|
|
30346
30490
|
id: r.metadata?.message_id,
|
|
30347
30491
|
threadId: r.metadata?.thread_id,
|
|
@@ -30954,6 +31098,7 @@ ${workingMemory}`;
|
|
|
30954
31098
|
direction: "ASC"
|
|
30955
31099
|
},
|
|
30956
31100
|
perPage: false,
|
|
31101
|
+
includeTotal: false,
|
|
30957
31102
|
filter: dateFilter
|
|
30958
31103
|
})).messages;
|
|
30959
31104
|
};
|
|
@@ -30967,6 +31112,7 @@ ${workingMemory}`;
|
|
|
30967
31112
|
direction: "ASC"
|
|
30968
31113
|
},
|
|
30969
31114
|
perPage: false,
|
|
31115
|
+
includeTotal: false,
|
|
30970
31116
|
filter: dateFilter
|
|
30971
31117
|
})).messages;
|
|
30972
31118
|
};
|
|
@@ -30982,7 +31128,8 @@ ${workingMemory}`;
|
|
|
30982
31128
|
field: "createdAt",
|
|
30983
31129
|
direction: "DESC"
|
|
30984
31130
|
},
|
|
30985
|
-
perPage: typeof lastMessages === "number" ? lastMessages : void 0
|
|
31131
|
+
perPage: typeof lastMessages === "number" ? lastMessages : void 0,
|
|
31132
|
+
includeTotal: false
|
|
30986
31133
|
})).messages.reverse();
|
|
30987
31134
|
}
|
|
30988
31135
|
return {
|
|
@@ -31344,7 +31491,8 @@ Notes:
|
|
|
31344
31491
|
threadId,
|
|
31345
31492
|
resourceId,
|
|
31346
31493
|
perPage: SUMMARIZE_THREAD_DEFAULTS.pageSize,
|
|
31347
|
-
page
|
|
31494
|
+
page,
|
|
31495
|
+
includeTotal: false
|
|
31348
31496
|
});
|
|
31349
31497
|
if (batch.length === 0) break;
|
|
31350
31498
|
let reachedLimit = false;
|
|
@@ -32276,4 +32424,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
|
|
|
32276
32424
|
}
|
|
32277
32425
|
});
|
|
32278
32426
|
|
|
32279
|
-
//# sourceMappingURL=src-
|
|
32427
|
+
//# sourceMappingURL=src-DjCR8GJe.cjs.map
|