@mastra/memory 1.20.1 → 1.20.2
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 +48 -0
- package/dist/chunk-43FJOLKM.cjs +108 -0
- package/dist/chunk-43FJOLKM.cjs.map +1 -0
- package/dist/{chunk-3Q3LOVQP.cjs → chunk-D4J4XPGM.cjs} +2 -9
- package/dist/chunk-D4J4XPGM.cjs.map +1 -0
- package/dist/{chunk-VKRZ3O5X.js → chunk-LSJJAJAF.js} +3 -9
- package/dist/chunk-LSJJAJAF.js.map +1 -0
- package/dist/{chunk-P4BYW7GY.cjs → chunk-PTCSCRB6.cjs} +27 -27
- package/dist/{chunk-P4BYW7GY.cjs.map → chunk-PTCSCRB6.cjs.map} +1 -1
- package/dist/chunk-PZ5AY32C.js +9 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-Q7SFCCGT.cjs +11 -0
- package/dist/chunk-Q7SFCCGT.cjs.map +1 -0
- package/dist/{chunk-KMJQDCCZ.js → chunk-SXFOZU7K.js} +3 -3
- package/dist/{chunk-KMJQDCCZ.js.map → chunk-SXFOZU7K.js.map} +1 -1
- package/dist/chunk-WCGXQIEN.js +103 -0
- package/dist/chunk-WCGXQIEN.js.map +1 -0
- package/dist/constants-DVRTNEGY.js +3 -0
- package/dist/{constants-SPS7MR4D.js.map → constants-DVRTNEGY.js.map} +1 -1
- package/dist/{constants-D6W7OWCP.cjs → constants-JS5SS7GS.cjs} +8 -8
- package/dist/{constants-D6W7OWCP.cjs.map → constants-JS5SS7GS.cjs.map} +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +43 -30
- package/dist/docs/references/docs-memory-multi-user-threads.md +1 -1
- package/dist/docs/references/docs-memory-working-memory.md +27 -0
- package/dist/docs/references/reference-storage-libsql.md +6 -0
- package/dist/docs/references/reference-storage-mongodb.md +3 -0
- package/dist/docs/references/reference-storage-postgresql.md +3 -0
- package/dist/index.cjs +222 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +184 -72
- package/dist/index.js.map +1 -1
- package/dist/{observational-memory-TJFOX3YN.js → observational-memory-G52HNRHE.js} +4 -4
- package/dist/{observational-memory-TJFOX3YN.js.map → observational-memory-G52HNRHE.js.map} +1 -1
- package/dist/{observational-memory-CDLGZL67.cjs → observational-memory-SZF7GKTS.cjs} +31 -31
- package/dist/{observational-memory-CDLGZL67.cjs.map → observational-memory-SZF7GKTS.cjs.map} +1 -1
- package/dist/processors/index.cjs +29 -29
- package/dist/processors/index.js +2 -2
- package/dist/processors/observational-memory/index.d.ts +1 -1
- package/dist/processors/observational-memory/index.d.ts.map +1 -1
- package/dist/processors/working-memory-state/index.d.ts +2 -0
- package/dist/processors/working-memory-state/index.d.ts.map +1 -0
- package/dist/processors/working-memory-state/processor.d.ts +53 -0
- package/dist/processors/working-memory-state/processor.d.ts.map +1 -0
- package/dist/tools/working-memory.d.ts +22 -0
- package/dist/tools/working-memory.d.ts.map +1 -1
- package/dist/working-memory-state-J7ASTNXX.js +3 -0
- package/dist/working-memory-state-J7ASTNXX.js.map +1 -0
- package/dist/working-memory-state-Y2SCKCNU.cjs +24 -0
- package/dist/working-memory-state-Y2SCKCNU.cjs.map +1 -0
- package/package.json +8 -7
- package/dist/chunk-3Q3LOVQP.cjs.map +0 -1
- package/dist/chunk-VKRZ3O5X.js.map +0 -1
- package/dist/constants-SPS7MR4D.js +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# @mastra/memory
|
|
2
2
|
|
|
3
|
+
## 1.20.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Improved agent message, stream, and observational-memory type handling across the client SDKs and playground UI. ([#17208](https://github.com/mastra-ai/mastra/pull/17208))
|
|
8
|
+
|
|
9
|
+
- Added experimental `workingMemory.useStateSignals` opt-in. When set to `true`, working memory is delivered to the model as a `state` signal (via the new state-signals API) instead of being folded into the system message. `Memory` auto-attaches a `WorkingMemoryStateProcessor` that emits a signal with `stateId: 'working-memory'` and dedups via `cacheKey`. Subsequent turns emit unified-diff deltas against the prior snapshot when the diff is smaller than the snapshot (markdown mode only); schema mode and the fallback path always emit a full snapshot. The working-memory tool is registered as `setWorkingMemory` instead of `updateWorkingMemory` under this opt-in so legacy persistence/prompt strip filters naturally bypass it. The default (`false`) preserves the existing system-message behavior. `useStateSignals` is not supported with template working memory `version: 'vnext'`. ([#17497](https://github.com/mastra-ai/mastra/pull/17497))
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { Memory } from '@mastra/memory';
|
|
13
|
+
|
|
14
|
+
const memory = new Memory({
|
|
15
|
+
options: {
|
|
16
|
+
workingMemory: {
|
|
17
|
+
enabled: true,
|
|
18
|
+
useStateSignals: true,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [[`c973db4`](https://github.com/mastra-ai/mastra/commit/c973db428df1b564ff0c35d4b2a90e8f4f1e13fd), [`552285e`](https://github.com/mastra-ai/mastra/commit/552285e5af43cfc680a0972032cab8de8776c6a0), [`77e686c`](https://github.com/mastra-ai/mastra/commit/77e686c264e493e99ae5024e4dfe3ea5d5a09718), [`ece8dba`](https://github.com/mastra-ai/mastra/commit/ece8dba7ec1a5089eee8c33167cd762bfa91e509), [`e751af2`](https://github.com/mastra-ai/mastra/commit/e751af219433fbf4c7035b2d771b4c9ec8813b05), [`e2a8380`](https://github.com/mastra-ai/mastra/commit/e2a838017a7657850404c1e94c70d79ffdc6f14a), [`be3f1cd`](https://github.com/mastra-ai/mastra/commit/be3f1cd81f0e2a649e8eac15a024d542d814aef8), [`a34d9db`](https://github.com/mastra-ai/mastra/commit/a34d9dbc39fedb722f271318e9355ecee70489ab)]:
|
|
25
|
+
- @mastra/core@1.39.0
|
|
26
|
+
|
|
27
|
+
## 1.20.2-alpha.0
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- Improved agent message, stream, and observational-memory type handling across the client SDKs and playground UI. ([#17208](https://github.com/mastra-ai/mastra/pull/17208))
|
|
32
|
+
|
|
33
|
+
- Added experimental `workingMemory.useStateSignals` opt-in. When set to `true`, working memory is delivered to the model as a `state` signal (via the new state-signals API) instead of being folded into the system message. `Memory` auto-attaches a `WorkingMemoryStateProcessor` that emits a signal with `stateId: 'working-memory'` and dedups via `cacheKey`. Subsequent turns emit unified-diff deltas against the prior snapshot when the diff is smaller than the snapshot (markdown mode only); schema mode and the fallback path always emit a full snapshot. The working-memory tool is registered as `setWorkingMemory` instead of `updateWorkingMemory` under this opt-in so legacy persistence/prompt strip filters naturally bypass it. The default (`false`) preserves the existing system-message behavior. `useStateSignals` is not supported with template working memory `version: 'vnext'`. ([#17497](https://github.com/mastra-ai/mastra/pull/17497))
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { Memory } from '@mastra/memory';
|
|
37
|
+
|
|
38
|
+
const memory = new Memory({
|
|
39
|
+
options: {
|
|
40
|
+
workingMemory: {
|
|
41
|
+
enabled: true,
|
|
42
|
+
useStateSignals: true,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- Updated dependencies [[`c973db4`](https://github.com/mastra-ai/mastra/commit/c973db428df1b564ff0c35d4b2a90e8f4f1e13fd), [`552285e`](https://github.com/mastra-ai/mastra/commit/552285e5af43cfc680a0972032cab8de8776c6a0), [`77e686c`](https://github.com/mastra-ai/mastra/commit/77e686c264e493e99ae5024e4dfe3ea5d5a09718), [`ece8dba`](https://github.com/mastra-ai/mastra/commit/ece8dba7ec1a5089eee8c33167cd762bfa91e509), [`e751af2`](https://github.com/mastra-ai/mastra/commit/e751af219433fbf4c7035b2d771b4c9ec8813b05), [`e2a8380`](https://github.com/mastra-ai/mastra/commit/e2a838017a7657850404c1e94c70d79ffdc6f14a), [`be3f1cd`](https://github.com/mastra-ai/mastra/commit/be3f1cd81f0e2a649e8eac15a024d542d814aef8), [`a34d9db`](https://github.com/mastra-ai/mastra/commit/a34d9dbc39fedb722f271318e9355ecee70489ab)]:
|
|
49
|
+
- @mastra/core@1.39.0-alpha.0
|
|
50
|
+
|
|
3
51
|
## 1.20.1
|
|
4
52
|
|
|
5
53
|
### Patch Changes
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var crypto = require('crypto');
|
|
4
|
+
var diff = require('diff');
|
|
5
|
+
|
|
6
|
+
// src/processors/working-memory-state/processor.ts
|
|
7
|
+
var WORKING_MEMORY_STATE_ID = "working-memory";
|
|
8
|
+
var WORKING_MEMORY_STATE_PROCESSOR_ID = "working-memory-state";
|
|
9
|
+
var WorkingMemoryStateProcessor = class {
|
|
10
|
+
constructor(memory, memoryConfig) {
|
|
11
|
+
this.memory = memory;
|
|
12
|
+
this.memoryConfig = memoryConfig;
|
|
13
|
+
}
|
|
14
|
+
memory;
|
|
15
|
+
memoryConfig;
|
|
16
|
+
id = WORKING_MEMORY_STATE_PROCESSOR_ID;
|
|
17
|
+
stateId = WORKING_MEMORY_STATE_ID;
|
|
18
|
+
async computeStateSignal(args) {
|
|
19
|
+
const template = await this.memory.getWorkingMemoryTemplate({ memoryConfig: this.memoryConfig });
|
|
20
|
+
if (!template) return;
|
|
21
|
+
const data = await this.memory.getWorkingMemory({
|
|
22
|
+
threadId: args.threadId,
|
|
23
|
+
resourceId: args.resourceId,
|
|
24
|
+
memoryConfig: this.memoryConfig
|
|
25
|
+
});
|
|
26
|
+
const contents = data?.trim();
|
|
27
|
+
if (!contents) return;
|
|
28
|
+
const cacheKey = stableWorkingMemoryCacheKey({ format: template.format, data: contents });
|
|
29
|
+
const shouldMakeSnapshot = !args.contextWindow.hasSnapshot;
|
|
30
|
+
if (args.tracking?.currentCacheKey === cacheKey && !shouldMakeSnapshot) return;
|
|
31
|
+
const mergedConfig = this.memory.getMergedThreadConfig(this.memoryConfig);
|
|
32
|
+
const scope = mergedConfig.workingMemory?.scope ?? "resource";
|
|
33
|
+
const deltaCandidate = template.format === "markdown" && !shouldMakeSnapshot ? buildMarkdownDelta({
|
|
34
|
+
lastSnapshot: args.lastSnapshot,
|
|
35
|
+
deltasSinceSnapshot: args.deltasSinceSnapshot,
|
|
36
|
+
nextContents: contents
|
|
37
|
+
}) : void 0;
|
|
38
|
+
if (deltaCandidate) {
|
|
39
|
+
return {
|
|
40
|
+
id: WORKING_MEMORY_STATE_ID,
|
|
41
|
+
mode: "delta",
|
|
42
|
+
cacheKey,
|
|
43
|
+
tagName: "working-memory",
|
|
44
|
+
contents: deltaCandidate.contents,
|
|
45
|
+
delta: deltaCandidate.contents,
|
|
46
|
+
// Stash the full post-edit text on the signal so the next turn can
|
|
47
|
+
// diff against the most recently emitted state instead of the older
|
|
48
|
+
// snapshot. Invisible to the model.
|
|
49
|
+
value: contents,
|
|
50
|
+
attributes: {
|
|
51
|
+
format: template.format,
|
|
52
|
+
scope,
|
|
53
|
+
patch: "unified-diff"
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
id: WORKING_MEMORY_STATE_ID,
|
|
59
|
+
mode: "snapshot",
|
|
60
|
+
cacheKey,
|
|
61
|
+
tagName: "working-memory",
|
|
62
|
+
contents,
|
|
63
|
+
// Mirror contents in value so the first delta after a snapshot has a
|
|
64
|
+
// typed prior-state to diff against without falling back to contents.
|
|
65
|
+
value: contents,
|
|
66
|
+
attributes: {
|
|
67
|
+
format: template.format,
|
|
68
|
+
scope
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
function stableWorkingMemoryCacheKey(input) {
|
|
74
|
+
const hash = crypto.createHash("sha256");
|
|
75
|
+
hash.update(input.format);
|
|
76
|
+
hash.update("\0");
|
|
77
|
+
hash.update(input.data ?? "");
|
|
78
|
+
return `sha256:${hash.digest("hex")}`;
|
|
79
|
+
}
|
|
80
|
+
function buildMarkdownDelta(args) {
|
|
81
|
+
const { lastSnapshot, deltasSinceSnapshot, nextContents } = args;
|
|
82
|
+
const latestDelta = deltasSinceSnapshot.at(-1);
|
|
83
|
+
const prior = pickStringValue(readSignalValue(latestDelta)) ?? pickStringValue(readSignalValue(lastSnapshot)) ?? (typeof lastSnapshot?.contents === "string" ? lastSnapshot.contents : void 0);
|
|
84
|
+
if (!prior) return;
|
|
85
|
+
const patch = renderHunksOnly(prior, nextContents);
|
|
86
|
+
return { contents: patch };
|
|
87
|
+
}
|
|
88
|
+
function pickStringValue(value) {
|
|
89
|
+
return typeof value === "string" ? value : void 0;
|
|
90
|
+
}
|
|
91
|
+
function readSignalValue(signal) {
|
|
92
|
+
return signal?.metadata?.value;
|
|
93
|
+
}
|
|
94
|
+
function renderHunksOnly(prior, next) {
|
|
95
|
+
const { hunks } = diff.structuredPatch("", "", prior, next, "", "", { context: 0 });
|
|
96
|
+
return hunks.map((hunk) => {
|
|
97
|
+
const header = `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`;
|
|
98
|
+
const lines = hunk.lines.filter((line) => !line.startsWith("\"));
|
|
99
|
+
return [header, ...lines].join("\n");
|
|
100
|
+
}).join("\n");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
exports.WORKING_MEMORY_STATE_ID = WORKING_MEMORY_STATE_ID;
|
|
104
|
+
exports.WORKING_MEMORY_STATE_PROCESSOR_ID = WORKING_MEMORY_STATE_PROCESSOR_ID;
|
|
105
|
+
exports.WorkingMemoryStateProcessor = WorkingMemoryStateProcessor;
|
|
106
|
+
exports.stableWorkingMemoryCacheKey = stableWorkingMemoryCacheKey;
|
|
107
|
+
//# sourceMappingURL=chunk-43FJOLKM.cjs.map
|
|
108
|
+
//# sourceMappingURL=chunk-43FJOLKM.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/processors/working-memory-state/processor.ts"],"names":["createHash","structuredPatch"],"mappings":"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","file":"chunk-43FJOLKM.cjs","sourcesContent":["/**\n * WorkingMemoryStateProcessor\n *\n * Experimental: delivers working memory to the model as a state signal instead\n * of folding it into the system message. Storage and the `setWorkingMemory`\n * tool are unchanged — this processor only changes the delivery path.\n *\n * Pattern matches `BrowserContextProcessor` in `@mastra/core/browser`:\n * - `stateId` namespaces the state lane on the thread.\n * - `cacheKey` is derived from the rendered payload so dedup is automatic.\n * - `contextWindow.hasSnapshot` re-injection ensures the model still sees the\n * current snapshot after older messages drop out of the window.\n *\n * Delta emission (markdown mode only): when a prior snapshot exists in the\n * context window, the processor emits a unified-diff delta against that\n * snapshot's contents. Schema mode and the snapshot fallback always emit a\n * full snapshot.\n *\n * @example\n * ```ts\n * new Memory({\n * options: {\n * workingMemory: {\n * enabled: true,\n * template: '...',\n * useStateSignals: true, // auto-attaches this processor\n * },\n * },\n * });\n * ```\n */\n\nimport { createHash } from 'node:crypto';\n\nimport type { MastraMemory, MemoryConfigInternal, WorkingMemoryTemplate } from '@mastra/core/memory';\nimport type {\n ComputeStateSignalArgs,\n ComputeStateSignalResult,\n Processor,\n ProcessorActiveStateSignal,\n} from '@mastra/core/processors';\nimport { structuredPatch } from 'diff';\n\nexport const WORKING_MEMORY_STATE_ID = 'working-memory';\nexport const WORKING_MEMORY_STATE_PROCESSOR_ID = 'working-memory-state';\n\nexport class WorkingMemoryStateProcessor implements Processor<typeof WORKING_MEMORY_STATE_PROCESSOR_ID> {\n readonly id = WORKING_MEMORY_STATE_PROCESSOR_ID;\n readonly stateId = WORKING_MEMORY_STATE_ID;\n\n constructor(\n private readonly memory: MastraMemory,\n private readonly memoryConfig?: MemoryConfigInternal,\n ) {}\n\n async computeStateSignal(args: ComputeStateSignalArgs): Promise<ComputeStateSignalResult> {\n const template = await this.memory.getWorkingMemoryTemplate({ memoryConfig: this.memoryConfig });\n if (!template) return;\n\n const data = await this.memory.getWorkingMemory({\n threadId: args.threadId,\n resourceId: args.resourceId,\n memoryConfig: this.memoryConfig,\n });\n\n // Nothing stored yet — no state to broadcast. The setWorkingMemory tool\n // description tells the model the expected shape; the signal carries state.\n const contents = data?.trim();\n if (!contents) return;\n\n const cacheKey = stableWorkingMemoryCacheKey({ format: template.format, data: contents });\n const shouldMakeSnapshot = !args.contextWindow.hasSnapshot;\n if (args.tracking?.currentCacheKey === cacheKey && !shouldMakeSnapshot) return;\n\n const mergedConfig = this.memory.getMergedThreadConfig(this.memoryConfig);\n const scope = mergedConfig.workingMemory?.scope ?? 'resource';\n\n const deltaCandidate =\n template.format === 'markdown' && !shouldMakeSnapshot\n ? buildMarkdownDelta({\n lastSnapshot: args.lastSnapshot,\n deltasSinceSnapshot: args.deltasSinceSnapshot,\n nextContents: contents,\n })\n : undefined;\n\n if (deltaCandidate) {\n return {\n id: WORKING_MEMORY_STATE_ID,\n mode: 'delta',\n cacheKey,\n tagName: 'working-memory',\n contents: deltaCandidate.contents,\n delta: deltaCandidate.contents,\n // Stash the full post-edit text on the signal so the next turn can\n // diff against the most recently emitted state instead of the older\n // snapshot. Invisible to the model.\n value: contents,\n attributes: {\n format: template.format,\n scope,\n patch: 'unified-diff',\n },\n };\n }\n\n return {\n id: WORKING_MEMORY_STATE_ID,\n mode: 'snapshot',\n cacheKey,\n tagName: 'working-memory',\n contents,\n // Mirror contents in value so the first delta after a snapshot has a\n // typed prior-state to diff against without falling back to contents.\n value: contents,\n attributes: {\n format: template.format,\n scope,\n },\n };\n }\n}\n\n/**\n * Stable cache key for the rendered working memory payload. Returns a SHA-256\n * digest so dedup metadata stays compact regardless of payload size (working\n * memory blobs can grow arbitrarily long).\n */\nexport function stableWorkingMemoryCacheKey(input: {\n format: WorkingMemoryTemplate['format'];\n data: string | null;\n}): string {\n const hash = createHash('sha256');\n hash.update(input.format);\n hash.update('\\0');\n hash.update(input.data ?? '');\n return `sha256:${hash.digest('hex')}`;\n}\n\n/**\n * Build a unified-diff delta against the most recently emitted state. Prefers\n * the latest delta's `value` (the post-edit full text) when available, falling\n * back to the snapshot's `value` and finally the snapshot's `contents`. This\n * keeps deltas incremental (B→C) instead of cumulative against a stale\n * snapshot (A→C), which matters when many small edits land between snapshots.\n *\n * Returns undefined when:\n * - there's no prior state to diff against\n * - the prior state isn't a plain string (multimodal signal)\n *\n * In either case the caller falls back to emitting a full snapshot.\n */\nfunction buildMarkdownDelta(args: {\n lastSnapshot?: ProcessorActiveStateSignal;\n deltasSinceSnapshot: ProcessorActiveStateSignal[];\n nextContents: string;\n}): { contents: string } | undefined {\n const { lastSnapshot, deltasSinceSnapshot, nextContents } = args;\n\n // `value` is stored on the persisted signal's metadata (see applyStateSignal\n // in @mastra/core/agent/state-signals). Read from there to recover the\n // post-edit full text from the most recently emitted state.\n const latestDelta = deltasSinceSnapshot.at(-1);\n const prior =\n pickStringValue(readSignalValue(latestDelta)) ??\n pickStringValue(readSignalValue(lastSnapshot)) ??\n (typeof lastSnapshot?.contents === 'string' ? lastSnapshot.contents : undefined);\n ('');\n if (!prior) return;\n\n const patch = renderHunksOnly(prior, nextContents);\n\n return { contents: patch };\n}\n\nfunction pickStringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction readSignalValue(signal: ProcessorActiveStateSignal | undefined): unknown {\n return (signal?.metadata as { value?: unknown } | undefined)?.value;\n}\n\n/**\n * Render a unified-diff-style patch body containing only `@@` hunks and their\n * lines — dropping the filename preamble (`Index:` / `===` / `---` / `+++`)\n * that `createPatch` emits and the `\` trailer.\n * The preamble exists for tooling like `patch -p1` to know which file to\n * apply to; we only ever diff a single working-memory blob. The newline\n * trailer is semantically meaningless to the model and adds noise to the\n * state signal.\n */\nfunction renderHunksOnly(prior: string, next: string): string {\n const { hunks } = structuredPatch('', '', prior, next, '', '', { context: 0 });\n return hunks\n .map(hunk => {\n const header = `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`;\n const lines = hunk.lines.filter(line => !line.startsWith('\\\'));\n return [header, ...lines].join('\\n');\n })\n .join('\\n');\n}\n"]}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __export = (target, all) => {
|
|
5
|
-
for (var name in all)
|
|
6
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
7
|
-
};
|
|
8
|
-
|
|
9
3
|
// src/processors/observational-memory/constants.ts
|
|
10
4
|
var OBSERVATIONAL_MEMORY_DEFAULTS = {
|
|
11
5
|
observation: {
|
|
@@ -113,6 +107,5 @@ exports.OBSERVATION_CONTEXT_INSTRUCTIONS = OBSERVATION_CONTEXT_INSTRUCTIONS;
|
|
|
113
107
|
exports.OBSERVATION_CONTEXT_PROMPT = OBSERVATION_CONTEXT_PROMPT;
|
|
114
108
|
exports.OBSERVATION_CONTINUATION_HINT = OBSERVATION_CONTINUATION_HINT;
|
|
115
109
|
exports.OBSERVATION_RETRIEVAL_INSTRUCTIONS = OBSERVATION_RETRIEVAL_INSTRUCTIONS;
|
|
116
|
-
|
|
117
|
-
//# sourceMappingURL=chunk-
|
|
118
|
-
//# sourceMappingURL=chunk-3Q3LOVQP.cjs.map
|
|
110
|
+
//# sourceMappingURL=chunk-D4J4XPGM.cjs.map
|
|
111
|
+
//# sourceMappingURL=chunk-D4J4XPGM.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/processors/observational-memory/constants.ts"],"names":[],"mappings":";;;AAGO,IAAM,6BAAA,GAAgC;AAAA,EAC3C,WAAA,EAAa;AAAA,IACX,KAAA,EAAO,yBAAA;AAAA,IACP,aAAA,EAAe,GAAA;AAAA,IACf,aAAA,EAAe;AAAA,MACb,WAAA,EAAa,GAAA;AAAA,MACb,eAAA,EAAiB;AAAA,KACnB;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,MAAA,EAAQ;AAAA,QACN,cAAA,EAAgB;AAAA,UACd,cAAA,EAAgB;AAAA;AAClB;AACF,KACF;AAAA,IACA,iBAAA,EAAmB,GAAA;AAAA;AAAA,IAEnB,YAAA,EAAc,GAAA;AAAA;AAAA,IACd,gBAAA,EAAkB;AAAA;AAAA,GACpB;AAAA,EACA,UAAA,EAAY;AAAA,IACV,KAAA,EAAO,yBAAA;AAAA,IACP,iBAAA,EAAmB,GAAA;AAAA,IACnB,aAAA,EAAe;AAAA,MACb,WAAA,EAAa,CAAA;AAAA;AAAA,MACb,eAAA,EAAiB;AAAA,KACnB;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,MAAA,EAAQ;AAAA,QACN,cAAA,EAAgB;AAAA,UACd,cAAA,EAAgB;AAAA;AAClB;AACF,KACF;AAAA;AAAA,IAEA,gBAAA,EAAkB;AAAA;AAAA;AAEtB;AAOO,IAAM,6BAAA,GAAgC,CAAA;;AAAA;;AAAA;;AAAA,wEAAA;AAatC,IAAM,0BAAA,GAA6B,CAAA,2FAAA;AAMnC,IAAM,gCAAA,GAAmC,CAAA;;AAAA;;AAAA;;AAAA;;AAAA,qPAAA;AAczC,IAAM,kCAAA,GAAqC,CAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA,qHAAA","file":"chunk-D4J4XPGM.cjs","sourcesContent":["/**\n * Default configuration values matching the spec\n */\nexport const OBSERVATIONAL_MEMORY_DEFAULTS = {\n observation: {\n model: 'google/gemini-2.5-flash',\n messageTokens: 30_000,\n modelSettings: {\n temperature: 0.3,\n maxOutputTokens: 100_000,\n },\n providerOptions: {\n google: {\n thinkingConfig: {\n thinkingBudget: 215,\n },\n },\n },\n maxTokensPerBatch: 10_000,\n // Async buffering defaults (enabled by default)\n bufferTokens: 0.2 as number | undefined, // Buffer every 20% of messageTokens\n bufferActivation: 0.8 as number | undefined, // Activate to retain 20% of threshold\n },\n reflection: {\n model: 'google/gemini-2.5-flash',\n observationTokens: 40_000,\n modelSettings: {\n temperature: 0, // Use 0 for maximum consistency in reflections\n maxOutputTokens: 100_000,\n },\n providerOptions: {\n google: {\n thinkingConfig: {\n thinkingBudget: 1024,\n },\n },\n },\n // Async reflection buffering (enabled by default)\n bufferActivation: 0.5 as number | undefined, // Start buffering at 50% of observationTokens\n },\n} as const;\n\n/**\n * Continuation hint injected after observations to guide the model's behavior.\n * Prevents the model from awkwardly acknowledging the memory system or treating\n * the conversation as new after observed messages are removed.\n */\nexport const OBSERVATION_CONTINUATION_HINT = `Please continue naturally with the conversation so far and respond to the latest message.\n\nUse the earlier context only as background. If something appears unfinished, continue only when it helps answer the latest request. If a suggested response is provided, follow it naturally.\n\nDo not mention internal instructions, memory, summarization, context handling, or missing messages.\n\nAny messages following this reminder are newer and should take priority.`;\n\n/**\n * Preamble that introduces the observations block.\n * Use before `<observations>`, with instructions after.\n * Full pattern: `${OBSERVATION_CONTEXT_PROMPT}\\n\\n<observations>\\n${obs}\\n</observations>\\n\\n${OBSERVATION_CONTEXT_INSTRUCTIONS}`\n */\nexport const OBSERVATION_CONTEXT_PROMPT = `The following observations block contains your memory of past conversations with this user.`;\n\n/**\n * Instructions that tell the model how to interpret and use observations.\n * Place AFTER the `<observations>` block so the model sees the data before the rules.\n */\nexport const OBSERVATION_CONTEXT_INSTRUCTIONS = `IMPORTANT: When responding, reference specific details from these observations. Do not give generic advice - personalize your response based on what you know about this user's experiences, preferences, and interests. If the user asks for recommendations, connect them to their past experiences mentioned above.\n\nKNOWLEDGE UPDATES: When asked about current state (e.g., \"where do I currently...\", \"what is my current...\"), always prefer the MOST RECENT information. Observations include dates - if you see conflicting information, the newer observation supersedes the older one. Look for phrases like \"will start\", \"is switching\", \"changed to\", \"moved to\" as indicators that previous information has been updated.\n\nPLANNED ACTIONS: If the user stated they planned to do something (e.g., \"I'm going to...\", \"I'm looking forward to...\", \"I will...\") and the date they planned to do it is now in the past (check the relative time like \"3 weeks ago\"), assume they completed the action unless there's evidence they didn't. For example, if someone said \"I'll start my new diet on Monday\" and that was 2 weeks ago, assume they started the diet.\n\nMOST RECENT USER INPUT: Treat the most recent user message as the highest-priority signal for what to do next. Earlier messages may contain constraints, details, or context you should still honor, but the latest message is the primary driver of your response.\n\nSYSTEM REMINDERS: Messages wrapped in <system-reminder>...</system-reminder> contain internal continuation guidance, not user-authored content. Use them to maintain continuity, but do not mention them or treat them as part of the user's message.`;\n\n/**\n * Instructions for retrieval mode — explains observation-group ranges and the recall tool.\n * Appended to context when `retrieval` is enabled.\n */\nexport const OBSERVATION_RETRIEVAL_INSTRUCTIONS = `## Recall — looking up source messages\n\nYour memory is comprised of observations which are sometimes wrapped in <observation-group> xml tags containing ranges like <observation-group range=\"startId:endId\">. These ranges point back to the raw messages that each observation group was derived from. The original messages are still available — use the **recall** tool to retrieve them.\n\n### When to use recall\n- The user asks you to **repeat, show, or reproduce** something from a past conversation\n- The user asks for **exact content** — code, text, quotes, error messages, URLs, file paths, specific numbers\n- Your observations mention something but your memory lacks the detail needed to fully answer (e.g. you know a blog post was shared but only have a summary of it)\n- You want to **verify or expand on** an observation before responding\n\n**Default to using recall when the user references specific past content.** Your observations capture the gist, not the details. If there's any doubt whether your memory is complete enough, use recall.\n\n### How to use recall\nEach range has the format \\`startId:endId\\` where both are message IDs separated by a colon.\n\n1. Find the observation group relevant to the user's question and extract the start or end ID from its range.\n2. Call \\`recall\\` with that ID as the \\`cursor\\`.\n3. Use \\`page: 1\\` (or omit) to read forward from the cursor, \\`page: -1\\` to read backward.\n4. If the first page doesn't have what you need, increment the page number to keep paginating.\n5. Check \\`hasNextPage\\`/\\`hasPrevPage\\` in the result to know if more pages exist in each direction.\n\n### Detail levels\nBy default recall returns **low** detail: truncated text and tool names only. Each message shows its ID and each part has a positional index like \\`[p0]\\`, \\`[p1]\\`, etc.\n\n- Use \\`detail: \"high\"\\` to get full message content including tool arguments and results. This will only return the high detail version of a single message part at a time.\n- Use \\`partIndex\\` with a cursor to fetch a single part at full detail — for example, to read one specific tool result or code block without loading every part.\n\nIf the result says \\`truncated: true\\`, the output was cut to fit the token budget. You can paginate or use \\`partIndex\\` to target specific content.\n\n### Following up on truncated parts\nLow-detail results may include truncation hints like:\n\\`[truncated — call recall cursor=\"...\" partIndex=N detail=\"high\" for full content]\\`\n\n**When you see these hints and need the full content, make the exact call described in the hint.** This is the normal workflow: first recall at low detail to scan, then drill into specific parts at high detail. Do not stop at the low-detail result if the user asked for exact content.\n\n### When recall is NOT needed\n- The user is asking for a high-level summary and your observations already cover it\n- The question is about general preferences or facts that don't require source text\n- There is no relevant range in your observations for the topic\n\nObservation groups with range IDs and your recall tool allows you to think back and remember details you're fuzzy on.`;\n"]}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __export = (target, all) => {
|
|
3
|
-
for (var name in all)
|
|
4
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
-
};
|
|
6
|
-
|
|
7
1
|
// src/processors/observational-memory/constants.ts
|
|
8
2
|
var OBSERVATIONAL_MEMORY_DEFAULTS = {
|
|
9
3
|
observation: {
|
|
@@ -106,6 +100,6 @@ Low-detail results may include truncation hints like:
|
|
|
106
100
|
|
|
107
101
|
Observation groups with range IDs and your recall tool allows you to think back and remember details you're fuzzy on.`;
|
|
108
102
|
|
|
109
|
-
export { OBSERVATIONAL_MEMORY_DEFAULTS, OBSERVATION_CONTEXT_INSTRUCTIONS, OBSERVATION_CONTEXT_PROMPT, OBSERVATION_CONTINUATION_HINT, OBSERVATION_RETRIEVAL_INSTRUCTIONS
|
|
110
|
-
//# sourceMappingURL=chunk-
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
103
|
+
export { OBSERVATIONAL_MEMORY_DEFAULTS, OBSERVATION_CONTEXT_INSTRUCTIONS, OBSERVATION_CONTEXT_PROMPT, OBSERVATION_CONTINUATION_HINT, OBSERVATION_RETRIEVAL_INSTRUCTIONS };
|
|
104
|
+
//# sourceMappingURL=chunk-LSJJAJAF.js.map
|
|
105
|
+
//# sourceMappingURL=chunk-LSJJAJAF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/processors/observational-memory/constants.ts"],"names":[],"mappings":";AAGO,IAAM,6BAAA,GAAgC;AAAA,EAC3C,WAAA,EAAa;AAAA,IACX,KAAA,EAAO,yBAAA;AAAA,IACP,aAAA,EAAe,GAAA;AAAA,IACf,aAAA,EAAe;AAAA,MACb,WAAA,EAAa,GAAA;AAAA,MACb,eAAA,EAAiB;AAAA,KACnB;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,MAAA,EAAQ;AAAA,QACN,cAAA,EAAgB;AAAA,UACd,cAAA,EAAgB;AAAA;AAClB;AACF,KACF;AAAA,IACA,iBAAA,EAAmB,GAAA;AAAA;AAAA,IAEnB,YAAA,EAAc,GAAA;AAAA;AAAA,IACd,gBAAA,EAAkB;AAAA;AAAA,GACpB;AAAA,EACA,UAAA,EAAY;AAAA,IACV,KAAA,EAAO,yBAAA;AAAA,IACP,iBAAA,EAAmB,GAAA;AAAA,IACnB,aAAA,EAAe;AAAA,MACb,WAAA,EAAa,CAAA;AAAA;AAAA,MACb,eAAA,EAAiB;AAAA,KACnB;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,MAAA,EAAQ;AAAA,QACN,cAAA,EAAgB;AAAA,UACd,cAAA,EAAgB;AAAA;AAClB;AACF,KACF;AAAA;AAAA,IAEA,gBAAA,EAAkB;AAAA;AAAA;AAEtB;AAOO,IAAM,6BAAA,GAAgC,CAAA;;AAAA;;AAAA;;AAAA,wEAAA;AAatC,IAAM,0BAAA,GAA6B,CAAA,2FAAA;AAMnC,IAAM,gCAAA,GAAmC,CAAA;;AAAA;;AAAA;;AAAA;;AAAA,qPAAA;AAczC,IAAM,kCAAA,GAAqC,CAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA,qHAAA","file":"chunk-LSJJAJAF.js","sourcesContent":["/**\n * Default configuration values matching the spec\n */\nexport const OBSERVATIONAL_MEMORY_DEFAULTS = {\n observation: {\n model: 'google/gemini-2.5-flash',\n messageTokens: 30_000,\n modelSettings: {\n temperature: 0.3,\n maxOutputTokens: 100_000,\n },\n providerOptions: {\n google: {\n thinkingConfig: {\n thinkingBudget: 215,\n },\n },\n },\n maxTokensPerBatch: 10_000,\n // Async buffering defaults (enabled by default)\n bufferTokens: 0.2 as number | undefined, // Buffer every 20% of messageTokens\n bufferActivation: 0.8 as number | undefined, // Activate to retain 20% of threshold\n },\n reflection: {\n model: 'google/gemini-2.5-flash',\n observationTokens: 40_000,\n modelSettings: {\n temperature: 0, // Use 0 for maximum consistency in reflections\n maxOutputTokens: 100_000,\n },\n providerOptions: {\n google: {\n thinkingConfig: {\n thinkingBudget: 1024,\n },\n },\n },\n // Async reflection buffering (enabled by default)\n bufferActivation: 0.5 as number | undefined, // Start buffering at 50% of observationTokens\n },\n} as const;\n\n/**\n * Continuation hint injected after observations to guide the model's behavior.\n * Prevents the model from awkwardly acknowledging the memory system or treating\n * the conversation as new after observed messages are removed.\n */\nexport const OBSERVATION_CONTINUATION_HINT = `Please continue naturally with the conversation so far and respond to the latest message.\n\nUse the earlier context only as background. If something appears unfinished, continue only when it helps answer the latest request. If a suggested response is provided, follow it naturally.\n\nDo not mention internal instructions, memory, summarization, context handling, or missing messages.\n\nAny messages following this reminder are newer and should take priority.`;\n\n/**\n * Preamble that introduces the observations block.\n * Use before `<observations>`, with instructions after.\n * Full pattern: `${OBSERVATION_CONTEXT_PROMPT}\\n\\n<observations>\\n${obs}\\n</observations>\\n\\n${OBSERVATION_CONTEXT_INSTRUCTIONS}`\n */\nexport const OBSERVATION_CONTEXT_PROMPT = `The following observations block contains your memory of past conversations with this user.`;\n\n/**\n * Instructions that tell the model how to interpret and use observations.\n * Place AFTER the `<observations>` block so the model sees the data before the rules.\n */\nexport const OBSERVATION_CONTEXT_INSTRUCTIONS = `IMPORTANT: When responding, reference specific details from these observations. Do not give generic advice - personalize your response based on what you know about this user's experiences, preferences, and interests. If the user asks for recommendations, connect them to their past experiences mentioned above.\n\nKNOWLEDGE UPDATES: When asked about current state (e.g., \"where do I currently...\", \"what is my current...\"), always prefer the MOST RECENT information. Observations include dates - if you see conflicting information, the newer observation supersedes the older one. Look for phrases like \"will start\", \"is switching\", \"changed to\", \"moved to\" as indicators that previous information has been updated.\n\nPLANNED ACTIONS: If the user stated they planned to do something (e.g., \"I'm going to...\", \"I'm looking forward to...\", \"I will...\") and the date they planned to do it is now in the past (check the relative time like \"3 weeks ago\"), assume they completed the action unless there's evidence they didn't. For example, if someone said \"I'll start my new diet on Monday\" and that was 2 weeks ago, assume they started the diet.\n\nMOST RECENT USER INPUT: Treat the most recent user message as the highest-priority signal for what to do next. Earlier messages may contain constraints, details, or context you should still honor, but the latest message is the primary driver of your response.\n\nSYSTEM REMINDERS: Messages wrapped in <system-reminder>...</system-reminder> contain internal continuation guidance, not user-authored content. Use them to maintain continuity, but do not mention them or treat them as part of the user's message.`;\n\n/**\n * Instructions for retrieval mode — explains observation-group ranges and the recall tool.\n * Appended to context when `retrieval` is enabled.\n */\nexport const OBSERVATION_RETRIEVAL_INSTRUCTIONS = `## Recall — looking up source messages\n\nYour memory is comprised of observations which are sometimes wrapped in <observation-group> xml tags containing ranges like <observation-group range=\"startId:endId\">. These ranges point back to the raw messages that each observation group was derived from. The original messages are still available — use the **recall** tool to retrieve them.\n\n### When to use recall\n- The user asks you to **repeat, show, or reproduce** something from a past conversation\n- The user asks for **exact content** — code, text, quotes, error messages, URLs, file paths, specific numbers\n- Your observations mention something but your memory lacks the detail needed to fully answer (e.g. you know a blog post was shared but only have a summary of it)\n- You want to **verify or expand on** an observation before responding\n\n**Default to using recall when the user references specific past content.** Your observations capture the gist, not the details. If there's any doubt whether your memory is complete enough, use recall.\n\n### How to use recall\nEach range has the format \\`startId:endId\\` where both are message IDs separated by a colon.\n\n1. Find the observation group relevant to the user's question and extract the start or end ID from its range.\n2. Call \\`recall\\` with that ID as the \\`cursor\\`.\n3. Use \\`page: 1\\` (or omit) to read forward from the cursor, \\`page: -1\\` to read backward.\n4. If the first page doesn't have what you need, increment the page number to keep paginating.\n5. Check \\`hasNextPage\\`/\\`hasPrevPage\\` in the result to know if more pages exist in each direction.\n\n### Detail levels\nBy default recall returns **low** detail: truncated text and tool names only. Each message shows its ID and each part has a positional index like \\`[p0]\\`, \\`[p1]\\`, etc.\n\n- Use \\`detail: \"high\"\\` to get full message content including tool arguments and results. This will only return the high detail version of a single message part at a time.\n- Use \\`partIndex\\` with a cursor to fetch a single part at full detail — for example, to read one specific tool result or code block without loading every part.\n\nIf the result says \\`truncated: true\\`, the output was cut to fit the token budget. You can paginate or use \\`partIndex\\` to target specific content.\n\n### Following up on truncated parts\nLow-detail results may include truncation hints like:\n\\`[truncated — call recall cursor=\"...\" partIndex=N detail=\"high\" for full content]\\`\n\n**When you see these hints and need the full content, make the exact call described in the hint.** This is the normal workflow: first recall at low detail to scan, then drill into specific parts at high detail. Do not stop at the low-detail result if the user asked for exact content.\n\n### When recall is NOT needed\n- The user is asking for a high-level summary and your observations already cover it\n- The question is about general preferences or facts that don't require source text\n- There is no relevant range in your observations for the topic\n\nObservation groups with range IDs and your recall tool allows you to think back and remember details you're fuzzy on.`;\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkD4J4XPGM_cjs = require('./chunk-D4J4XPGM.cjs');
|
|
4
4
|
var features = require('@mastra/core/features');
|
|
5
5
|
var llm = require('@mastra/core/llm');
|
|
6
6
|
var memory = require('@mastra/core/memory');
|
|
@@ -1835,7 +1835,7 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
|
|
|
1835
1835
|
}
|
|
1836
1836
|
}
|
|
1837
1837
|
async observe(_existingObservations, _messages) {
|
|
1838
|
-
const maxTokensPerBatch = this.observationConfig.maxTokensPerBatch ??
|
|
1838
|
+
const maxTokensPerBatch = this.observationConfig.maxTokensPerBatch ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.maxTokensPerBatch;
|
|
1839
1839
|
const orderedThreadIds = this.threadOrder.filter((tid) => this.threadsWithMessages.has(tid));
|
|
1840
1840
|
const batches = [];
|
|
1841
1841
|
let currentBatch = {
|
|
@@ -7266,16 +7266,16 @@ var ObservationalMemory = class _ObservationalMemory {
|
|
|
7266
7266
|
this.onIndexObservations = config.onIndexObservations;
|
|
7267
7267
|
this.mastra = config.mastra;
|
|
7268
7268
|
const resolveModel = (model, defaultModel) => model === "default" ? defaultModel : model;
|
|
7269
|
-
const observationModel = resolveModel(config.model,
|
|
7270
|
-
const reflectionModel = resolveModel(config.model,
|
|
7271
|
-
const messageTokens = config.observation?.messageTokens ??
|
|
7272
|
-
const observationTokens = config.reflection?.observationTokens ??
|
|
7269
|
+
const observationModel = resolveModel(config.model, chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.model) ?? resolveModel(config.observation?.model, chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.model) ?? resolveModel(config.reflection?.model, chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.model) ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.model;
|
|
7270
|
+
const reflectionModel = resolveModel(config.model, chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.model) ?? resolveModel(config.reflection?.model, chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.model) ?? resolveModel(config.observation?.model, chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.model) ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.model;
|
|
7271
|
+
const messageTokens = config.observation?.messageTokens ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens;
|
|
7272
|
+
const observationTokens = config.reflection?.observationTokens ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.observationTokens;
|
|
7273
7273
|
const isSharedBudget = config.shareTokenBudget ?? false;
|
|
7274
7274
|
const isDefaultModelSelection = (model) => model === void 0 || model === "default" || model instanceof ModelByInputTokens;
|
|
7275
7275
|
const observationSelectedModel = config.model ?? config.observation?.model ?? config.reflection?.model;
|
|
7276
7276
|
const reflectionSelectedModel = config.model ?? config.reflection?.model ?? config.observation?.model;
|
|
7277
|
-
const observationDefaultMaxOutputTokens = config.observation?.modelSettings?.maxOutputTokens ?? (isDefaultModelSelection(observationSelectedModel) ?
|
|
7278
|
-
const reflectionDefaultMaxOutputTokens = config.reflection?.modelSettings?.maxOutputTokens ?? (isDefaultModelSelection(reflectionSelectedModel) ?
|
|
7277
|
+
const observationDefaultMaxOutputTokens = config.observation?.modelSettings?.maxOutputTokens ?? (isDefaultModelSelection(observationSelectedModel) ? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.modelSettings.maxOutputTokens : void 0);
|
|
7278
|
+
const reflectionDefaultMaxOutputTokens = config.reflection?.modelSettings?.maxOutputTokens ?? (isDefaultModelSelection(reflectionSelectedModel) ? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.modelSettings.maxOutputTokens : void 0);
|
|
7279
7279
|
const totalBudget = messageTokens + observationTokens;
|
|
7280
7280
|
const userExplicitlyConfiguredAsync = config.observation?.bufferTokens !== void 0 || config.observation?.bufferActivation !== void 0 || config.reflection?.bufferActivation !== void 0;
|
|
7281
7281
|
const asyncBufferingDisabled = config.observation?.bufferTokens === false || config.scope === "resource" && !userExplicitlyConfiguredAsync;
|
|
@@ -7308,22 +7308,22 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
|
|
|
7308
7308
|
messageTokens: isSharedBudget ? { min: messageTokens, max: totalBudget } : messageTokens,
|
|
7309
7309
|
shareTokenBudget: isSharedBudget,
|
|
7310
7310
|
modelSettings: {
|
|
7311
|
-
temperature: config.observation?.modelSettings?.temperature ??
|
|
7311
|
+
temperature: config.observation?.modelSettings?.temperature ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.modelSettings.temperature,
|
|
7312
7312
|
...observationDefaultMaxOutputTokens !== void 0 ? { maxOutputTokens: observationDefaultMaxOutputTokens } : {}
|
|
7313
7313
|
},
|
|
7314
|
-
providerOptions: config.observation?.providerOptions ??
|
|
7315
|
-
maxTokensPerBatch: config.observation?.maxTokensPerBatch ??
|
|
7314
|
+
providerOptions: config.observation?.providerOptions ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.providerOptions,
|
|
7315
|
+
maxTokensPerBatch: config.observation?.maxTokensPerBatch ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.maxTokensPerBatch,
|
|
7316
7316
|
bufferTokens: asyncBufferingDisabled ? void 0 : resolveBufferTokens(
|
|
7317
|
-
config.observation?.bufferTokens ??
|
|
7318
|
-
config.observation?.messageTokens ??
|
|
7317
|
+
config.observation?.bufferTokens ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferTokens,
|
|
7318
|
+
config.observation?.messageTokens ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens
|
|
7319
7319
|
),
|
|
7320
7320
|
bufferOnIdle: config.observation?.bufferOnIdle ?? false,
|
|
7321
|
-
bufferActivation: asyncBufferingDisabled ? void 0 : config.observation?.bufferActivation ??
|
|
7321
|
+
bufferActivation: asyncBufferingDisabled ? void 0 : config.observation?.bufferActivation ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferActivation,
|
|
7322
7322
|
activateAfterIdle: parseActivationTTL(observationActivateAfterIdle, observationActivateAfterIdlePath),
|
|
7323
7323
|
activateOnProviderChange: config.observation?.activateOnProviderChange ?? config.activateOnProviderChange ?? false,
|
|
7324
7324
|
blockAfter: asyncBufferingDisabled ? void 0 : resolveBlockAfter(
|
|
7325
|
-
config.observation?.blockAfter ?? (config.observation?.bufferTokens ??
|
|
7326
|
-
config.observation?.messageTokens ??
|
|
7325
|
+
config.observation?.blockAfter ?? (config.observation?.bufferTokens ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferTokens ? 1.2 : void 0),
|
|
7326
|
+
config.observation?.messageTokens ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens
|
|
7327
7327
|
),
|
|
7328
7328
|
previousObserverTokens: config.observation?.previousObserverTokens ?? 2e3,
|
|
7329
7329
|
instruction: config.observation?.instruction,
|
|
@@ -7335,16 +7335,16 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
|
|
|
7335
7335
|
observationTokens,
|
|
7336
7336
|
shareTokenBudget: isSharedBudget,
|
|
7337
7337
|
modelSettings: {
|
|
7338
|
-
temperature: config.reflection?.modelSettings?.temperature ??
|
|
7338
|
+
temperature: config.reflection?.modelSettings?.temperature ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.modelSettings.temperature,
|
|
7339
7339
|
...reflectionDefaultMaxOutputTokens !== void 0 ? { maxOutputTokens: reflectionDefaultMaxOutputTokens } : {}
|
|
7340
7340
|
},
|
|
7341
|
-
providerOptions: config.reflection?.providerOptions ??
|
|
7342
|
-
bufferActivation: asyncBufferingDisabled ? void 0 : config?.reflection?.bufferActivation ??
|
|
7341
|
+
providerOptions: config.reflection?.providerOptions ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.providerOptions,
|
|
7342
|
+
bufferActivation: asyncBufferingDisabled ? void 0 : config?.reflection?.bufferActivation ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation,
|
|
7343
7343
|
activateAfterIdle: parseActivationTTL(config.reflection?.activateAfterIdle, "reflection.activateAfterIdle"),
|
|
7344
7344
|
activateOnProviderChange: config.reflection?.activateOnProviderChange ?? false,
|
|
7345
7345
|
blockAfter: asyncBufferingDisabled ? void 0 : resolveBlockAfter(
|
|
7346
|
-
config.reflection?.blockAfter ?? (config.reflection?.bufferActivation ??
|
|
7347
|
-
config.reflection?.observationTokens ??
|
|
7346
|
+
config.reflection?.blockAfter ?? (config.reflection?.bufferActivation ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation ? 1.2 : void 0),
|
|
7347
|
+
config.reflection?.observationTokens ?? chunkD4J4XPGM_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.observationTokens
|
|
7348
7348
|
),
|
|
7349
7349
|
instruction: config.reflection?.instruction
|
|
7350
7350
|
};
|
|
@@ -8108,11 +8108,11 @@ ${unreflectedContent}` : bufferedReflection;
|
|
|
8108
8108
|
optimized = addRelativeTimeToObservations(optimized, currentDate);
|
|
8109
8109
|
}
|
|
8110
8110
|
const messages = [
|
|
8111
|
-
`${
|
|
8111
|
+
`${chunkD4J4XPGM_cjs.OBSERVATION_CONTEXT_PROMPT}
|
|
8112
8112
|
|
|
8113
|
-
${
|
|
8113
|
+
${chunkD4J4XPGM_cjs.OBSERVATION_CONTEXT_INSTRUCTIONS}${retrieval ? `
|
|
8114
8114
|
|
|
8115
|
-
${
|
|
8115
|
+
${chunkD4J4XPGM_cjs.OBSERVATION_RETRIEVAL_INSTRUCTIONS}` : ""}`
|
|
8116
8116
|
];
|
|
8117
8117
|
if (unobservedContextBlocks) {
|
|
8118
8118
|
messages.push(
|
|
@@ -9744,7 +9744,7 @@ function injectObservationContextMessages({
|
|
|
9744
9744
|
createdAt: /* @__PURE__ */ new Date(0),
|
|
9745
9745
|
content: {
|
|
9746
9746
|
format: 2,
|
|
9747
|
-
parts: [{ type: "text", text: `<system-reminder>${
|
|
9747
|
+
parts: [{ type: "text", text: `<system-reminder>${chunkD4J4XPGM_cjs.OBSERVATION_CONTINUATION_HINT}</system-reminder>` }]
|
|
9748
9748
|
},
|
|
9749
9749
|
threadId,
|
|
9750
9750
|
resourceId
|
|
@@ -10012,5 +10012,5 @@ exports.stripEphemeralAnchorIds = stripEphemeralAnchorIds;
|
|
|
10012
10012
|
exports.stripObservationGroups = stripObservationGroups;
|
|
10013
10013
|
exports.truncateStringByTokens = truncateStringByTokens;
|
|
10014
10014
|
exports.wrapInObservationGroup = wrapInObservationGroup;
|
|
10015
|
-
//# sourceMappingURL=chunk-
|
|
10016
|
-
//# sourceMappingURL=chunk-
|
|
10015
|
+
//# sourceMappingURL=chunk-PTCSCRB6.cjs.map
|
|
10016
|
+
//# sourceMappingURL=chunk-PTCSCRB6.cjs.map
|