@mastra/memory 1.8.2 → 1.8.3-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/CHANGELOG.md +32 -0
- package/dist/chunk-3PUO6DLX.js +439 -0
- package/dist/chunk-3PUO6DLX.js.map +1 -0
- package/dist/{chunk-SUU4IAZJ.js → chunk-4KPXPQX3.js} +212 -75
- package/dist/chunk-4KPXPQX3.js.map +1 -0
- package/dist/{chunk-23EXJLET.cjs → chunk-CK4U3AYR.cjs} +4 -4
- package/dist/{chunk-23EXJLET.cjs.map → chunk-CK4U3AYR.cjs.map} +1 -1
- package/dist/chunk-DAJJSFVA.cjs +441 -0
- package/dist/chunk-DAJJSFVA.cjs.map +1 -0
- package/dist/{chunk-YPFNHFT6.cjs → chunk-LGCREJMO.cjs} +212 -74
- package/dist/chunk-LGCREJMO.cjs.map +1 -0
- package/dist/{chunk-BSDWQEU3.js → chunk-SVPZMV27.js} +4 -4
- package/dist/{chunk-BSDWQEU3.js.map → chunk-SVPZMV27.js.map} +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +30 -25
- package/dist/docs/references/docs-agents-agent-approval.md +4 -4
- package/dist/docs/references/docs-agents-network-approval.md +1 -1
- package/dist/docs/references/docs-agents-networks.md +1 -1
- package/dist/docs/references/docs-agents-supervisor-agents.md +3 -3
- package/dist/docs/references/docs-memory-memory-processors.md +6 -6
- package/dist/docs/references/docs-memory-semantic-recall.md +1 -1
- package/dist/docs/references/docs-memory-storage.md +1 -1
- package/dist/docs/references/docs-memory-working-memory.md +1 -1
- package/dist/docs/references/reference-memory-memory-class.md +3 -3
- package/dist/docs/references/reference-memory-observational-memory.md +5 -5
- package/dist/docs/references/reference-processors-token-limiter-processor.md +3 -3
- package/dist/docs/references/reference-storage-mongodb.md +1 -1
- package/dist/docs/references/reference-storage-postgresql.md +1 -1
- package/dist/docs/references/reference-storage-upstash.md +1 -1
- package/dist/docs/references/reference-vectors-libsql.md +1 -1
- package/dist/docs/references/reference-vectors-mongodb.md +1 -1
- package/dist/docs/references/reference-vectors-pg.md +1 -1
- package/dist/docs/references/reference-vectors-upstash.md +1 -1
- package/dist/index.cjs +891 -255
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +881 -249
- package/dist/index.js.map +1 -1
- package/dist/{observational-memory-3HFM7PY2.cjs → observational-memory-4TV5KKFV.cjs} +21 -17
- package/dist/{observational-memory-3HFM7PY2.cjs.map → observational-memory-4TV5KKFV.cjs.map} +1 -1
- package/dist/observational-memory-UEDVTWS2.js +3 -0
- package/dist/{observational-memory-XXD6E2SO.js.map → observational-memory-UEDVTWS2.js.map} +1 -1
- package/dist/processors/index.cjs +19 -15
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/index.d.ts +1 -0
- package/dist/processors/observational-memory/index.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-utils.d.ts +16 -0
- package/dist/processors/observational-memory/observation-utils.d.ts.map +1 -0
- package/dist/processors/observational-memory/observational-memory.d.ts +13 -4
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/observer-agent.d.ts +9 -7
- package/dist/processors/observational-memory/observer-agent.d.ts.map +1 -1
- package/dist/processors/observational-memory/token-counter.d.ts.map +1 -1
- package/dist/processors/observational-memory/tool-result-helpers.d.ts +12 -0
- package/dist/processors/observational-memory/tool-result-helpers.d.ts.map +1 -0
- package/dist/{token-6GSAFR2W-TW2P7HCS.cjs → token-APYSY3BW-POD4OUWN.cjs} +14 -14
- package/dist/token-APYSY3BW-POD4OUWN.cjs.map +1 -0
- package/dist/{token-6GSAFR2W-ABXTQD64.js → token-APYSY3BW-YTVQELJT.js} +11 -11
- package/dist/token-APYSY3BW-YTVQELJT.js.map +1 -0
- package/dist/token-util-RMHT2CPJ-77HHGIQN.cjs +10 -0
- package/dist/token-util-RMHT2CPJ-77HHGIQN.cjs.map +1 -0
- package/dist/token-util-RMHT2CPJ-WJZ2SYAR.js +8 -0
- package/dist/token-util-RMHT2CPJ-WJZ2SYAR.js.map +1 -0
- package/package.json +8 -8
- package/dist/chunk-HJYHDIOC.js +0 -250
- package/dist/chunk-HJYHDIOC.js.map +0 -1
- package/dist/chunk-LIBOSOHM.cjs +0 -252
- package/dist/chunk-LIBOSOHM.cjs.map +0 -1
- package/dist/chunk-SUU4IAZJ.js.map +0 -1
- package/dist/chunk-YPFNHFT6.cjs.map +0 -1
- package/dist/observational-memory-XXD6E2SO.js +0 -3
- package/dist/token-6GSAFR2W-ABXTQD64.js.map +0 -1
- package/dist/token-6GSAFR2W-TW2P7HCS.cjs.map +0 -1
- package/dist/token-util-NEHG7TUY-GYFEVMWP.cjs +0 -10
- package/dist/token-util-NEHG7TUY-GYFEVMWP.cjs.map +0 -1
- package/dist/token-util-NEHG7TUY-XQP3QSPX.js +0 -8
- package/dist/token-util-NEHG7TUY-XQP3QSPX.js.map +0 -1
|
@@ -8,10 +8,10 @@ var llm = require('@mastra/core/llm');
|
|
|
8
8
|
var memory = require('@mastra/core/memory');
|
|
9
9
|
var processors = require('@mastra/core/processors');
|
|
10
10
|
var xxhash = require('xxhash-wasm');
|
|
11
|
+
var tokenx = require('tokenx');
|
|
11
12
|
var crypto$1 = require('crypto');
|
|
12
13
|
var async_hooks = require('async_hooks');
|
|
13
14
|
var imageSize = require('image-size');
|
|
14
|
-
var tokenx = require('tokenx');
|
|
15
15
|
|
|
16
16
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
17
|
|
|
@@ -307,6 +307,97 @@ function createActivationMarker(params) {
|
|
|
307
307
|
}
|
|
308
308
|
};
|
|
309
309
|
}
|
|
310
|
+
var ENCRYPTED_CONTENT_KEY = "encryptedContent";
|
|
311
|
+
var ENCRYPTED_CONTENT_REDACTION_THRESHOLD = 256;
|
|
312
|
+
var DEFAULT_OBSERVER_TOOL_RESULT_MAX_TOKENS = 1e4;
|
|
313
|
+
function isObjectLike(value) {
|
|
314
|
+
return typeof value === "object" && value !== null;
|
|
315
|
+
}
|
|
316
|
+
function sanitizeToolResultValue(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
317
|
+
if (!isObjectLike(value)) {
|
|
318
|
+
return value;
|
|
319
|
+
}
|
|
320
|
+
if (seen.has(value)) {
|
|
321
|
+
return seen.get(value);
|
|
322
|
+
}
|
|
323
|
+
if (Array.isArray(value)) {
|
|
324
|
+
const sanitizedArray = [];
|
|
325
|
+
seen.set(value, sanitizedArray);
|
|
326
|
+
for (const item of value) {
|
|
327
|
+
sanitizedArray.push(sanitizeToolResultValue(item, seen));
|
|
328
|
+
}
|
|
329
|
+
return sanitizedArray;
|
|
330
|
+
}
|
|
331
|
+
const sanitizedObject = {};
|
|
332
|
+
seen.set(value, sanitizedObject);
|
|
333
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
334
|
+
if (key === ENCRYPTED_CONTENT_KEY && typeof entry === "string" && entry.length > ENCRYPTED_CONTENT_REDACTION_THRESHOLD) {
|
|
335
|
+
sanitizedObject[key] = `[stripped encryptedContent: ${entry.length} characters]`;
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
sanitizedObject[key] = sanitizeToolResultValue(entry, seen);
|
|
339
|
+
}
|
|
340
|
+
return sanitizedObject;
|
|
341
|
+
}
|
|
342
|
+
function stringifyToolResult(value) {
|
|
343
|
+
if (typeof value === "string") {
|
|
344
|
+
return value;
|
|
345
|
+
}
|
|
346
|
+
const sanitized = sanitizeToolResultValue(value);
|
|
347
|
+
try {
|
|
348
|
+
return JSON.stringify(sanitized, null, 2);
|
|
349
|
+
} catch {
|
|
350
|
+
return String(sanitized);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
function resolveToolResultValue(part, invocationResult) {
|
|
354
|
+
const mastraMetadata = part?.providerMetadata?.mastra;
|
|
355
|
+
if (mastraMetadata && typeof mastraMetadata === "object" && "modelOutput" in mastraMetadata) {
|
|
356
|
+
return {
|
|
357
|
+
value: mastraMetadata.modelOutput,
|
|
358
|
+
usingStoredModelOutput: true
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
value: invocationResult,
|
|
363
|
+
usingStoredModelOutput: false
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function truncateStringByTokens(text, maxTokens) {
|
|
367
|
+
if (!text || maxTokens <= 0) {
|
|
368
|
+
return "";
|
|
369
|
+
}
|
|
370
|
+
const totalTokens = tokenx.estimateTokenCount(text);
|
|
371
|
+
if (totalTokens <= maxTokens) {
|
|
372
|
+
return text;
|
|
373
|
+
}
|
|
374
|
+
const buildCandidate = (sliceEnd) => {
|
|
375
|
+
const visible = text.slice(0, sliceEnd);
|
|
376
|
+
const omittedChars = text.length - sliceEnd;
|
|
377
|
+
return `${visible}
|
|
378
|
+
... [truncated ~${totalTokens - tokenx.estimateTokenCount(visible)} tokens / ${omittedChars} characters]`;
|
|
379
|
+
};
|
|
380
|
+
let low = 0;
|
|
381
|
+
let high = text.length;
|
|
382
|
+
let best = buildCandidate(0);
|
|
383
|
+
while (low <= high) {
|
|
384
|
+
const mid = Math.floor((low + high) / 2);
|
|
385
|
+
const candidate = buildCandidate(mid);
|
|
386
|
+
const candidateTokens = tokenx.estimateTokenCount(candidate);
|
|
387
|
+
if (candidateTokens <= maxTokens) {
|
|
388
|
+
best = candidate;
|
|
389
|
+
low = mid + 1;
|
|
390
|
+
} else {
|
|
391
|
+
high = mid - 1;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return best;
|
|
395
|
+
}
|
|
396
|
+
function formatToolResultForObserver(value, options) {
|
|
397
|
+
const serialized = stringifyToolResult(value);
|
|
398
|
+
const maxTokens = options?.maxTokens ?? DEFAULT_OBSERVER_TOOL_RESULT_MAX_TOKENS;
|
|
399
|
+
return truncateStringByTokens(serialized, maxTokens);
|
|
400
|
+
}
|
|
310
401
|
|
|
311
402
|
// src/processors/observational-memory/observer-agent.ts
|
|
312
403
|
var OBSERVER_EXTRACTION_INSTRUCTIONS = `CRITICAL: DISTINGUISH USER ASSERTIONS FROM QUESTIONS
|
|
@@ -781,6 +872,7 @@ function formatObserverAttachmentPlaceholder(part, counter) {
|
|
|
781
872
|
}
|
|
782
873
|
function formatObserverMessage(msg, counter, options) {
|
|
783
874
|
const maxLen = options?.maxPartLength;
|
|
875
|
+
const maxToolResultTokens = options?.maxToolResultTokens ?? DEFAULT_OBSERVER_TOOL_RESULT_MAX_TOKENS;
|
|
784
876
|
const timestamp = formatObserverTimestamp(msg.createdAt);
|
|
785
877
|
const role = msg.role.charAt(0).toUpperCase() + msg.role.slice(1);
|
|
786
878
|
const timestampStr = timestamp ? ` (${timestamp})` : "";
|
|
@@ -794,7 +886,11 @@ function formatObserverMessage(msg, counter, options) {
|
|
|
794
886
|
if (part.type === "tool-invocation") {
|
|
795
887
|
const inv = part.toolInvocation;
|
|
796
888
|
if (inv.state === "result") {
|
|
797
|
-
const
|
|
889
|
+
const { value: resultForObserver } = resolveToolResultValue(
|
|
890
|
+
part,
|
|
891
|
+
inv.result
|
|
892
|
+
);
|
|
893
|
+
const resultStr = formatToolResultForObserver(resultForObserver, { maxTokens: maxToolResultTokens });
|
|
798
894
|
return `[Tool Result: ${inv.toolName}]
|
|
799
895
|
${maybeTruncate(resultStr, maxLen)}`;
|
|
800
896
|
}
|
|
@@ -835,12 +931,12 @@ function formatMessagesForObserver(messages, options) {
|
|
|
835
931
|
const counter = { nextImageId: 1, nextFileId: 1 };
|
|
836
932
|
return messages.map((msg) => formatObserverMessage(msg, counter, options).text).filter(Boolean).join("\n\n---\n\n");
|
|
837
933
|
}
|
|
838
|
-
function buildObserverHistoryMessage(messages) {
|
|
934
|
+
function buildObserverHistoryMessage(messages, options) {
|
|
839
935
|
const counter = { nextImageId: 1, nextFileId: 1 };
|
|
840
936
|
const content = [{ type: "text", text: "## New Message History to Observe\n\n" }];
|
|
841
937
|
let visibleCount = 0;
|
|
842
938
|
messages.forEach((message) => {
|
|
843
|
-
const formatted = formatObserverMessage(message, counter);
|
|
939
|
+
const formatted = formatObserverMessage(message, counter, options);
|
|
844
940
|
if (!formatted.text && formatted.attachments.length === 0) return;
|
|
845
941
|
if (visibleCount > 0) {
|
|
846
942
|
content.push({ type: "text", text: "\n\n---\n\n" });
|
|
@@ -861,7 +957,7 @@ function maybeTruncate(str, maxLen) {
|
|
|
861
957
|
return `${truncated}
|
|
862
958
|
... [truncated ${remaining} characters]`;
|
|
863
959
|
}
|
|
864
|
-
function buildMultiThreadObserverHistoryMessage(messagesByThread, threadOrder) {
|
|
960
|
+
function buildMultiThreadObserverHistoryMessage(messagesByThread, threadOrder, options) {
|
|
865
961
|
const counter = { nextImageId: 1, nextFileId: 1 };
|
|
866
962
|
const content = [
|
|
867
963
|
{
|
|
@@ -879,7 +975,7 @@ The following messages are from ${threadOrder.length} different conversation thr
|
|
|
879
975
|
const threadContent = [];
|
|
880
976
|
let visibleCount = 0;
|
|
881
977
|
messages.forEach((message) => {
|
|
882
|
-
const formatted = formatObserverMessage(message, counter);
|
|
978
|
+
const formatted = formatObserverMessage(message, counter, options);
|
|
883
979
|
if (!formatted.text && formatted.attachments.length === 0) return;
|
|
884
980
|
if (visibleCount > 0) {
|
|
885
981
|
threadContent.push({ type: "text", text: "\n\n---\n\n" });
|
|
@@ -2523,17 +2619,7 @@ var TokenCounter = class _TokenCounter {
|
|
|
2523
2619
|
return tokens;
|
|
2524
2620
|
}
|
|
2525
2621
|
resolveToolResultForTokenCounting(part, invocationResult) {
|
|
2526
|
-
|
|
2527
|
-
if (mastraMetadata && typeof mastraMetadata === "object" && "modelOutput" in mastraMetadata) {
|
|
2528
|
-
return {
|
|
2529
|
-
value: mastraMetadata.modelOutput,
|
|
2530
|
-
usingStoredModelOutput: true
|
|
2531
|
-
};
|
|
2532
|
-
}
|
|
2533
|
-
return {
|
|
2534
|
-
value: invocationResult,
|
|
2535
|
-
usingStoredModelOutput: false
|
|
2536
|
-
};
|
|
2622
|
+
return resolveToolResultValue(part, invocationResult);
|
|
2537
2623
|
}
|
|
2538
2624
|
estimateImageAssetTokens(part, asset, kind) {
|
|
2539
2625
|
const modelContext = this.getModelContext();
|
|
@@ -2772,19 +2858,13 @@ var TokenCounter = class _TokenCounter {
|
|
|
2772
2858
|
invocation.result
|
|
2773
2859
|
);
|
|
2774
2860
|
if (resultForCounting !== void 0) {
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
const resultJson = JSON.stringify(resultForCounting);
|
|
2783
|
-
tokens += this.readOrPersistPartEstimate(
|
|
2784
|
-
part,
|
|
2785
|
-
usingStoredModelOutput ? "tool-result-model-output-json" : "tool-result-json",
|
|
2786
|
-
resultJson
|
|
2787
|
-
);
|
|
2861
|
+
const formattedResult = formatToolResultForObserver(resultForCounting);
|
|
2862
|
+
tokens += this.readOrPersistPartEstimate(
|
|
2863
|
+
part,
|
|
2864
|
+
usingStoredModelOutput ? "tool-result-model-output-json" : "tool-result-json",
|
|
2865
|
+
formattedResult
|
|
2866
|
+
);
|
|
2867
|
+
if (typeof resultForCounting !== "string") {
|
|
2788
2868
|
overheadDelta -= 12;
|
|
2789
2869
|
}
|
|
2790
2870
|
}
|
|
@@ -2900,6 +2980,14 @@ function omDebug(msg) {
|
|
|
2900
2980
|
} catch {
|
|
2901
2981
|
}
|
|
2902
2982
|
}
|
|
2983
|
+
function getLatestStepParts(parts) {
|
|
2984
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
2985
|
+
if (parts[i]?.type === "step-start") {
|
|
2986
|
+
return parts.slice(i + 1);
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
return parts;
|
|
2990
|
+
}
|
|
2903
2991
|
function omError(msg, err) {
|
|
2904
2992
|
const errStr = err instanceof Error ? err.stack ?? err.message : err !== void 0 ? String(err) : "";
|
|
2905
2993
|
const full = errStr ? `${msg}: ${errStr}` : msg;
|
|
@@ -4346,38 +4434,51 @@ ${unreflectedContent}` : bufferedReflection;
|
|
|
4346
4434
|
if (currentDate) {
|
|
4347
4435
|
optimized = addRelativeTimeToObservations(optimized, currentDate);
|
|
4348
4436
|
}
|
|
4349
|
-
|
|
4350
|
-
${OBSERVATION_CONTEXT_PROMPT}
|
|
4351
|
-
|
|
4352
|
-
<observations>
|
|
4353
|
-
${optimized}
|
|
4354
|
-
</observations>
|
|
4437
|
+
const messages = [`${OBSERVATION_CONTEXT_PROMPT}
|
|
4355
4438
|
|
|
4356
|
-
${OBSERVATION_CONTEXT_INSTRUCTIONS}
|
|
4439
|
+
${OBSERVATION_CONTEXT_INSTRUCTIONS}`];
|
|
4357
4440
|
if (unobservedContextBlocks) {
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
The following content is from OTHER conversations different from the current conversation, they're here for reference, but they're not necessarily your focus:
|
|
4441
|
+
messages.push(
|
|
4442
|
+
`The following content is from OTHER conversations different from the current conversation, they're here for reference, but they're not necessarily your focus:
|
|
4361
4443
|
START_OTHER_CONVERSATIONS_BLOCK
|
|
4362
4444
|
${unobservedContextBlocks}
|
|
4363
|
-
END_OTHER_CONVERSATIONS_BLOCK
|
|
4445
|
+
END_OTHER_CONVERSATIONS_BLOCK`
|
|
4446
|
+
);
|
|
4447
|
+
}
|
|
4448
|
+
const observationChunks = this.splitObservationContextChunks(optimized);
|
|
4449
|
+
if (observationChunks.length > 0) {
|
|
4450
|
+
messages.push("<observations>", ...observationChunks);
|
|
4364
4451
|
}
|
|
4365
4452
|
if (currentTask) {
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
<current-task>
|
|
4453
|
+
messages.push(`<current-task>
|
|
4369
4454
|
${currentTask}
|
|
4370
|
-
</current-task
|
|
4455
|
+
</current-task>`);
|
|
4371
4456
|
}
|
|
4372
4457
|
if (suggestedResponse) {
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
<suggested-response>
|
|
4458
|
+
messages.push(`<suggested-response>
|
|
4376
4459
|
${suggestedResponse}
|
|
4377
|
-
</suggested-response
|
|
4378
|
-
|
|
4460
|
+
</suggested-response>`);
|
|
4461
|
+
}
|
|
4462
|
+
return messages;
|
|
4463
|
+
}
|
|
4464
|
+
splitObservationContextChunks(observations) {
|
|
4465
|
+
const trimmed = observations.trim();
|
|
4466
|
+
if (!trimmed) {
|
|
4467
|
+
return [];
|
|
4379
4468
|
}
|
|
4380
|
-
return
|
|
4469
|
+
return trimmed.split(/\n{2,}--- message boundary \(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z\) ---\n{2,}/).map((chunk) => chunk.trim()).filter(Boolean);
|
|
4470
|
+
}
|
|
4471
|
+
/**
|
|
4472
|
+
* Create a message boundary delimiter with an ISO 8601 date.
|
|
4473
|
+
* The date should be the lastObservedAt timestamp — the latest message
|
|
4474
|
+
* timestamp that was observed to produce the observations following this boundary.
|
|
4475
|
+
*/
|
|
4476
|
+
static createMessageBoundary(date) {
|
|
4477
|
+
return `
|
|
4478
|
+
|
|
4479
|
+
--- message boundary (${date.toISOString()}) ---
|
|
4480
|
+
|
|
4481
|
+
`;
|
|
4381
4482
|
}
|
|
4382
4483
|
/**
|
|
4383
4484
|
* Get threadId and resourceId from either RequestContext or MessageList
|
|
@@ -4815,7 +4916,7 @@ ${suggestedResponse}
|
|
|
4815
4916
|
if (!record.activeObservations) {
|
|
4816
4917
|
return;
|
|
4817
4918
|
}
|
|
4818
|
-
const
|
|
4919
|
+
const observationSystemMessages = this.formatObservationsForContext(
|
|
4819
4920
|
record.activeObservations,
|
|
4820
4921
|
currentTask,
|
|
4821
4922
|
suggestedResponse,
|
|
@@ -4823,7 +4924,7 @@ ${suggestedResponse}
|
|
|
4823
4924
|
currentDate
|
|
4824
4925
|
);
|
|
4825
4926
|
messageList.clearSystemMessages("observational-memory");
|
|
4826
|
-
messageList.addSystem(
|
|
4927
|
+
messageList.addSystem(observationSystemMessages, "observational-memory");
|
|
4827
4928
|
const continuationMessage = {
|
|
4828
4929
|
id: `om-continuation`,
|
|
4829
4930
|
role: "user",
|
|
@@ -5099,12 +5200,20 @@ ${suggestedResponse}
|
|
|
5099
5200
|
const sealedIds = /* @__PURE__ */ new Set([...stateSealedIds, ...staticSealedIds]);
|
|
5100
5201
|
state.sealedIds = sealedIds;
|
|
5101
5202
|
const lockKey = this.getLockKey(threadId, resourceId);
|
|
5203
|
+
const lastMessage = allMessages[allMessages.length - 1];
|
|
5204
|
+
const latestStepParts = getLatestStepParts(lastMessage?.content?.parts ?? []);
|
|
5205
|
+
const hasIncompleteToolCalls = latestStepParts.some(
|
|
5206
|
+
(part) => part?.type === "tool-invocation" && part.toolInvocation?.state === "call"
|
|
5207
|
+
);
|
|
5208
|
+
omDebug(
|
|
5209
|
+
`[OM:deferred-check] hasIncompleteToolCalls=${hasIncompleteToolCalls}, latestStepPartsCount=${latestStepParts.length}`
|
|
5210
|
+
);
|
|
5102
5211
|
if (this.isAsyncObservationEnabled() && totalPendingTokens < threshold) {
|
|
5103
5212
|
const shouldTrigger = this.shouldTriggerAsyncObservation(totalPendingTokens, lockKey, record, threshold);
|
|
5104
5213
|
omDebug(
|
|
5105
|
-
`[OM:async-obs] belowThreshold: pending=${totalPendingTokens}, unbuffered=${unbufferedPendingTokens}, threshold=${threshold}, shouldTrigger=${shouldTrigger}, isBufferingObs=${record.isBufferingObservation}, lastBufferedAt=${record.lastBufferedAtTokens}`
|
|
5214
|
+
`[OM:async-obs] belowThreshold: pending=${totalPendingTokens}, unbuffered=${unbufferedPendingTokens}, threshold=${threshold}, shouldTrigger=${shouldTrigger}, isBufferingObs=${record.isBufferingObservation}, lastBufferedAt=${record.lastBufferedAtTokens}, hasIncompleteToolCalls=${hasIncompleteToolCalls}`
|
|
5106
5215
|
);
|
|
5107
|
-
if (shouldTrigger) {
|
|
5216
|
+
if (shouldTrigger && !hasIncompleteToolCalls) {
|
|
5108
5217
|
void this.startAsyncBufferedObservation(
|
|
5109
5218
|
record,
|
|
5110
5219
|
threadId,
|
|
@@ -5118,9 +5227,9 @@ ${suggestedResponse}
|
|
|
5118
5227
|
} else if (this.isAsyncObservationEnabled()) {
|
|
5119
5228
|
const shouldTrigger = this.shouldTriggerAsyncObservation(totalPendingTokens, lockKey, record, threshold);
|
|
5120
5229
|
omDebug(
|
|
5121
|
-
`[OM:async-obs] atOrAboveThreshold: pending=${totalPendingTokens}, unbuffered=${unbufferedPendingTokens}, threshold=${threshold}, step=${stepNumber}, shouldTrigger=${shouldTrigger}`
|
|
5230
|
+
`[OM:async-obs] atOrAboveThreshold: pending=${totalPendingTokens}, unbuffered=${unbufferedPendingTokens}, threshold=${threshold}, step=${stepNumber}, shouldTrigger=${shouldTrigger}, hasIncompleteToolCalls=${hasIncompleteToolCalls}`
|
|
5122
5231
|
);
|
|
5123
|
-
if (shouldTrigger) {
|
|
5232
|
+
if (shouldTrigger && !hasIncompleteToolCalls) {
|
|
5124
5233
|
void this.startAsyncBufferedObservation(
|
|
5125
5234
|
record,
|
|
5126
5235
|
threadId,
|
|
@@ -5135,7 +5244,7 @@ ${suggestedResponse}
|
|
|
5135
5244
|
if (stepNumber > 0) {
|
|
5136
5245
|
await this.handlePerStepSave(messageList, sealedIds, threadId, resourceId, state);
|
|
5137
5246
|
}
|
|
5138
|
-
if (stepNumber > 0 && totalPendingTokens >= threshold) {
|
|
5247
|
+
if (stepNumber > 0 && !hasIncompleteToolCalls && totalPendingTokens >= threshold) {
|
|
5139
5248
|
reproCaptureDetails.thresholdReached = true;
|
|
5140
5249
|
const { observationSucceeded, updatedRecord, activatedMessageIds } = await this.handleThresholdReached(
|
|
5141
5250
|
messageList,
|
|
@@ -5493,16 +5602,14 @@ ${cleanObservations}
|
|
|
5493
5602
|
* merge the observations into that section to reduce token usage.
|
|
5494
5603
|
* Otherwise, append as a new section.
|
|
5495
5604
|
*/
|
|
5496
|
-
replaceOrAppendThreadSection(existingObservations, _threadId, newThreadSection) {
|
|
5605
|
+
replaceOrAppendThreadSection(existingObservations, _threadId, newThreadSection, lastObservedAt) {
|
|
5497
5606
|
if (!existingObservations) {
|
|
5498
5607
|
return newThreadSection;
|
|
5499
5608
|
}
|
|
5500
5609
|
const threadIdMatch = newThreadSection.match(/<thread id="([^"]+)">/);
|
|
5501
5610
|
const dateMatch = newThreadSection.match(/Date:\s*([A-Za-z]+\s+\d+,\s+\d+)/);
|
|
5502
5611
|
if (!threadIdMatch || !dateMatch) {
|
|
5503
|
-
return `${existingObservations}
|
|
5504
|
-
|
|
5505
|
-
${newThreadSection}`;
|
|
5612
|
+
return `${existingObservations}${_ObservationalMemory.createMessageBoundary(lastObservedAt)}${newThreadSection}`;
|
|
5506
5613
|
}
|
|
5507
5614
|
const newThreadId = threadIdMatch[1];
|
|
5508
5615
|
const newDate = dateMatch[1];
|
|
@@ -5537,9 +5644,7 @@ ${threadClose}`;
|
|
|
5537
5644
|
}
|
|
5538
5645
|
}
|
|
5539
5646
|
}
|
|
5540
|
-
return `${existingObservations}
|
|
5541
|
-
|
|
5542
|
-
${newThreadSection}`;
|
|
5647
|
+
return `${existingObservations}${_ObservationalMemory.createMessageBoundary(lastObservedAt)}${newThreadSection}`;
|
|
5543
5648
|
}
|
|
5544
5649
|
/**
|
|
5545
5650
|
* Sort threads by their oldest unobserved message.
|
|
@@ -5622,19 +5727,22 @@ ${newThreadSection}`;
|
|
|
5622
5727
|
priorSuggestedResponse: threadOMMetadata?.suggestedResponse,
|
|
5623
5728
|
wasTruncated
|
|
5624
5729
|
});
|
|
5730
|
+
const lastObservedAt = this.getMaxMessageTimestamp(messagesToObserve);
|
|
5625
5731
|
const existingObservations = freshRecord?.activeObservations ?? record.activeObservations ?? "";
|
|
5626
5732
|
let newObservations;
|
|
5627
5733
|
if (this.scope === "resource") {
|
|
5628
5734
|
const threadSection = await this.wrapWithThreadTag(threadId, result.observations);
|
|
5629
|
-
newObservations = this.replaceOrAppendThreadSection(
|
|
5735
|
+
newObservations = this.replaceOrAppendThreadSection(
|
|
5736
|
+
existingObservations,
|
|
5737
|
+
threadId,
|
|
5738
|
+
threadSection,
|
|
5739
|
+
lastObservedAt
|
|
5740
|
+
);
|
|
5630
5741
|
} else {
|
|
5631
|
-
newObservations = existingObservations ? `${existingObservations}
|
|
5632
|
-
|
|
5633
|
-
${result.observations}` : result.observations;
|
|
5742
|
+
newObservations = existingObservations ? `${existingObservations}${_ObservationalMemory.createMessageBoundary(lastObservedAt)}${result.observations}` : result.observations;
|
|
5634
5743
|
}
|
|
5635
5744
|
let totalTokenCount = this.tokenCounter.countObservations(newObservations);
|
|
5636
5745
|
const cycleObservationTokens = this.tokenCounter.countObservations(result.observations);
|
|
5637
|
-
const lastObservedAt = this.getMaxMessageTimestamp(messagesToObserve);
|
|
5638
5746
|
const newMessageIds = messagesToObserve.map((m) => m.id);
|
|
5639
5747
|
const existingIds = freshRecord?.observedMessageIds ?? record.observedMessageIds ?? [];
|
|
5640
5748
|
const allObservedIds = [.../* @__PURE__ */ new Set([...Array.isArray(existingIds) ? existingIds : [], ...newMessageIds])];
|
|
@@ -6528,9 +6636,14 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
|
|
|
6528
6636
|
if (!obsResult) continue;
|
|
6529
6637
|
const { threadId, threadMessages, result } = obsResult;
|
|
6530
6638
|
cycleObservationTokens += this.tokenCounter.countObservations(result.observations);
|
|
6531
|
-
const threadSection = await this.wrapWithThreadTag(threadId, result.observations);
|
|
6532
|
-
currentObservations = this.replaceOrAppendThreadSection(currentObservations, threadId, threadSection);
|
|
6533
6639
|
const threadLastObservedAt = this.getMaxMessageTimestamp(threadMessages);
|
|
6640
|
+
const threadSection = await this.wrapWithThreadTag(threadId, result.observations);
|
|
6641
|
+
currentObservations = this.replaceOrAppendThreadSection(
|
|
6642
|
+
currentObservations,
|
|
6643
|
+
threadId,
|
|
6644
|
+
threadSection,
|
|
6645
|
+
threadLastObservedAt
|
|
6646
|
+
);
|
|
6534
6647
|
const thread = await this.storage.getThreadById({ threadId });
|
|
6535
6648
|
if (thread) {
|
|
6536
6649
|
const newMetadata = memory.setThreadOMMetadata(thread.metadata, {
|
|
@@ -6975,6 +7088,30 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
|
|
|
6975
7088
|
}
|
|
6976
7089
|
};
|
|
6977
7090
|
|
|
7091
|
+
// src/processors/observational-memory/observation-utils.ts
|
|
7092
|
+
var BOUNDARY_WITH_DATE_RE = /\n{2,}--- message boundary \((\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z)\) ---\n{2,}/;
|
|
7093
|
+
function getObservationsAsOf(activeObservations, asOf) {
|
|
7094
|
+
const trimmed = activeObservations.trim();
|
|
7095
|
+
if (!trimmed) return "";
|
|
7096
|
+
const parts = trimmed.split(BOUNDARY_WITH_DATE_RE);
|
|
7097
|
+
const chunks = [];
|
|
7098
|
+
const firstChunk = parts[0]?.trim();
|
|
7099
|
+
if (firstChunk) {
|
|
7100
|
+
chunks.push(firstChunk);
|
|
7101
|
+
}
|
|
7102
|
+
for (let i = 1; i < parts.length; i += 2) {
|
|
7103
|
+
const dateStr = parts[i];
|
|
7104
|
+
const chunk = parts[i + 1]?.trim();
|
|
7105
|
+
if (!chunk) continue;
|
|
7106
|
+
const boundaryDate = new Date(dateStr);
|
|
7107
|
+
if (isNaN(boundaryDate.getTime())) continue;
|
|
7108
|
+
if (boundaryDate <= asOf) {
|
|
7109
|
+
chunks.push(chunk);
|
|
7110
|
+
}
|
|
7111
|
+
}
|
|
7112
|
+
return chunks.join("\n\n");
|
|
7113
|
+
}
|
|
7114
|
+
|
|
6978
7115
|
exports.OBSERVATIONAL_MEMORY_DEFAULTS = OBSERVATIONAL_MEMORY_DEFAULTS;
|
|
6979
7116
|
exports.OBSERVATION_CONTEXT_INSTRUCTIONS = OBSERVATION_CONTEXT_INSTRUCTIONS;
|
|
6980
7117
|
exports.OBSERVATION_CONTEXT_PROMPT = OBSERVATION_CONTEXT_PROMPT;
|
|
@@ -6986,8 +7123,9 @@ exports.buildObserverPrompt = buildObserverPrompt;
|
|
|
6986
7123
|
exports.buildObserverSystemPrompt = buildObserverSystemPrompt;
|
|
6987
7124
|
exports.extractCurrentTask = extractCurrentTask;
|
|
6988
7125
|
exports.formatMessagesForObserver = formatMessagesForObserver;
|
|
7126
|
+
exports.getObservationsAsOf = getObservationsAsOf;
|
|
6989
7127
|
exports.hasCurrentTaskSection = hasCurrentTaskSection;
|
|
6990
7128
|
exports.optimizeObservationsForContext = optimizeObservationsForContext;
|
|
6991
7129
|
exports.parseObserverOutput = parseObserverOutput;
|
|
6992
|
-
//# sourceMappingURL=chunk-
|
|
6993
|
-
//# sourceMappingURL=chunk-
|
|
7130
|
+
//# sourceMappingURL=chunk-LGCREJMO.cjs.map
|
|
7131
|
+
//# sourceMappingURL=chunk-LGCREJMO.cjs.map
|