@graphrefly/ts 0.0.0
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/LICENSE +21 -0
- package/dist/adapters/index.cjs +9015 -0
- package/dist/adapters/index.cjs.map +1 -0
- package/dist/adapters/index.d.cts +678 -0
- package/dist/adapters/index.d.ts +678 -0
- package/dist/adapters/index.js +2894 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/observe-storage.cjs +260 -0
- package/dist/adapters/observe-storage.cjs.map +1 -0
- package/dist/adapters/observe-storage.d.cts +77 -0
- package/dist/adapters/observe-storage.d.ts +77 -0
- package/dist/adapters/observe-storage.js +161 -0
- package/dist/adapters/observe-storage.js.map +1 -0
- package/dist/append-log-DisvEReb.d.cts +189 -0
- package/dist/append-log-DzKMmjxx.d.ts +189 -0
- package/dist/chunk-2ILL7HQI.js +1189 -0
- package/dist/chunk-2ILL7HQI.js.map +1 -0
- package/dist/chunk-4VLAQHZI.js +330 -0
- package/dist/chunk-4VLAQHZI.js.map +1 -0
- package/dist/chunk-6PHB5CJS.js +229 -0
- package/dist/chunk-6PHB5CJS.js.map +1 -0
- package/dist/chunk-COHO25CZ.js +2449 -0
- package/dist/chunk-COHO25CZ.js.map +1 -0
- package/dist/chunk-D6BG7U6A.js +161 -0
- package/dist/chunk-D6BG7U6A.js.map +1 -0
- package/dist/chunk-DJC4CHLQ.js +818 -0
- package/dist/chunk-DJC4CHLQ.js.map +1 -0
- package/dist/chunk-DK554R7P.js +67 -0
- package/dist/chunk-DK554R7P.js.map +1 -0
- package/dist/chunk-DKP56CSW.js +322 -0
- package/dist/chunk-DKP56CSW.js.map +1 -0
- package/dist/chunk-G4M3NHRJ.js +688 -0
- package/dist/chunk-G4M3NHRJ.js.map +1 -0
- package/dist/chunk-GAJW5I5P.js +1 -0
- package/dist/chunk-GAJW5I5P.js.map +1 -0
- package/dist/chunk-GDL26N2T.js +282 -0
- package/dist/chunk-GDL26N2T.js.map +1 -0
- package/dist/chunk-GTPCOEOZ.js +741 -0
- package/dist/chunk-GTPCOEOZ.js.map +1 -0
- package/dist/chunk-H2HTHFVN.js +1 -0
- package/dist/chunk-H2HTHFVN.js.map +1 -0
- package/dist/chunk-HDRL4VQQ.js +218 -0
- package/dist/chunk-HDRL4VQQ.js.map +1 -0
- package/dist/chunk-I3IHOHCJ.js +2267 -0
- package/dist/chunk-I3IHOHCJ.js.map +1 -0
- package/dist/chunk-JIMUDQN3.js +965 -0
- package/dist/chunk-JIMUDQN3.js.map +1 -0
- package/dist/chunk-JR4IKCR2.js +462 -0
- package/dist/chunk-JR4IKCR2.js.map +1 -0
- package/dist/chunk-K3FXTC3I.js +165 -0
- package/dist/chunk-K3FXTC3I.js.map +1 -0
- package/dist/chunk-OOEN33FB.js +65 -0
- package/dist/chunk-OOEN33FB.js.map +1 -0
- package/dist/chunk-PKVBHGBM.js +554 -0
- package/dist/chunk-PKVBHGBM.js.map +1 -0
- package/dist/chunk-RIIOUTGM.js +1857 -0
- package/dist/chunk-RIIOUTGM.js.map +1 -0
- package/dist/chunk-SCRFRCGR.js +33 -0
- package/dist/chunk-SCRFRCGR.js.map +1 -0
- package/dist/chunk-SWTLEQL6.js +53 -0
- package/dist/chunk-SWTLEQL6.js.map +1 -0
- package/dist/chunk-SZAETNNA.js +1 -0
- package/dist/chunk-SZAETNNA.js.map +1 -0
- package/dist/chunk-TEW47IVR.js +49 -0
- package/dist/chunk-TEW47IVR.js.map +1 -0
- package/dist/chunk-Y3ZLRGHC.js +1482 -0
- package/dist/chunk-Y3ZLRGHC.js.map +1 -0
- package/dist/chunk-Z2ANQ6JW.js +149 -0
- package/dist/chunk-Z2ANQ6JW.js.map +1 -0
- package/dist/codec-BB7p8fJc.d.cts +38 -0
- package/dist/codec-BB7p8fJc.d.ts +38 -0
- package/dist/composition/index.cjs +2505 -0
- package/dist/composition/index.cjs.map +1 -0
- package/dist/composition/index.d.cts +95 -0
- package/dist/composition/index.d.ts +95 -0
- package/dist/composition/index.js +19 -0
- package/dist/composition/index.js.map +1 -0
- package/dist/core/index.cjs +2475 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +25 -0
- package/dist/core/index.d.ts +25 -0
- package/dist/core/index.js +74 -0
- package/dist/core/index.js.map +1 -0
- package/dist/cqrs/index.cjs +595 -0
- package/dist/cqrs/index.cjs.map +1 -0
- package/dist/cqrs/index.d.cts +200 -0
- package/dist/cqrs/index.d.ts +200 -0
- package/dist/cqrs/index.js +557 -0
- package/dist/cqrs/index.js.map +1 -0
- package/dist/data-structures/index.cjs +4277 -0
- package/dist/data-structures/index.cjs.map +1 -0
- package/dist/data-structures/index.d.cts +22 -0
- package/dist/data-structures/index.d.ts +22 -0
- package/dist/data-structures/index.js +31 -0
- package/dist/data-structures/index.js.map +1 -0
- package/dist/describe-BZb7AS2y.d.ts +57 -0
- package/dist/describe-Ciu8SUnN.d.cts +57 -0
- package/dist/graph/index.cjs +7832 -0
- package/dist/graph/index.cjs.map +1 -0
- package/dist/graph/index.d.cts +251 -0
- package/dist/graph/index.d.ts +251 -0
- package/dist/graph/index.js +131 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph-DfdF9zy4.d.ts +666 -0
- package/dist/graph-s23RbbFO.d.cts +666 -0
- package/dist/index-CAEmLCYF.d.cts +166 -0
- package/dist/index-SnzZu3x7.d.ts +166 -0
- package/dist/index.cjs +15409 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +582 -0
- package/dist/index.js.map +1 -0
- package/dist/messages-BZqrGGm1.d.cts +55 -0
- package/dist/messages-BZqrGGm1.d.ts +55 -0
- package/dist/messaging/index.cjs +818 -0
- package/dist/messaging/index.cjs.map +1 -0
- package/dist/messaging/index.d.cts +235 -0
- package/dist/messaging/index.d.ts +235 -0
- package/dist/messaging/index.js +767 -0
- package/dist/messaging/index.js.map +1 -0
- package/dist/observe-event-log-0SVsx7JG.d.cts +88 -0
- package/dist/observe-event-log-Dnm76owp.d.ts +88 -0
- package/dist/operators/index.cjs +3774 -0
- package/dist/operators/index.cjs.map +1 -0
- package/dist/operators/index.d.cts +308 -0
- package/dist/operators/index.d.ts +308 -0
- package/dist/operators/index.js +112 -0
- package/dist/operators/index.js.map +1 -0
- package/dist/orchestration/index.cjs +3541 -0
- package/dist/orchestration/index.cjs.map +1 -0
- package/dist/orchestration/index.d.cts +302 -0
- package/dist/orchestration/index.d.ts +302 -0
- package/dist/orchestration/index.js +1004 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/patterns/index.cjs +1045 -0
- package/dist/patterns/index.cjs.map +1 -0
- package/dist/patterns/index.d.cts +39 -0
- package/dist/patterns/index.d.ts +39 -0
- package/dist/patterns/index.js +33 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/reactive-collection-BxBqtIOE.d.cts +344 -0
- package/dist/reactive-collection-Cb1II1Fi.d.ts +344 -0
- package/dist/reactive-collection-storage-BNiEc-Gd.d.ts +217 -0
- package/dist/reactive-collection-storage-D-KmjE0J.d.cts +217 -0
- package/dist/reactive-map-BcB4KsQR.d.ts +256 -0
- package/dist/reactive-map-D-g3dv8I.d.cts +256 -0
- package/dist/read-through-B1CYPfq_.d.cts +82 -0
- package/dist/read-through-DwyJhGs1.d.ts +82 -0
- package/dist/render/index.cjs +250 -0
- package/dist/render/index.cjs.map +1 -0
- package/dist/render/index.d.cts +58 -0
- package/dist/render/index.d.ts +58 -0
- package/dist/render/index.js +20 -0
- package/dist/render/index.js.map +1 -0
- package/dist/resilience-Dig3Q7n0.d.cts +45 -0
- package/dist/resilience-Dig3Q7n0.d.ts +45 -0
- package/dist/semantic-memory-graph-BYoIlP35.d.cts +356 -0
- package/dist/semantic-memory-graph-CxyXLms3.d.ts +356 -0
- package/dist/solutions/index.cjs +3249 -0
- package/dist/solutions/index.cjs.map +1 -0
- package/dist/solutions/index.d.cts +520 -0
- package/dist/solutions/index.d.ts +520 -0
- package/dist/solutions/index.js +31 -0
- package/dist/solutions/index.js.map +1 -0
- package/dist/sources/browser.cjs +3095 -0
- package/dist/sources/browser.cjs.map +1 -0
- package/dist/sources/browser.d.cts +39 -0
- package/dist/sources/browser.d.ts +39 -0
- package/dist/sources/browser.js +137 -0
- package/dist/sources/browser.js.map +1 -0
- package/dist/sources/index.cjs +3021 -0
- package/dist/sources/index.cjs.map +1 -0
- package/dist/sources/index.d.cts +7 -0
- package/dist/sources/index.d.ts +7 -0
- package/dist/sources/index.js +63 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/node.cjs +675 -0
- package/dist/sources/node.cjs.map +1 -0
- package/dist/sources/node.d.cts +109 -0
- package/dist/sources/node.d.ts +109 -0
- package/dist/sources/node.js +639 -0
- package/dist/sources/node.js.map +1 -0
- package/dist/storage/browser.cjs +777 -0
- package/dist/storage/browser.cjs.map +1 -0
- package/dist/storage/browser.d.cts +40 -0
- package/dist/storage/browser.d.ts +40 -0
- package/dist/storage/browser.js +275 -0
- package/dist/storage/browser.js.map +1 -0
- package/dist/storage/index.cjs +1989 -0
- package/dist/storage/index.cjs.map +1 -0
- package/dist/storage/index.d.cts +92 -0
- package/dist/storage/index.d.ts +92 -0
- package/dist/storage/index.js +161 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/node.cjs +898 -0
- package/dist/storage/node.cjs.map +1 -0
- package/dist/storage/node.d.cts +66 -0
- package/dist/storage/node.d.ts +66 -0
- package/dist/storage/node.js +402 -0
- package/dist/storage/node.js.map +1 -0
- package/dist/testing/index.cjs +95 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +20 -0
- package/dist/testing/index.d.ts +20 -0
- package/dist/testing/index.js +8 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types-bNMSWKqF.d.cts +732 -0
- package/dist/types-h12mNYbq.d.ts +732 -0
- package/package.json +250 -0
|
@@ -0,0 +1,3249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/solutions/index.ts
|
|
21
|
+
var solutions_exports = {};
|
|
22
|
+
__export(solutions_exports, {
|
|
23
|
+
AGENTIC_MEMORY_RECORD_FRAME_FORMAT: () => AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
|
|
24
|
+
AGENTIC_MEMORY_RECORD_FRAME_VERSION: () => AGENTIC_MEMORY_RECORD_FRAME_VERSION,
|
|
25
|
+
agenticMemoryBundle: () => agenticMemoryBundle,
|
|
26
|
+
agenticMemoryConsolidationBundle: () => agenticMemoryConsolidationBundle,
|
|
27
|
+
agenticMemoryContextPackingBundle: () => agenticMemoryContextPackingBundle,
|
|
28
|
+
agenticMemoryKgProjectionBundle: () => agenticMemoryKgProjectionBundle,
|
|
29
|
+
agenticMemoryRecordCodec: () => agenticMemoryRecordCodec,
|
|
30
|
+
agenticMemoryRecordFrame: () => agenticMemoryRecordFrame,
|
|
31
|
+
agenticMemoryRecordFrameCodec: () => agenticMemoryRecordFrameCodec,
|
|
32
|
+
agenticMemoryRetentionBundle: () => agenticMemoryRetentionBundle,
|
|
33
|
+
assertAgenticMemoryRecordFrame: () => assertAgenticMemoryRecordFrame
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(solutions_exports);
|
|
36
|
+
|
|
37
|
+
// src/protocol/messages.ts
|
|
38
|
+
var SENTINEL = void 0;
|
|
39
|
+
|
|
40
|
+
// src/ctx/types.ts
|
|
41
|
+
var CTX_DEP_CACHE = /* @__PURE__ */ Symbol("graphrefly.ctx.depCache");
|
|
42
|
+
function depWaves(ctx, depIndex) {
|
|
43
|
+
return ctx.waveData[depIndex] ?? [];
|
|
44
|
+
}
|
|
45
|
+
function depBatch(ctx, depIndex) {
|
|
46
|
+
const waves = depWaves(ctx, depIndex);
|
|
47
|
+
if (waves.length === 0) return null;
|
|
48
|
+
const flattened = waves.flat().filter((v) => v !== SENTINEL);
|
|
49
|
+
return flattened.length === 0 ? [] : flattened;
|
|
50
|
+
}
|
|
51
|
+
function depLatest(ctx, depIndex) {
|
|
52
|
+
return ctx[CTX_DEP_CACHE]?.latest[depIndex];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/json/codec.ts
|
|
56
|
+
var JS_MIN_NORMAL_NUMBER = 2 ** -1022;
|
|
57
|
+
function assertStableJsonNumber(value, path) {
|
|
58
|
+
if (!Number.isFinite(value)) {
|
|
59
|
+
throw new TypeError(`stableJsonString: non-finite number at ${path}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function assertStrictJsonNumber(value, path) {
|
|
63
|
+
assertStableJsonNumber(value, path);
|
|
64
|
+
if (Object.is(value, -0)) {
|
|
65
|
+
throw new TypeError(`stableJsonString: non-canonical number at ${path}`);
|
|
66
|
+
}
|
|
67
|
+
const abs = Math.abs(value);
|
|
68
|
+
if (abs > 0 && abs < JS_MIN_NORMAL_NUMBER) {
|
|
69
|
+
throw new TypeError(`stableJsonString: subnormal number at ${path}`);
|
|
70
|
+
}
|
|
71
|
+
if (Number.isInteger(value) && !Number.isSafeInteger(value)) {
|
|
72
|
+
throw new TypeError(`stableJsonString: integer outside safe range at ${path}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function sortedJsonValue(value, seen = /* @__PURE__ */ new Set(), path = "$", strictNumbers = false) {
|
|
76
|
+
if (value === null) return null;
|
|
77
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
78
|
+
if (typeof value === "number") {
|
|
79
|
+
if (strictNumbers) assertStrictJsonNumber(value, path);
|
|
80
|
+
else assertStableJsonNumber(value, path);
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
if (typeof value !== "object") {
|
|
84
|
+
throw new TypeError(`stableJsonString: value at ${path} is not JSON-encodable`);
|
|
85
|
+
}
|
|
86
|
+
if (seen.has(value)) throw new TypeError(`stableJsonString: circular reference at ${path}`);
|
|
87
|
+
const proto = Object.getPrototypeOf(value);
|
|
88
|
+
if (!Array.isArray(value) && proto !== Object.prototype && proto !== null) {
|
|
89
|
+
throw new TypeError(`stableJsonString: non-plain object at ${path}`);
|
|
90
|
+
}
|
|
91
|
+
seen.add(value);
|
|
92
|
+
try {
|
|
93
|
+
if (Array.isArray(value)) {
|
|
94
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
95
|
+
throw new TypeError(`stableJsonString: symbol-keyed properties at ${path}`);
|
|
96
|
+
}
|
|
97
|
+
for (const key of Object.getOwnPropertyNames(value)) {
|
|
98
|
+
const isIndex = /^(0|[1-9]\d*)$/.test(key) && Number.isSafeInteger(Number(key)) && Number(key) < value.length;
|
|
99
|
+
if (key !== "length" && !isIndex) {
|
|
100
|
+
throw new TypeError(`stableJsonString: non-index array property at ${path}.${key}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const out2 = [];
|
|
104
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
105
|
+
if (!(i in value)) {
|
|
106
|
+
throw new TypeError(`stableJsonString: sparse array hole at ${path}[${i}]`);
|
|
107
|
+
}
|
|
108
|
+
out2.push(sortedJsonValue(value[i], seen, `${path}[${i}]`, strictNumbers));
|
|
109
|
+
}
|
|
110
|
+
return out2;
|
|
111
|
+
}
|
|
112
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
113
|
+
throw new TypeError(`stableJsonString: symbol-keyed properties at ${path}`);
|
|
114
|
+
}
|
|
115
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
116
|
+
for (const key of Object.keys(value).sort()) {
|
|
117
|
+
out[key] = sortedJsonValue(
|
|
118
|
+
value[key],
|
|
119
|
+
seen,
|
|
120
|
+
`${path}.${key}`,
|
|
121
|
+
strictNumbers
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
} finally {
|
|
126
|
+
seen.delete(value);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function stableJsonString(value) {
|
|
130
|
+
return JSON.stringify(sortedJsonValue(value));
|
|
131
|
+
}
|
|
132
|
+
function strictStableJsonString(value) {
|
|
133
|
+
return JSON.stringify(sortedJsonValue(value, /* @__PURE__ */ new Set(), "$", true));
|
|
134
|
+
}
|
|
135
|
+
function jsonCodecFor() {
|
|
136
|
+
const encoder = new TextEncoder();
|
|
137
|
+
const decoder = new TextDecoder();
|
|
138
|
+
return {
|
|
139
|
+
encode(value) {
|
|
140
|
+
return encoder.encode(stableJsonString(value));
|
|
141
|
+
},
|
|
142
|
+
decode(bytes) {
|
|
143
|
+
return JSON.parse(decoder.decode(bytes));
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
var jsonCodec = jsonCodecFor();
|
|
148
|
+
function bytesEqual(a, b) {
|
|
149
|
+
if (a.byteLength !== b.byteLength) return false;
|
|
150
|
+
for (let i = 0; i < a.byteLength; i += 1) {
|
|
151
|
+
if (a[i] !== b[i]) return false;
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
function hasUnpairedSurrogate(value) {
|
|
156
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
157
|
+
const code = value.charCodeAt(i);
|
|
158
|
+
if (code >= 55296 && code <= 56319) {
|
|
159
|
+
const next = value.charCodeAt(i + 1);
|
|
160
|
+
if (next >= 56320 && next <= 57343) {
|
|
161
|
+
i += 1;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
if (code >= 56320 && code <= 57343) return true;
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
function assertNoUnpairedSurrogates(value, seen = /* @__PURE__ */ new Set(), path = "$") {
|
|
171
|
+
if (typeof value === "string") {
|
|
172
|
+
if (hasUnpairedSurrogate(value)) {
|
|
173
|
+
throw new TypeError(`strictJsonCodec: unpaired surrogate at ${path}`);
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (value === null || typeof value !== "object") return;
|
|
178
|
+
if (seen.has(value)) return;
|
|
179
|
+
seen.add(value);
|
|
180
|
+
try {
|
|
181
|
+
if (Array.isArray(value)) {
|
|
182
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
183
|
+
assertNoUnpairedSurrogates(value[i], seen, `${path}[${i}]`);
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
for (const key of Object.keys(value)) {
|
|
188
|
+
if (hasUnpairedSurrogate(key)) {
|
|
189
|
+
throw new TypeError(`strictJsonCodec: unpaired surrogate at ${path}.${key}`);
|
|
190
|
+
}
|
|
191
|
+
assertNoUnpairedSurrogates(value[key], seen, `${path}.${key}`);
|
|
192
|
+
}
|
|
193
|
+
} finally {
|
|
194
|
+
seen.delete(value);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function assertNoDuplicateJsonObjectKeys(text) {
|
|
198
|
+
let index = 0;
|
|
199
|
+
function fail(message) {
|
|
200
|
+
throw new TypeError(`strictJsonCodec: ${message}`);
|
|
201
|
+
}
|
|
202
|
+
function skipWhitespace() {
|
|
203
|
+
while (/\s/.test(text[index] ?? "")) index += 1;
|
|
204
|
+
}
|
|
205
|
+
function readJsonString() {
|
|
206
|
+
const start = index;
|
|
207
|
+
index += 1;
|
|
208
|
+
while (index < text.length) {
|
|
209
|
+
const ch = text[index];
|
|
210
|
+
if (ch === '"') {
|
|
211
|
+
index += 1;
|
|
212
|
+
try {
|
|
213
|
+
return JSON.parse(text.slice(start, index));
|
|
214
|
+
} catch {
|
|
215
|
+
fail("malformed JSON string");
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (ch === "\\") {
|
|
219
|
+
index += 2;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
index += 1;
|
|
223
|
+
}
|
|
224
|
+
fail("unterminated JSON string");
|
|
225
|
+
}
|
|
226
|
+
function consumeLiteral(literal) {
|
|
227
|
+
if (text.slice(index, index + literal.length) !== literal) {
|
|
228
|
+
fail(`malformed JSON near byte ${index}`);
|
|
229
|
+
}
|
|
230
|
+
index += literal.length;
|
|
231
|
+
}
|
|
232
|
+
function consumeNumber() {
|
|
233
|
+
const match = /^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?/.exec(text.slice(index));
|
|
234
|
+
if (!match) fail(`malformed JSON number near byte ${index}`);
|
|
235
|
+
index += match[0].length;
|
|
236
|
+
}
|
|
237
|
+
function parseValue(path) {
|
|
238
|
+
skipWhitespace();
|
|
239
|
+
const ch = text[index];
|
|
240
|
+
if (ch === "{") {
|
|
241
|
+
parseObject(path);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (ch === "[") {
|
|
245
|
+
parseArray(path);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (ch === '"') {
|
|
249
|
+
readJsonString();
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (ch === "t") {
|
|
253
|
+
consumeLiteral("true");
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (ch === "f") {
|
|
257
|
+
consumeLiteral("false");
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (ch === "n") {
|
|
261
|
+
consumeLiteral("null");
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (ch === "-" || ch !== void 0 && ch >= "0" && ch <= "9") {
|
|
265
|
+
consumeNumber();
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
fail(`malformed JSON near byte ${index}`);
|
|
269
|
+
}
|
|
270
|
+
function parseObject(path) {
|
|
271
|
+
const keys = /* @__PURE__ */ new Set();
|
|
272
|
+
index += 1;
|
|
273
|
+
skipWhitespace();
|
|
274
|
+
if (text[index] === "}") {
|
|
275
|
+
index += 1;
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
while (index < text.length) {
|
|
279
|
+
skipWhitespace();
|
|
280
|
+
if (text[index] !== '"') fail(`expected object key near byte ${index}`);
|
|
281
|
+
const key = readJsonString();
|
|
282
|
+
if (keys.has(key)) {
|
|
283
|
+
throw new TypeError(
|
|
284
|
+
`strictJsonCodec: duplicate object key ${JSON.stringify(key)} at ${path}`
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
keys.add(key);
|
|
288
|
+
skipWhitespace();
|
|
289
|
+
if (text[index] !== ":") fail(`expected ':' after object key near byte ${index}`);
|
|
290
|
+
index += 1;
|
|
291
|
+
parseValue(`${path}.${key}`);
|
|
292
|
+
skipWhitespace();
|
|
293
|
+
if (text[index] === ",") {
|
|
294
|
+
index += 1;
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
if (text[index] === "}") {
|
|
298
|
+
index += 1;
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
fail(`expected ',' or '}' near byte ${index}`);
|
|
302
|
+
}
|
|
303
|
+
fail("unterminated JSON object");
|
|
304
|
+
}
|
|
305
|
+
function parseArray(path) {
|
|
306
|
+
index += 1;
|
|
307
|
+
skipWhitespace();
|
|
308
|
+
if (text[index] === "]") {
|
|
309
|
+
index += 1;
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
let item = 0;
|
|
313
|
+
while (index < text.length) {
|
|
314
|
+
parseValue(`${path}[${item}]`);
|
|
315
|
+
item += 1;
|
|
316
|
+
skipWhitespace();
|
|
317
|
+
if (text[index] === ",") {
|
|
318
|
+
index += 1;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (text[index] === "]") {
|
|
322
|
+
index += 1;
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
fail(`expected ',' or ']' near byte ${index}`);
|
|
326
|
+
}
|
|
327
|
+
fail("unterminated JSON array");
|
|
328
|
+
}
|
|
329
|
+
parseValue("$");
|
|
330
|
+
skipWhitespace();
|
|
331
|
+
if (index !== text.length) fail(`trailing JSON token near byte ${index}`);
|
|
332
|
+
}
|
|
333
|
+
function strictJsonCodecFor() {
|
|
334
|
+
const encoder = new TextEncoder();
|
|
335
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
336
|
+
return {
|
|
337
|
+
encode(value) {
|
|
338
|
+
assertNoUnpairedSurrogates(value);
|
|
339
|
+
return encoder.encode(strictStableJsonString(value));
|
|
340
|
+
},
|
|
341
|
+
decode(bytes) {
|
|
342
|
+
const text = decoder.decode(bytes);
|
|
343
|
+
assertNoDuplicateJsonObjectKeys(text);
|
|
344
|
+
const decoded = JSON.parse(text);
|
|
345
|
+
assertNoUnpairedSurrogates(decoded);
|
|
346
|
+
const canonical = encoder.encode(strictStableJsonString(decoded));
|
|
347
|
+
if (!bytesEqual(bytes, canonical)) {
|
|
348
|
+
throw new TypeError("strictJsonCodec: bytes are not canonical stable JSON");
|
|
349
|
+
}
|
|
350
|
+
return decoded;
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
var strictJsonCodec = strictJsonCodecFor();
|
|
355
|
+
|
|
356
|
+
// src/patterns/semantic-memory.ts
|
|
357
|
+
function cosineSimilarity(a, b) {
|
|
358
|
+
const n = Math.max(a.length, b.length);
|
|
359
|
+
let dot = 0;
|
|
360
|
+
let na = 0;
|
|
361
|
+
let nb = 0;
|
|
362
|
+
for (let i = 0; i < n; i += 1) {
|
|
363
|
+
const av = a[i] ?? 0;
|
|
364
|
+
const bv = b[i] ?? 0;
|
|
365
|
+
dot += av * bv;
|
|
366
|
+
na += av * av;
|
|
367
|
+
nb += bv * bv;
|
|
368
|
+
}
|
|
369
|
+
if (na === 0 || nb === 0) return 0;
|
|
370
|
+
const score = dot / Math.sqrt(na * nb);
|
|
371
|
+
return Number.isFinite(score) ? score : 0;
|
|
372
|
+
}
|
|
373
|
+
function memoryFragmentValidAt(fragment, asOf) {
|
|
374
|
+
if (asOf === void 0) return fragment.validTo === void 0 && fragment.validFrom === void 0;
|
|
375
|
+
if (fragment.validFrom !== void 0 && fragment.validFrom > asOf) return false;
|
|
376
|
+
if (fragment.validTo !== void 0 && fragment.validTo <= asOf) return false;
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
function memoryFragmentMatchesQuery(fragment, query = {}) {
|
|
380
|
+
if (!memoryFragmentValidAt(fragment, query.asOf)) return false;
|
|
381
|
+
if (query.minConfidence !== void 0 && fragment.confidence < query.minConfidence) return false;
|
|
382
|
+
if (query.tags && query.tags.length > 0 && !query.tags.some((tag) => fragment.tags.includes(tag))) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
function filterMemoryFragments(fragments, query = {}) {
|
|
388
|
+
const results = [...fragments].filter((fragment) => memoryFragmentMatchesQuery(fragment, query));
|
|
389
|
+
results.sort((a, b) => b.confidence - a.confidence || compareBigIntDesc(a.tNs, b.tNs));
|
|
390
|
+
return query.limit === void 0 ? results : results.slice(0, Math.max(0, query.limit));
|
|
391
|
+
}
|
|
392
|
+
function validateMemoryFragment(value) {
|
|
393
|
+
const errors = [];
|
|
394
|
+
if (typeof value !== "object" || value === null) {
|
|
395
|
+
return { ok: false, errors: ["fragment must be an object"] };
|
|
396
|
+
}
|
|
397
|
+
const fragment = value;
|
|
398
|
+
if (typeof fragment.id !== "string" || fragment.id.length === 0) {
|
|
399
|
+
errors.push("id must be a non-empty string");
|
|
400
|
+
}
|
|
401
|
+
if (!Object.hasOwn(fragment, "payload")) {
|
|
402
|
+
errors.push("payload must be present");
|
|
403
|
+
}
|
|
404
|
+
if (typeof fragment.tNs !== "bigint") {
|
|
405
|
+
errors.push("tNs must be a bigint");
|
|
406
|
+
}
|
|
407
|
+
const confidence = fragment.confidence;
|
|
408
|
+
if (!Number.isFinite(confidence) || confidence === void 0 || confidence < 0 || confidence > 1) {
|
|
409
|
+
errors.push("confidence must be a finite number in [0, 1]");
|
|
410
|
+
}
|
|
411
|
+
if (!isDenseArrayOf(fragment.tags, (tag) => typeof tag === "string")) {
|
|
412
|
+
errors.push("tags must be a readonly string array");
|
|
413
|
+
}
|
|
414
|
+
if (!isDenseArrayOf(fragment.sources, (source) => typeof source === "string")) {
|
|
415
|
+
errors.push("sources must be a readonly string array");
|
|
416
|
+
}
|
|
417
|
+
if (fragment.validFrom !== void 0 && typeof fragment.validFrom !== "bigint") {
|
|
418
|
+
errors.push("validFrom must be a bigint when present");
|
|
419
|
+
}
|
|
420
|
+
if (fragment.validTo !== void 0 && typeof fragment.validTo !== "bigint") {
|
|
421
|
+
errors.push("validTo must be a bigint when present");
|
|
422
|
+
}
|
|
423
|
+
if (typeof fragment.validFrom === "bigint" && typeof fragment.validTo === "bigint" && fragment.validFrom >= fragment.validTo) {
|
|
424
|
+
errors.push("validFrom must be earlier than validTo");
|
|
425
|
+
}
|
|
426
|
+
if (fragment.embedding !== void 0 && !isDenseArrayOf(
|
|
427
|
+
fragment.embedding,
|
|
428
|
+
(component) => Number.isFinite(component)
|
|
429
|
+
)) {
|
|
430
|
+
errors.push("embedding must be a finite number array when present");
|
|
431
|
+
}
|
|
432
|
+
if (fragment.parentFragmentId !== void 0 && typeof fragment.parentFragmentId !== "string") {
|
|
433
|
+
errors.push("parentFragmentId must be a string when present");
|
|
434
|
+
}
|
|
435
|
+
if (fragment.provenance !== void 0 && typeof fragment.provenance !== "string") {
|
|
436
|
+
errors.push("provenance must be a string when present");
|
|
437
|
+
}
|
|
438
|
+
return { ok: errors.length === 0, errors };
|
|
439
|
+
}
|
|
440
|
+
function compareBigIntDesc(a, b) {
|
|
441
|
+
if (a === b) return 0;
|
|
442
|
+
return a > b ? -1 : 1;
|
|
443
|
+
}
|
|
444
|
+
function isDenseArrayOf(value, predicate) {
|
|
445
|
+
if (!Array.isArray(value)) return false;
|
|
446
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
447
|
+
if (!Object.hasOwn(value, i) || !predicate(value[i])) return false;
|
|
448
|
+
}
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// src/patterns/semantic-memory-graph.ts
|
|
453
|
+
function memoryRetrievalBundle(graph, opts) {
|
|
454
|
+
const name = opts.name ?? "memoryRetrieval";
|
|
455
|
+
const { fragments, query } = opts;
|
|
456
|
+
const snapshot = graph.node(
|
|
457
|
+
[fragments, query],
|
|
458
|
+
(ctx) => {
|
|
459
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
460
|
+
state.evaluation += 1;
|
|
461
|
+
const rawFragments = depLatest(ctx, 0);
|
|
462
|
+
const rawQuery = depLatest(ctx, 1);
|
|
463
|
+
const queryValidation = validateMemoryRetrievalQuery(rawQuery);
|
|
464
|
+
const currentQuery = queryValidation.query;
|
|
465
|
+
const valid = [];
|
|
466
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
467
|
+
const errors = [...queryValidation.errors];
|
|
468
|
+
if (!Array.isArray(rawFragments)) {
|
|
469
|
+
errors.push({
|
|
470
|
+
code: "invalid-fragments-input",
|
|
471
|
+
message: "memoryRetrievalBundle: fragments input must be an array",
|
|
472
|
+
fragment: rawFragments
|
|
473
|
+
});
|
|
474
|
+
} else {
|
|
475
|
+
const length = safeArrayLength(rawFragments);
|
|
476
|
+
if (length === void 0) {
|
|
477
|
+
errors.push({
|
|
478
|
+
code: "invalid-fragments-input",
|
|
479
|
+
message: "memoryRetrievalBundle: fragments input length could not be read",
|
|
480
|
+
fragment: rawFragments
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
for (let i = 0; i < (length ?? 0); i += 1) {
|
|
484
|
+
const result = validateAndSnapshotFragment(rawFragments, i);
|
|
485
|
+
if (result.error !== void 0) {
|
|
486
|
+
errors.push(result.error);
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
const fragment = result.fragment;
|
|
490
|
+
if (seenIds.has(fragment.id)) {
|
|
491
|
+
errors.push({
|
|
492
|
+
code: "duplicate-fragment-id",
|
|
493
|
+
message: "memoryRetrievalBundle: duplicate fragment id",
|
|
494
|
+
index: i,
|
|
495
|
+
fragment,
|
|
496
|
+
validationErrors: [`duplicate fragment id '${fragment.id}'`]
|
|
497
|
+
});
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
seenIds.add(fragment.id);
|
|
501
|
+
valid.push(fragment);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
const ranked = errors.some((error) => !isRecoverableFragmentError(error)) ? [] : rankFragments(valid, currentQuery);
|
|
505
|
+
const cursor = Object.freeze({
|
|
506
|
+
evaluation: state.evaluation,
|
|
507
|
+
validFragments: valid.length,
|
|
508
|
+
invalidFragments: errors.filter(
|
|
509
|
+
(error) => error.code === "invalid-fragment" || error.code === "duplicate-fragment-id"
|
|
510
|
+
).length,
|
|
511
|
+
resultCount: ranked.length
|
|
512
|
+
});
|
|
513
|
+
ctx.state.set(state);
|
|
514
|
+
const answer = Object.freeze({
|
|
515
|
+
query: currentQuery,
|
|
516
|
+
results: Object.freeze(ranked)
|
|
517
|
+
});
|
|
518
|
+
const status = Object.freeze({
|
|
519
|
+
state: statusState(errors, ranked.length),
|
|
520
|
+
query: currentQuery,
|
|
521
|
+
cursor
|
|
522
|
+
});
|
|
523
|
+
const indexed = Object.freeze({
|
|
524
|
+
ids: Object.freeze(valid.map((fragment) => fragment.id)),
|
|
525
|
+
byId: indexById(valid),
|
|
526
|
+
cursor
|
|
527
|
+
});
|
|
528
|
+
const errorFacts = Object.freeze(
|
|
529
|
+
errors.map(
|
|
530
|
+
(error) => Object.freeze({
|
|
531
|
+
...error,
|
|
532
|
+
...error.validationErrors === void 0 ? {} : { validationErrors: Object.freeze([...error.validationErrors]) },
|
|
533
|
+
cursor
|
|
534
|
+
})
|
|
535
|
+
)
|
|
536
|
+
);
|
|
537
|
+
ctx.down([
|
|
538
|
+
[
|
|
539
|
+
"DATA",
|
|
540
|
+
Object.freeze({
|
|
541
|
+
fragments: Object.freeze([...valid]),
|
|
542
|
+
indexed,
|
|
543
|
+
ranked: answer,
|
|
544
|
+
status,
|
|
545
|
+
errors: errorFacts,
|
|
546
|
+
cursor
|
|
547
|
+
})
|
|
548
|
+
]
|
|
549
|
+
]);
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
name: `${name}/snapshot`,
|
|
553
|
+
factory: "memoryRetrievalSnapshot",
|
|
554
|
+
completeWhenDepsComplete: false,
|
|
555
|
+
errorWhenDepsError: false
|
|
556
|
+
}
|
|
557
|
+
);
|
|
558
|
+
return {
|
|
559
|
+
input: { fragments, query },
|
|
560
|
+
snapshot,
|
|
561
|
+
fragments: retrievalProjection(
|
|
562
|
+
graph,
|
|
563
|
+
snapshot,
|
|
564
|
+
`${name}/fragments`,
|
|
565
|
+
"memoryRetrievalFragments",
|
|
566
|
+
(fact) => fact.fragments
|
|
567
|
+
),
|
|
568
|
+
indexed: retrievalProjection(
|
|
569
|
+
graph,
|
|
570
|
+
snapshot,
|
|
571
|
+
`${name}/indexed`,
|
|
572
|
+
"memoryRetrievalIndexed",
|
|
573
|
+
(fact) => fact.indexed
|
|
574
|
+
),
|
|
575
|
+
ranked: retrievalProjection(
|
|
576
|
+
graph,
|
|
577
|
+
snapshot,
|
|
578
|
+
`${name}/ranked`,
|
|
579
|
+
"memoryRetrievalRanked",
|
|
580
|
+
(fact) => fact.ranked
|
|
581
|
+
),
|
|
582
|
+
status: retrievalProjection(
|
|
583
|
+
graph,
|
|
584
|
+
snapshot,
|
|
585
|
+
`${name}/status`,
|
|
586
|
+
"memoryRetrievalStatus",
|
|
587
|
+
(fact) => fact.status
|
|
588
|
+
),
|
|
589
|
+
errors: retrievalProjection(
|
|
590
|
+
graph,
|
|
591
|
+
snapshot,
|
|
592
|
+
`${name}/errors`,
|
|
593
|
+
"memoryRetrievalErrors",
|
|
594
|
+
(fact) => fact.errors
|
|
595
|
+
),
|
|
596
|
+
cursor: retrievalProjection(
|
|
597
|
+
graph,
|
|
598
|
+
snapshot,
|
|
599
|
+
`${name}/cursor`,
|
|
600
|
+
"memoryRetrievalCursor",
|
|
601
|
+
(fact) => fact.cursor
|
|
602
|
+
)
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
function retrievalProjection(graph, snapshot, name, factory, select) {
|
|
606
|
+
return graph.node(
|
|
607
|
+
[snapshot],
|
|
608
|
+
(ctx) => {
|
|
609
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
610
|
+
const fact = raw;
|
|
611
|
+
const selected = select(fact);
|
|
612
|
+
if (selected !== void 0) ctx.down([["DATA", selected]]);
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
name,
|
|
617
|
+
factory,
|
|
618
|
+
completeWhenDepsComplete: false,
|
|
619
|
+
errorWhenDepsError: false
|
|
620
|
+
}
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
function rankFragments(fragments, query) {
|
|
624
|
+
if (query.vector === void 0) return filterMemoryFragments(fragments, query);
|
|
625
|
+
const ranked = fragments.filter((fragment) => memoryFragmentMatchesQuery(fragment, query));
|
|
626
|
+
ranked.sort((a, b) => {
|
|
627
|
+
const vectorDelta = vectorScore(b, query) - vectorScore(a, query);
|
|
628
|
+
if (vectorDelta !== 0) return vectorDelta;
|
|
629
|
+
const confidenceDelta = b.confidence - a.confidence;
|
|
630
|
+
if (confidenceDelta !== 0) return confidenceDelta;
|
|
631
|
+
return compareBigIntDesc2(a.tNs, b.tNs);
|
|
632
|
+
});
|
|
633
|
+
return query.limit === void 0 ? ranked : ranked.slice(0, Math.max(0, query.limit));
|
|
634
|
+
}
|
|
635
|
+
function vectorScore(fragment, query) {
|
|
636
|
+
if (query.vector === void 0 || fragment.embedding === void 0) return 0;
|
|
637
|
+
return cosineSimilarity(query.vector, fragment.embedding);
|
|
638
|
+
}
|
|
639
|
+
function statusState(errors, resultCount) {
|
|
640
|
+
if (errors.some((error) => !isRecoverableFragmentError(error))) return "error";
|
|
641
|
+
if (errors.length > 0) return "partial";
|
|
642
|
+
return resultCount > 0 ? "ready" : "empty";
|
|
643
|
+
}
|
|
644
|
+
function isRecoverableFragmentError(error) {
|
|
645
|
+
return error.code === "invalid-fragment" || error.code === "duplicate-fragment-id";
|
|
646
|
+
}
|
|
647
|
+
function indexById(fragments) {
|
|
648
|
+
const byId = /* @__PURE__ */ Object.create(null);
|
|
649
|
+
for (const fragment of fragments) byId[fragment.id] = fragment;
|
|
650
|
+
return Object.freeze(byId);
|
|
651
|
+
}
|
|
652
|
+
function isFiniteVector(value) {
|
|
653
|
+
if (!Array.isArray(value)) return false;
|
|
654
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
655
|
+
if (!Object.hasOwn(value, i) || !Number.isFinite(value[i])) return false;
|
|
656
|
+
}
|
|
657
|
+
return true;
|
|
658
|
+
}
|
|
659
|
+
function validateMemoryRetrievalQuery(value) {
|
|
660
|
+
try {
|
|
661
|
+
return validateMemoryRetrievalQueryInner(value);
|
|
662
|
+
} catch (error) {
|
|
663
|
+
return {
|
|
664
|
+
ok: false,
|
|
665
|
+
query: {},
|
|
666
|
+
errors: [
|
|
667
|
+
{
|
|
668
|
+
code: "invalid-query",
|
|
669
|
+
message: `memoryRetrievalBundle: query access failed: ${errorMessage(error)}`,
|
|
670
|
+
fragment: value
|
|
671
|
+
}
|
|
672
|
+
]
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
function validateMemoryRetrievalQueryInner(value) {
|
|
677
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
678
|
+
return invalidQuery(value, "memoryRetrievalBundle: query must be an object");
|
|
679
|
+
}
|
|
680
|
+
const query = value;
|
|
681
|
+
const errors = [];
|
|
682
|
+
if (query.tags !== void 0 && !isDenseArrayOf2(query.tags, (tag) => typeof tag === "string")) {
|
|
683
|
+
errors.push({
|
|
684
|
+
code: "invalid-query",
|
|
685
|
+
message: "memoryRetrievalBundle: query.tags must be a readonly string array",
|
|
686
|
+
fragment: value,
|
|
687
|
+
validationErrors: ["tags must be a readonly string array"]
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
if (query.asOf !== void 0 && typeof query.asOf !== "bigint") {
|
|
691
|
+
errors.push({
|
|
692
|
+
code: "invalid-query",
|
|
693
|
+
message: "memoryRetrievalBundle: query.asOf must be a bigint",
|
|
694
|
+
fragment: value,
|
|
695
|
+
validationErrors: ["asOf must be a bigint when present"]
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
if (query.minConfidence !== void 0 && (!Number.isFinite(query.minConfidence) || query.minConfidence < 0 || query.minConfidence > 1)) {
|
|
699
|
+
errors.push({
|
|
700
|
+
code: "invalid-query",
|
|
701
|
+
message: "memoryRetrievalBundle: query.minConfidence must be a finite number in [0, 1]",
|
|
702
|
+
fragment: value,
|
|
703
|
+
validationErrors: ["minConfidence must be a finite number in [0, 1]"]
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
if (query.limit !== void 0 && (!Number.isSafeInteger(query.limit) || query.limit < 0)) {
|
|
707
|
+
errors.push({
|
|
708
|
+
code: "invalid-query",
|
|
709
|
+
message: "memoryRetrievalBundle: query.limit must be a non-negative safe integer",
|
|
710
|
+
fragment: value,
|
|
711
|
+
validationErrors: ["limit must be a non-negative safe integer"]
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
if (query.vector !== void 0 && !isFiniteVector(query.vector)) {
|
|
715
|
+
errors.push({
|
|
716
|
+
code: "invalid-query-vector",
|
|
717
|
+
message: "memoryRetrievalBundle: query.vector must be a finite number array",
|
|
718
|
+
fragment: value,
|
|
719
|
+
validationErrors: ["vector must be a finite number array"]
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
if (errors.length > 0) return { ok: false, query: {}, errors };
|
|
723
|
+
return { ok: true, query: snapshotQuery(query), errors };
|
|
724
|
+
}
|
|
725
|
+
function invalidQuery(value, message) {
|
|
726
|
+
return {
|
|
727
|
+
ok: false,
|
|
728
|
+
query: {},
|
|
729
|
+
errors: [
|
|
730
|
+
{
|
|
731
|
+
code: "invalid-query",
|
|
732
|
+
message,
|
|
733
|
+
fragment: value
|
|
734
|
+
}
|
|
735
|
+
]
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
function snapshotQuery(query) {
|
|
739
|
+
return Object.freeze({
|
|
740
|
+
...query.tags === void 0 ? {} : { tags: Object.freeze([...query.tags]) },
|
|
741
|
+
...query.asOf === void 0 ? {} : { asOf: query.asOf },
|
|
742
|
+
...query.minConfidence === void 0 ? {} : { minConfidence: query.minConfidence },
|
|
743
|
+
...query.limit === void 0 ? {} : { limit: query.limit },
|
|
744
|
+
...query.vector === void 0 ? {} : { vector: Object.freeze([...query.vector]) }
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
function safeArrayLength(value) {
|
|
748
|
+
try {
|
|
749
|
+
return value.length;
|
|
750
|
+
} catch {
|
|
751
|
+
return void 0;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
function validateAndSnapshotFragment(rawFragments, index) {
|
|
755
|
+
let raw;
|
|
756
|
+
try {
|
|
757
|
+
raw = rawFragments[index];
|
|
758
|
+
const validation = validateMemoryFragment(raw);
|
|
759
|
+
if (!validation.ok) {
|
|
760
|
+
return {
|
|
761
|
+
error: {
|
|
762
|
+
code: "invalid-fragment",
|
|
763
|
+
message: "memoryRetrievalBundle: invalid memory fragment",
|
|
764
|
+
index,
|
|
765
|
+
fragment: raw,
|
|
766
|
+
validationErrors: Object.freeze([...validation.errors])
|
|
767
|
+
}
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
return { fragment: snapshotFragment(raw) };
|
|
771
|
+
} catch (error) {
|
|
772
|
+
return {
|
|
773
|
+
error: {
|
|
774
|
+
code: "invalid-fragment",
|
|
775
|
+
message: `memoryRetrievalBundle: fragment access failed: ${errorMessage(error)}`,
|
|
776
|
+
index,
|
|
777
|
+
fragment: raw,
|
|
778
|
+
validationErrors: Object.freeze(["fragment access failed"])
|
|
779
|
+
}
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
function snapshotFragment(fragment) {
|
|
784
|
+
return Object.freeze({
|
|
785
|
+
id: fragment.id,
|
|
786
|
+
payload: fragment.payload,
|
|
787
|
+
tNs: fragment.tNs,
|
|
788
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: fragment.validFrom },
|
|
789
|
+
...fragment.validTo === void 0 ? {} : { validTo: fragment.validTo },
|
|
790
|
+
confidence: fragment.confidence,
|
|
791
|
+
tags: Object.freeze([...fragment.tags]),
|
|
792
|
+
sources: Object.freeze([...fragment.sources]),
|
|
793
|
+
...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
|
|
794
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
795
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
function isDenseArrayOf2(value, predicate) {
|
|
799
|
+
if (!Array.isArray(value)) return false;
|
|
800
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
801
|
+
if (!Object.hasOwn(value, i) || !predicate(value[i])) return false;
|
|
802
|
+
}
|
|
803
|
+
return true;
|
|
804
|
+
}
|
|
805
|
+
function errorMessage(error) {
|
|
806
|
+
return error instanceof Error ? error.message : String(error);
|
|
807
|
+
}
|
|
808
|
+
function compareBigIntDesc2(a, b) {
|
|
809
|
+
if (a === b) return 0;
|
|
810
|
+
return a > b ? -1 : 1;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// src/solutions/agentic-memory.ts
|
|
814
|
+
var AGENTIC_MEMORY_RECORD_FRAME_FORMAT = "graphrefly.agenticMemoryRecord";
|
|
815
|
+
var AGENTIC_MEMORY_RECORD_FRAME_VERSION = 1;
|
|
816
|
+
function agenticMemoryBundle(graph, opts) {
|
|
817
|
+
const name = opts.name ?? "agenticMemory";
|
|
818
|
+
const projection = agenticMemoryRecordProjection(graph, opts.records, `${name}/projection`);
|
|
819
|
+
const projectedRecords = agenticMemoryProjection(
|
|
820
|
+
graph,
|
|
821
|
+
projection,
|
|
822
|
+
`${name}/records`,
|
|
823
|
+
"agenticMemoryRecords",
|
|
824
|
+
(fact) => fact.records
|
|
825
|
+
);
|
|
826
|
+
const projectedFragments = agenticMemoryProjection(
|
|
827
|
+
graph,
|
|
828
|
+
projection,
|
|
829
|
+
`${name}/fragments`,
|
|
830
|
+
"agenticMemoryFragments",
|
|
831
|
+
(fact) => fact.fragments
|
|
832
|
+
);
|
|
833
|
+
const status = agenticMemoryProjection(
|
|
834
|
+
graph,
|
|
835
|
+
projection,
|
|
836
|
+
`${name}/status`,
|
|
837
|
+
"agenticMemoryStatus",
|
|
838
|
+
(fact) => fact.status
|
|
839
|
+
);
|
|
840
|
+
const errors = agenticMemoryProjection(
|
|
841
|
+
graph,
|
|
842
|
+
projection,
|
|
843
|
+
`${name}/errors`,
|
|
844
|
+
"agenticMemoryErrors",
|
|
845
|
+
(fact) => fact.errors
|
|
846
|
+
);
|
|
847
|
+
const retrieval = memoryRetrievalBundle(graph, {
|
|
848
|
+
name: `${name}/retrieval`,
|
|
849
|
+
fragments: projectedFragments,
|
|
850
|
+
query: opts.query
|
|
851
|
+
});
|
|
852
|
+
const sources = agenticMemoryProjection(
|
|
853
|
+
graph,
|
|
854
|
+
projection,
|
|
855
|
+
`${name}/sources`,
|
|
856
|
+
"agenticMemorySources",
|
|
857
|
+
(fact) => Object.freeze(
|
|
858
|
+
fact.fragments.map(
|
|
859
|
+
(fragment) => Object.freeze({
|
|
860
|
+
fragmentId: fragment.id,
|
|
861
|
+
...fact.metadataByFragmentId[fragment.id] === void 0 ? {} : { record: fact.metadataByFragmentId[fragment.id] },
|
|
862
|
+
sources: Object.freeze([...fragment.sources]),
|
|
863
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
864
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
865
|
+
})
|
|
866
|
+
)
|
|
867
|
+
)
|
|
868
|
+
);
|
|
869
|
+
const context = agenticMemoryContextProjection(
|
|
870
|
+
graph,
|
|
871
|
+
projection,
|
|
872
|
+
retrieval.snapshot,
|
|
873
|
+
`${name}/context`
|
|
874
|
+
);
|
|
875
|
+
return {
|
|
876
|
+
input: { records: opts.records, query: opts.query },
|
|
877
|
+
projection,
|
|
878
|
+
retrieval,
|
|
879
|
+
retrievalSnapshot: retrieval.snapshot,
|
|
880
|
+
records: projectedRecords,
|
|
881
|
+
fragments: projectedFragments,
|
|
882
|
+
sources,
|
|
883
|
+
indexed: retrieval.indexed,
|
|
884
|
+
ranked: retrieval.ranked,
|
|
885
|
+
context,
|
|
886
|
+
status,
|
|
887
|
+
errors,
|
|
888
|
+
retrievalStatus: retrieval.status,
|
|
889
|
+
retrievalErrors: retrieval.errors,
|
|
890
|
+
cursor: retrieval.cursor
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
function agenticMemoryKgProjectionBundle(graph, opts) {
|
|
894
|
+
const name = opts.name ?? "agenticMemoryKgProjection";
|
|
895
|
+
const projection = graph.node(
|
|
896
|
+
[opts.records, opts.drafts],
|
|
897
|
+
(ctx) => {
|
|
898
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
899
|
+
state.evaluation += 1;
|
|
900
|
+
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
901
|
+
const draftProjection = validateAndProjectKgDrafts(
|
|
902
|
+
depLatest(ctx, 1),
|
|
903
|
+
recordProjection.records
|
|
904
|
+
);
|
|
905
|
+
const cursor = Object.freeze({
|
|
906
|
+
evaluation: state.evaluation,
|
|
907
|
+
validRecords: recordProjection.records.length,
|
|
908
|
+
validDrafts: draftProjection.assertions.length,
|
|
909
|
+
invalidDrafts: draftProjection.invalidDrafts,
|
|
910
|
+
projectedAssertions: draftProjection.assertions.length
|
|
911
|
+
});
|
|
912
|
+
const errors = Object.freeze(
|
|
913
|
+
[...recordProjection.errors.map(kgErrorFromRecordError), ...draftProjection.errors].map(
|
|
914
|
+
(error) => freezeError({ ...error, cursor })
|
|
915
|
+
)
|
|
916
|
+
);
|
|
917
|
+
const status = Object.freeze({
|
|
918
|
+
state: agenticStatusState(errors.length, draftProjection.assertions.length),
|
|
919
|
+
cursor
|
|
920
|
+
});
|
|
921
|
+
ctx.state.set(state);
|
|
922
|
+
ctx.down([
|
|
923
|
+
[
|
|
924
|
+
"DATA",
|
|
925
|
+
Object.freeze({
|
|
926
|
+
assertions: Object.freeze(draftProjection.assertions),
|
|
927
|
+
status,
|
|
928
|
+
errors,
|
|
929
|
+
cursor
|
|
930
|
+
})
|
|
931
|
+
]
|
|
932
|
+
]);
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
name: `${name}/projection`,
|
|
936
|
+
factory: "agenticMemoryKgProjection",
|
|
937
|
+
completeWhenDepsComplete: false,
|
|
938
|
+
errorWhenDepsError: false
|
|
939
|
+
}
|
|
940
|
+
);
|
|
941
|
+
return {
|
|
942
|
+
input: { records: opts.records, drafts: opts.drafts },
|
|
943
|
+
projection,
|
|
944
|
+
assertions: solutionProjection(
|
|
945
|
+
graph,
|
|
946
|
+
projection,
|
|
947
|
+
`${name}/assertions`,
|
|
948
|
+
"agenticMemoryKgAssertions",
|
|
949
|
+
(fact) => fact.assertions
|
|
950
|
+
),
|
|
951
|
+
status: solutionProjection(
|
|
952
|
+
graph,
|
|
953
|
+
projection,
|
|
954
|
+
`${name}/status`,
|
|
955
|
+
"agenticMemoryKgStatus",
|
|
956
|
+
(fact) => fact.status
|
|
957
|
+
),
|
|
958
|
+
errors: solutionProjection(
|
|
959
|
+
graph,
|
|
960
|
+
projection,
|
|
961
|
+
`${name}/errors`,
|
|
962
|
+
"agenticMemoryKgErrors",
|
|
963
|
+
(fact) => fact.errors
|
|
964
|
+
),
|
|
965
|
+
cursor: solutionProjection(
|
|
966
|
+
graph,
|
|
967
|
+
projection,
|
|
968
|
+
`${name}/cursor`,
|
|
969
|
+
"agenticMemoryKgCursor",
|
|
970
|
+
(fact) => fact.cursor
|
|
971
|
+
)
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
function agenticMemoryRecordFrame(record) {
|
|
975
|
+
const result = validateAndSnapshotRecord(record, 0);
|
|
976
|
+
if (result.errors.length > 0 || result.record === void 0) {
|
|
977
|
+
throw new TypeError(
|
|
978
|
+
`agenticMemoryRecordFrame: invalid record: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
assertAgenticMemoryRecordCodecShape(record);
|
|
982
|
+
assertStrictJsonValue(result.record.fragment.payload, "record.fragment.payload");
|
|
983
|
+
return Object.freeze({
|
|
984
|
+
format: AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
|
|
985
|
+
version: AGENTIC_MEMORY_RECORD_FRAME_VERSION,
|
|
986
|
+
record: Object.freeze({
|
|
987
|
+
id: result.record.id,
|
|
988
|
+
kind: result.record.kind,
|
|
989
|
+
persistenceLevel: result.record.persistenceLevel,
|
|
990
|
+
artifactKind: result.record.artifactKind,
|
|
991
|
+
...result.record.scope === void 0 ? {} : { scope: result.record.scope },
|
|
992
|
+
fragment: fragmentFrame(result.record.fragment)
|
|
993
|
+
})
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
function assertAgenticMemoryRecordFrame(value) {
|
|
997
|
+
if (!isPlainRecord(value))
|
|
998
|
+
throw new TypeError("agenticMemoryRecordFrame: frame must be an object");
|
|
999
|
+
assertStrictJsonValue(value, "agenticMemoryRecordFrame");
|
|
1000
|
+
assertExactKeys(value, ["format", "record", "version"], "agenticMemoryRecordFrame");
|
|
1001
|
+
if (value.format !== AGENTIC_MEMORY_RECORD_FRAME_FORMAT) {
|
|
1002
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid format");
|
|
1003
|
+
}
|
|
1004
|
+
if (value.version !== AGENTIC_MEMORY_RECORD_FRAME_VERSION) {
|
|
1005
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid version");
|
|
1006
|
+
}
|
|
1007
|
+
const rawRecord = value.record;
|
|
1008
|
+
if (!isPlainRecord(rawRecord)) {
|
|
1009
|
+
throw new TypeError("agenticMemoryRecordFrame: record must be an object");
|
|
1010
|
+
}
|
|
1011
|
+
assertExactKeys(
|
|
1012
|
+
rawRecord,
|
|
1013
|
+
rawRecord.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
|
|
1014
|
+
"agenticMemoryRecordFrame.record"
|
|
1015
|
+
);
|
|
1016
|
+
const rawFragment = rawRecord.fragment;
|
|
1017
|
+
if (!isPlainRecord(rawFragment)) {
|
|
1018
|
+
throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
|
|
1019
|
+
}
|
|
1020
|
+
assertExactKeys(
|
|
1021
|
+
rawFragment,
|
|
1022
|
+
[
|
|
1023
|
+
"id",
|
|
1024
|
+
"payload",
|
|
1025
|
+
"tNs",
|
|
1026
|
+
...rawFragment.validFrom === void 0 ? [] : ["validFrom"],
|
|
1027
|
+
...rawFragment.validTo === void 0 ? [] : ["validTo"],
|
|
1028
|
+
"confidence",
|
|
1029
|
+
"tags",
|
|
1030
|
+
"sources",
|
|
1031
|
+
...rawFragment.embedding === void 0 ? [] : ["embedding"],
|
|
1032
|
+
...rawFragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
|
|
1033
|
+
...rawFragment.provenance === void 0 ? [] : ["provenance"]
|
|
1034
|
+
],
|
|
1035
|
+
"agenticMemoryRecordFrame.record.fragment"
|
|
1036
|
+
);
|
|
1037
|
+
if (rawRecord.scope !== void 0) assertScopeFrame(rawRecord.scope);
|
|
1038
|
+
const frame = value;
|
|
1039
|
+
const decoded = recordFromFrame(frame);
|
|
1040
|
+
const roundtrip = agenticMemoryRecordFrame(decoded);
|
|
1041
|
+
return roundtrip;
|
|
1042
|
+
}
|
|
1043
|
+
function agenticMemoryRecordFrameCodec() {
|
|
1044
|
+
return {
|
|
1045
|
+
encode(value) {
|
|
1046
|
+
return strictJsonCodec.encode(assertAgenticMemoryRecordFrame(value));
|
|
1047
|
+
},
|
|
1048
|
+
decode(bytes) {
|
|
1049
|
+
return assertAgenticMemoryRecordFrame(strictJsonCodec.decode(bytes));
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
function agenticMemoryRecordCodec() {
|
|
1054
|
+
const frameCodec = agenticMemoryRecordFrameCodec();
|
|
1055
|
+
return {
|
|
1056
|
+
encode(value) {
|
|
1057
|
+
return frameCodec.encode(agenticMemoryRecordFrame(value));
|
|
1058
|
+
},
|
|
1059
|
+
decode(bytes) {
|
|
1060
|
+
return recordFromFrame(frameCodec.decode(bytes));
|
|
1061
|
+
}
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
function agenticMemoryRetentionBundle(graph, opts) {
|
|
1065
|
+
const name = opts.name ?? "agenticMemoryRetention";
|
|
1066
|
+
const projection = graph.node(
|
|
1067
|
+
[opts.records, opts.commands],
|
|
1068
|
+
(ctx) => {
|
|
1069
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
1070
|
+
state.evaluation += 1;
|
|
1071
|
+
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
1072
|
+
const retention = projectRetention(depLatest(ctx, 1), recordProjection.records);
|
|
1073
|
+
const cursor = Object.freeze({
|
|
1074
|
+
evaluation: state.evaluation,
|
|
1075
|
+
validRecords: recordProjection.records.length,
|
|
1076
|
+
validCommands: retention.validCommands,
|
|
1077
|
+
invalidCommands: retention.invalidCommands,
|
|
1078
|
+
activeRecords: retention.activeRecords.length,
|
|
1079
|
+
archivedRecords: retention.archivedRecords.length,
|
|
1080
|
+
consolidationRequests: retention.consolidationRequests.length
|
|
1081
|
+
});
|
|
1082
|
+
const errors = Object.freeze(
|
|
1083
|
+
[...recordProjection.errors.map(retentionErrorFromRecordError), ...retention.errors].map(
|
|
1084
|
+
(error) => freezeError({ ...error, cursor })
|
|
1085
|
+
)
|
|
1086
|
+
);
|
|
1087
|
+
const status = Object.freeze({
|
|
1088
|
+
state: agenticStatusState(errors.length, recordProjection.records.length),
|
|
1089
|
+
cursor
|
|
1090
|
+
});
|
|
1091
|
+
ctx.state.set(state);
|
|
1092
|
+
ctx.down([
|
|
1093
|
+
[
|
|
1094
|
+
"DATA",
|
|
1095
|
+
Object.freeze({
|
|
1096
|
+
activeRecords: Object.freeze(retention.activeRecords),
|
|
1097
|
+
archivedRecords: Object.freeze(retention.archivedRecords),
|
|
1098
|
+
consolidationRequests: Object.freeze(retention.consolidationRequests),
|
|
1099
|
+
status,
|
|
1100
|
+
errors,
|
|
1101
|
+
cursor
|
|
1102
|
+
})
|
|
1103
|
+
]
|
|
1104
|
+
]);
|
|
1105
|
+
},
|
|
1106
|
+
{
|
|
1107
|
+
name: `${name}/projection`,
|
|
1108
|
+
factory: "agenticMemoryRetention",
|
|
1109
|
+
completeWhenDepsComplete: false,
|
|
1110
|
+
errorWhenDepsError: false
|
|
1111
|
+
}
|
|
1112
|
+
);
|
|
1113
|
+
return {
|
|
1114
|
+
input: { records: opts.records, commands: opts.commands },
|
|
1115
|
+
projection,
|
|
1116
|
+
activeRecords: solutionProjection(
|
|
1117
|
+
graph,
|
|
1118
|
+
projection,
|
|
1119
|
+
`${name}/activeRecords`,
|
|
1120
|
+
"agenticMemoryRetentionActiveRecords",
|
|
1121
|
+
(fact) => fact.activeRecords
|
|
1122
|
+
),
|
|
1123
|
+
archivedRecords: solutionProjection(
|
|
1124
|
+
graph,
|
|
1125
|
+
projection,
|
|
1126
|
+
`${name}/archivedRecords`,
|
|
1127
|
+
"agenticMemoryRetentionArchivedRecords",
|
|
1128
|
+
(fact) => fact.archivedRecords
|
|
1129
|
+
),
|
|
1130
|
+
consolidationRequests: solutionProjection(
|
|
1131
|
+
graph,
|
|
1132
|
+
projection,
|
|
1133
|
+
`${name}/consolidationRequests`,
|
|
1134
|
+
"agenticMemoryRetentionConsolidationRequests",
|
|
1135
|
+
(fact) => fact.consolidationRequests
|
|
1136
|
+
),
|
|
1137
|
+
status: solutionProjection(
|
|
1138
|
+
graph,
|
|
1139
|
+
projection,
|
|
1140
|
+
`${name}/status`,
|
|
1141
|
+
"agenticMemoryRetentionStatus",
|
|
1142
|
+
(fact) => fact.status
|
|
1143
|
+
),
|
|
1144
|
+
errors: solutionProjection(
|
|
1145
|
+
graph,
|
|
1146
|
+
projection,
|
|
1147
|
+
`${name}/errors`,
|
|
1148
|
+
"agenticMemoryRetentionErrors",
|
|
1149
|
+
(fact) => fact.errors
|
|
1150
|
+
),
|
|
1151
|
+
cursor: solutionProjection(
|
|
1152
|
+
graph,
|
|
1153
|
+
projection,
|
|
1154
|
+
`${name}/cursor`,
|
|
1155
|
+
"agenticMemoryRetentionCursor",
|
|
1156
|
+
(fact) => fact.cursor
|
|
1157
|
+
)
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
function agenticMemoryConsolidationBundle(graph, opts) {
|
|
1161
|
+
const name = opts.name ?? "agenticMemoryConsolidation";
|
|
1162
|
+
const projection = graph.node(
|
|
1163
|
+
[opts.records, opts.requests, opts.outcomes],
|
|
1164
|
+
(ctx) => {
|
|
1165
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
1166
|
+
state.evaluation += 1;
|
|
1167
|
+
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
1168
|
+
const requests = validateConsolidationRequests(depLatest(ctx, 1), recordProjection.records);
|
|
1169
|
+
const outcomes = projectConsolidationOutcomes(
|
|
1170
|
+
depLatest(ctx, 2),
|
|
1171
|
+
requests.requests,
|
|
1172
|
+
state.evaluation
|
|
1173
|
+
);
|
|
1174
|
+
const cursor = Object.freeze({
|
|
1175
|
+
evaluation: state.evaluation,
|
|
1176
|
+
validRequests: requests.requests.length,
|
|
1177
|
+
validOutcomes: outcomes.validOutcomes,
|
|
1178
|
+
invalidOutcomes: outcomes.invalidOutcomes,
|
|
1179
|
+
results: outcomes.results.length,
|
|
1180
|
+
proposedRecordDrafts: outcomes.proposedRecordDrafts.length
|
|
1181
|
+
});
|
|
1182
|
+
const errors = Object.freeze(
|
|
1183
|
+
[
|
|
1184
|
+
...recordProjection.errors.map(consolidationErrorFromRecordError),
|
|
1185
|
+
...requests.errors.map(consolidationErrorFromRetentionError),
|
|
1186
|
+
...outcomes.errors
|
|
1187
|
+
].map((error) => freezeError({ ...error, cursor }))
|
|
1188
|
+
);
|
|
1189
|
+
const status = Object.freeze({
|
|
1190
|
+
state: agenticStatusState(errors.length, outcomes.results.length),
|
|
1191
|
+
cursor
|
|
1192
|
+
});
|
|
1193
|
+
ctx.state.set(state);
|
|
1194
|
+
ctx.down([
|
|
1195
|
+
[
|
|
1196
|
+
"DATA",
|
|
1197
|
+
Object.freeze({
|
|
1198
|
+
results: Object.freeze(outcomes.results),
|
|
1199
|
+
proposedRecordDrafts: Object.freeze(outcomes.proposedRecordDrafts),
|
|
1200
|
+
commands: Object.freeze(outcomes.commands),
|
|
1201
|
+
status,
|
|
1202
|
+
errors,
|
|
1203
|
+
cursor
|
|
1204
|
+
})
|
|
1205
|
+
]
|
|
1206
|
+
]);
|
|
1207
|
+
},
|
|
1208
|
+
{
|
|
1209
|
+
name: `${name}/projection`,
|
|
1210
|
+
factory: "agenticMemoryConsolidation",
|
|
1211
|
+
completeWhenDepsComplete: false,
|
|
1212
|
+
errorWhenDepsError: false
|
|
1213
|
+
}
|
|
1214
|
+
);
|
|
1215
|
+
return {
|
|
1216
|
+
input: { records: opts.records, requests: opts.requests, outcomes: opts.outcomes },
|
|
1217
|
+
projection,
|
|
1218
|
+
results: solutionProjection(
|
|
1219
|
+
graph,
|
|
1220
|
+
projection,
|
|
1221
|
+
`${name}/results`,
|
|
1222
|
+
"agenticMemoryConsolidationResults",
|
|
1223
|
+
(fact) => fact.results
|
|
1224
|
+
),
|
|
1225
|
+
proposedRecordDrafts: solutionProjection(
|
|
1226
|
+
graph,
|
|
1227
|
+
projection,
|
|
1228
|
+
`${name}/proposedRecordDrafts`,
|
|
1229
|
+
"agenticMemoryConsolidationRecordDrafts",
|
|
1230
|
+
(fact) => fact.proposedRecordDrafts
|
|
1231
|
+
),
|
|
1232
|
+
commands: solutionProjection(
|
|
1233
|
+
graph,
|
|
1234
|
+
projection,
|
|
1235
|
+
`${name}/commands`,
|
|
1236
|
+
"agenticMemoryConsolidationCommands",
|
|
1237
|
+
(fact) => fact.commands
|
|
1238
|
+
),
|
|
1239
|
+
status: solutionProjection(
|
|
1240
|
+
graph,
|
|
1241
|
+
projection,
|
|
1242
|
+
`${name}/status`,
|
|
1243
|
+
"agenticMemoryConsolidationStatus",
|
|
1244
|
+
(fact) => fact.status
|
|
1245
|
+
),
|
|
1246
|
+
errors: solutionProjection(
|
|
1247
|
+
graph,
|
|
1248
|
+
projection,
|
|
1249
|
+
`${name}/errors`,
|
|
1250
|
+
"agenticMemoryConsolidationErrors",
|
|
1251
|
+
(fact) => fact.errors
|
|
1252
|
+
),
|
|
1253
|
+
cursor: solutionProjection(
|
|
1254
|
+
graph,
|
|
1255
|
+
projection,
|
|
1256
|
+
`${name}/cursor`,
|
|
1257
|
+
"agenticMemoryConsolidationCursor",
|
|
1258
|
+
(fact) => fact.cursor
|
|
1259
|
+
)
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
function agenticMemoryContextPackingBundle(graph, opts) {
|
|
1263
|
+
const name = opts.name ?? "agenticMemoryContextPacking";
|
|
1264
|
+
const projection = graph.node(
|
|
1265
|
+
[opts.context, opts.texts, opts.policy],
|
|
1266
|
+
(ctx) => {
|
|
1267
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
1268
|
+
state.evaluation += 1;
|
|
1269
|
+
const packed = packContext(
|
|
1270
|
+
depLatest(ctx, 0),
|
|
1271
|
+
depLatest(ctx, 1),
|
|
1272
|
+
depLatest(ctx, 2),
|
|
1273
|
+
state.evaluation
|
|
1274
|
+
);
|
|
1275
|
+
ctx.state.set(state);
|
|
1276
|
+
ctx.down([["DATA", packed]]);
|
|
1277
|
+
},
|
|
1278
|
+
{
|
|
1279
|
+
name: `${name}/projection`,
|
|
1280
|
+
factory: "agenticMemoryContextPacking",
|
|
1281
|
+
completeWhenDepsComplete: false,
|
|
1282
|
+
errorWhenDepsError: false
|
|
1283
|
+
}
|
|
1284
|
+
);
|
|
1285
|
+
return {
|
|
1286
|
+
input: { context: opts.context, texts: opts.texts, policy: opts.policy },
|
|
1287
|
+
projection,
|
|
1288
|
+
packedContext: solutionProjection(
|
|
1289
|
+
graph,
|
|
1290
|
+
projection,
|
|
1291
|
+
`${name}/packedContext`,
|
|
1292
|
+
"agenticMemoryPackedContext",
|
|
1293
|
+
(fact) => fact.packedContext
|
|
1294
|
+
),
|
|
1295
|
+
status: solutionProjection(
|
|
1296
|
+
graph,
|
|
1297
|
+
projection,
|
|
1298
|
+
`${name}/status`,
|
|
1299
|
+
"agenticMemoryContextPackingStatus",
|
|
1300
|
+
(fact) => fact.status
|
|
1301
|
+
),
|
|
1302
|
+
errors: solutionProjection(
|
|
1303
|
+
graph,
|
|
1304
|
+
projection,
|
|
1305
|
+
`${name}/errors`,
|
|
1306
|
+
"agenticMemoryContextPackingErrors",
|
|
1307
|
+
(fact) => fact.errors
|
|
1308
|
+
),
|
|
1309
|
+
cursor: solutionProjection(
|
|
1310
|
+
graph,
|
|
1311
|
+
projection,
|
|
1312
|
+
`${name}/cursor`,
|
|
1313
|
+
"agenticMemoryContextPackingCursor",
|
|
1314
|
+
(fact) => fact.cursor
|
|
1315
|
+
)
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
function solutionProjection(graph, snapshot, name, factory, select) {
|
|
1319
|
+
return graph.node(
|
|
1320
|
+
[snapshot],
|
|
1321
|
+
(ctx) => {
|
|
1322
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
1323
|
+
ctx.down([["DATA", select(raw)]]);
|
|
1324
|
+
}
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
name,
|
|
1328
|
+
factory,
|
|
1329
|
+
completeWhenDepsComplete: false,
|
|
1330
|
+
errorWhenDepsError: false
|
|
1331
|
+
}
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1334
|
+
function agenticMemoryProjection(graph, snapshot, name, factory, select) {
|
|
1335
|
+
return graph.node(
|
|
1336
|
+
[snapshot],
|
|
1337
|
+
(ctx) => {
|
|
1338
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
1339
|
+
ctx.down([["DATA", select(raw)]]);
|
|
1340
|
+
}
|
|
1341
|
+
},
|
|
1342
|
+
{
|
|
1343
|
+
name,
|
|
1344
|
+
factory,
|
|
1345
|
+
completeWhenDepsComplete: false,
|
|
1346
|
+
errorWhenDepsError: false
|
|
1347
|
+
}
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1350
|
+
function agenticMemoryContextProjection(graph, projection, retrieval, name) {
|
|
1351
|
+
return graph.node(
|
|
1352
|
+
[projection, retrieval],
|
|
1353
|
+
(ctx) => {
|
|
1354
|
+
const projectionFact = depLatest(ctx, 0);
|
|
1355
|
+
const retrievalFacts = depBatch(ctx, 1) ?? [];
|
|
1356
|
+
if (projectionFact === void 0 || retrievalFacts.length === 0) return;
|
|
1357
|
+
for (const raw of retrievalFacts) {
|
|
1358
|
+
ctx.down([
|
|
1359
|
+
["DATA", contextFromSnapshot(projectionFact, raw)]
|
|
1360
|
+
]);
|
|
1361
|
+
}
|
|
1362
|
+
},
|
|
1363
|
+
{
|
|
1364
|
+
name,
|
|
1365
|
+
factory: "agenticMemoryContext",
|
|
1366
|
+
completeWhenDepsComplete: false,
|
|
1367
|
+
errorWhenDepsError: false
|
|
1368
|
+
}
|
|
1369
|
+
);
|
|
1370
|
+
}
|
|
1371
|
+
function contextFromSnapshot(projection, retrieval) {
|
|
1372
|
+
const entries = retrieval.ranked.results.map(
|
|
1373
|
+
(fragment) => Object.freeze({
|
|
1374
|
+
fragmentId: fragment.id,
|
|
1375
|
+
payload: fragment.payload,
|
|
1376
|
+
confidence: fragment.confidence,
|
|
1377
|
+
tags: fragment.tags,
|
|
1378
|
+
sources: fragment.sources,
|
|
1379
|
+
...projection.metadataByFragmentId[fragment.id] === void 0 ? {} : { record: projection.metadataByFragmentId[fragment.id] },
|
|
1380
|
+
fragment
|
|
1381
|
+
})
|
|
1382
|
+
);
|
|
1383
|
+
const hasContext = entries.length > 0;
|
|
1384
|
+
const state = contextState(projection.status.state, retrieval.status.state);
|
|
1385
|
+
return Object.freeze({
|
|
1386
|
+
state,
|
|
1387
|
+
query: retrieval.ranked.query,
|
|
1388
|
+
entries: Object.freeze(entries),
|
|
1389
|
+
cursor: retrieval.cursor,
|
|
1390
|
+
errors: projection.errors,
|
|
1391
|
+
retrievalErrors: retrieval.errors,
|
|
1392
|
+
contextReady: hasContext && (state === "ready" || state === "partial")
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
function agenticMemoryRecordProjection(graph, records, name) {
|
|
1396
|
+
return graph.node(
|
|
1397
|
+
[records],
|
|
1398
|
+
(ctx) => {
|
|
1399
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
1400
|
+
state.evaluation += 1;
|
|
1401
|
+
const rawRecords = (depBatch(ctx, 0) ?? []).at(-1);
|
|
1402
|
+
const projected = validateAndProjectRecords(rawRecords);
|
|
1403
|
+
const cursor = Object.freeze({
|
|
1404
|
+
evaluation: state.evaluation,
|
|
1405
|
+
validRecords: projected.records.length,
|
|
1406
|
+
invalidRecords: projected.invalidRecordIndexes.size,
|
|
1407
|
+
projectedFragments: projected.fragments.length
|
|
1408
|
+
});
|
|
1409
|
+
const status = Object.freeze({
|
|
1410
|
+
state: agenticStatusState(projected.errors.length, projected.records.length),
|
|
1411
|
+
cursor
|
|
1412
|
+
});
|
|
1413
|
+
const errors = Object.freeze(
|
|
1414
|
+
projected.errors.map(
|
|
1415
|
+
(error) => Object.freeze({
|
|
1416
|
+
...error,
|
|
1417
|
+
...error.validationErrors === void 0 ? {} : { validationErrors: Object.freeze([...error.validationErrors]) },
|
|
1418
|
+
cursor
|
|
1419
|
+
})
|
|
1420
|
+
)
|
|
1421
|
+
);
|
|
1422
|
+
ctx.state.set(state);
|
|
1423
|
+
ctx.down([
|
|
1424
|
+
[
|
|
1425
|
+
"DATA",
|
|
1426
|
+
Object.freeze({
|
|
1427
|
+
records: Object.freeze(projected.records),
|
|
1428
|
+
fragments: Object.freeze(projected.fragments),
|
|
1429
|
+
metadataByFragmentId: Object.freeze(projected.metadataByFragmentId),
|
|
1430
|
+
status,
|
|
1431
|
+
errors,
|
|
1432
|
+
cursor
|
|
1433
|
+
})
|
|
1434
|
+
]
|
|
1435
|
+
]);
|
|
1436
|
+
},
|
|
1437
|
+
{
|
|
1438
|
+
name,
|
|
1439
|
+
factory: "agenticMemoryProjection",
|
|
1440
|
+
completeWhenDepsComplete: false,
|
|
1441
|
+
errorWhenDepsError: false
|
|
1442
|
+
}
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1445
|
+
function validateAndProjectKgDrafts(value, records) {
|
|
1446
|
+
const assertions = [];
|
|
1447
|
+
const errors = [];
|
|
1448
|
+
let invalidDrafts = 0;
|
|
1449
|
+
if (!Array.isArray(value)) {
|
|
1450
|
+
return {
|
|
1451
|
+
assertions,
|
|
1452
|
+
invalidDrafts: 1,
|
|
1453
|
+
errors: [
|
|
1454
|
+
{
|
|
1455
|
+
code: "invalid-drafts-input",
|
|
1456
|
+
message: "agenticMemoryKgProjectionBundle: drafts input must be an array",
|
|
1457
|
+
draft: value
|
|
1458
|
+
}
|
|
1459
|
+
]
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
const length = safeArrayLength2(value);
|
|
1463
|
+
if (length === void 0) {
|
|
1464
|
+
return {
|
|
1465
|
+
assertions,
|
|
1466
|
+
invalidDrafts: 1,
|
|
1467
|
+
errors: [
|
|
1468
|
+
{
|
|
1469
|
+
code: "invalid-drafts-input",
|
|
1470
|
+
message: "agenticMemoryKgProjectionBundle: drafts input length could not be read",
|
|
1471
|
+
draft: value
|
|
1472
|
+
}
|
|
1473
|
+
]
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
const recordById = new Map(records.map((record) => [record.id, record]));
|
|
1477
|
+
const fragmentToRecord = new Map(records.map((record) => [record.fragment.id, record.id]));
|
|
1478
|
+
const seenAssertions = /* @__PURE__ */ new Set();
|
|
1479
|
+
for (let i = 0; i < length; i += 1) {
|
|
1480
|
+
let raw;
|
|
1481
|
+
try {
|
|
1482
|
+
raw = value[i];
|
|
1483
|
+
const result = validateKgDraft(raw, i);
|
|
1484
|
+
if (result.errors.length > 0 || result.draft === void 0) {
|
|
1485
|
+
invalidDrafts += 1;
|
|
1486
|
+
errors.push(...result.errors);
|
|
1487
|
+
continue;
|
|
1488
|
+
}
|
|
1489
|
+
const draft = result.draft;
|
|
1490
|
+
if (seenAssertions.has(draft.id)) {
|
|
1491
|
+
invalidDrafts += 1;
|
|
1492
|
+
errors.push({
|
|
1493
|
+
code: "duplicate-assertion-id",
|
|
1494
|
+
message: "agenticMemoryKgProjectionBundle: duplicate assertion id",
|
|
1495
|
+
index: i,
|
|
1496
|
+
assertionId: draft.id,
|
|
1497
|
+
recordId: draft.recordId,
|
|
1498
|
+
fragmentId: draft.fragmentId,
|
|
1499
|
+
draft: raw,
|
|
1500
|
+
validationErrors: [`duplicate assertion id '${draft.id}'`]
|
|
1501
|
+
});
|
|
1502
|
+
continue;
|
|
1503
|
+
}
|
|
1504
|
+
const record = recordById.get(draft.recordId);
|
|
1505
|
+
if (record === void 0) {
|
|
1506
|
+
invalidDrafts += 1;
|
|
1507
|
+
errors.push({
|
|
1508
|
+
code: "missing-record-ref",
|
|
1509
|
+
message: "agenticMemoryKgProjectionBundle: draft references a missing record",
|
|
1510
|
+
index: i,
|
|
1511
|
+
assertionId: draft.id,
|
|
1512
|
+
recordId: draft.recordId,
|
|
1513
|
+
fragmentId: draft.fragmentId,
|
|
1514
|
+
draft: raw,
|
|
1515
|
+
validationErrors: [`record '${draft.recordId}' is not projected`]
|
|
1516
|
+
});
|
|
1517
|
+
continue;
|
|
1518
|
+
}
|
|
1519
|
+
const owner = fragmentToRecord.get(draft.fragmentId);
|
|
1520
|
+
if (owner === void 0) {
|
|
1521
|
+
invalidDrafts += 1;
|
|
1522
|
+
errors.push({
|
|
1523
|
+
code: "missing-fragment-ref",
|
|
1524
|
+
message: "agenticMemoryKgProjectionBundle: draft references a missing fragment",
|
|
1525
|
+
index: i,
|
|
1526
|
+
assertionId: draft.id,
|
|
1527
|
+
recordId: draft.recordId,
|
|
1528
|
+
fragmentId: draft.fragmentId,
|
|
1529
|
+
draft: raw,
|
|
1530
|
+
validationErrors: [`fragment '${draft.fragmentId}' is not projected`]
|
|
1531
|
+
});
|
|
1532
|
+
continue;
|
|
1533
|
+
}
|
|
1534
|
+
if (owner !== draft.recordId || record.fragment.id !== draft.fragmentId) {
|
|
1535
|
+
invalidDrafts += 1;
|
|
1536
|
+
errors.push({
|
|
1537
|
+
code: "fragment-record-mismatch",
|
|
1538
|
+
message: "agenticMemoryKgProjectionBundle: draft record and fragment refs disagree",
|
|
1539
|
+
index: i,
|
|
1540
|
+
assertionId: draft.id,
|
|
1541
|
+
recordId: draft.recordId,
|
|
1542
|
+
fragmentId: draft.fragmentId,
|
|
1543
|
+
draft: raw,
|
|
1544
|
+
validationErrors: [
|
|
1545
|
+
`fragment '${draft.fragmentId}' belongs to record '${owner}', not '${draft.recordId}'`
|
|
1546
|
+
]
|
|
1547
|
+
});
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
seenAssertions.add(draft.id);
|
|
1551
|
+
assertions.push(
|
|
1552
|
+
Object.freeze({
|
|
1553
|
+
id: draft.id,
|
|
1554
|
+
recordId: draft.recordId,
|
|
1555
|
+
fragmentId: draft.fragmentId,
|
|
1556
|
+
subject: draft.subject,
|
|
1557
|
+
predicate: draft.predicate,
|
|
1558
|
+
object: draft.object,
|
|
1559
|
+
...draft.confidence === void 0 ? {} : { confidence: draft.confidence },
|
|
1560
|
+
sources: Object.freeze(draft.sources ?? [draft.fragmentId]),
|
|
1561
|
+
...draft.provenance === void 0 ? {} : { provenance: draft.provenance }
|
|
1562
|
+
})
|
|
1563
|
+
);
|
|
1564
|
+
} catch (error) {
|
|
1565
|
+
invalidDrafts += 1;
|
|
1566
|
+
errors.push({
|
|
1567
|
+
code: "invalid-draft",
|
|
1568
|
+
message: `agenticMemoryKgProjectionBundle: draft access failed: ${errorMessage2(error)}`,
|
|
1569
|
+
index: i,
|
|
1570
|
+
draft: raw,
|
|
1571
|
+
validationErrors: ["draft access failed"]
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
return { assertions, errors, invalidDrafts };
|
|
1576
|
+
}
|
|
1577
|
+
function validateKgDraft(value, index) {
|
|
1578
|
+
const errors = [];
|
|
1579
|
+
if (!isPlainRecord(value)) {
|
|
1580
|
+
return {
|
|
1581
|
+
errors: [
|
|
1582
|
+
{
|
|
1583
|
+
code: "invalid-draft",
|
|
1584
|
+
message: "agenticMemoryKgProjectionBundle: draft must be an object",
|
|
1585
|
+
index,
|
|
1586
|
+
draft: value
|
|
1587
|
+
}
|
|
1588
|
+
]
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
const raw = value;
|
|
1592
|
+
const id = typeof raw.id === "string" && raw.id.length > 0 ? raw.id : void 0;
|
|
1593
|
+
const recordId = typeof raw.recordId === "string" && raw.recordId.length > 0 ? raw.recordId : void 0;
|
|
1594
|
+
const fragmentId = typeof raw.fragmentId === "string" && raw.fragmentId.length > 0 ? raw.fragmentId : void 0;
|
|
1595
|
+
const subject = validateAssertionSubject(raw.subject);
|
|
1596
|
+
const object = validateAssertionObject(raw.object);
|
|
1597
|
+
const shapeErrors = [];
|
|
1598
|
+
if (id === void 0) shapeErrors.push("draft.id must be a non-empty string");
|
|
1599
|
+
if (recordId === void 0) {
|
|
1600
|
+
shapeErrors.push("draft.recordId must be a non-empty string");
|
|
1601
|
+
}
|
|
1602
|
+
if (fragmentId === void 0) {
|
|
1603
|
+
shapeErrors.push("draft.fragmentId must be a non-empty string");
|
|
1604
|
+
}
|
|
1605
|
+
shapeErrors.push(...subject.errors);
|
|
1606
|
+
if (typeof raw.predicate !== "string" || raw.predicate.length === 0) {
|
|
1607
|
+
shapeErrors.push("draft.predicate must be a non-empty string");
|
|
1608
|
+
}
|
|
1609
|
+
shapeErrors.push(...object.errors);
|
|
1610
|
+
if (raw.confidence !== void 0 && (!Number.isFinite(raw.confidence) || raw.confidence < 0 || raw.confidence > 1)) {
|
|
1611
|
+
shapeErrors.push("draft.confidence must be a finite number in [0, 1]");
|
|
1612
|
+
}
|
|
1613
|
+
if (raw.sources !== void 0 && !isDenseArrayOf3(raw.sources, isNonEmptyString)) {
|
|
1614
|
+
shapeErrors.push("draft.sources must be a readonly string array");
|
|
1615
|
+
}
|
|
1616
|
+
if (raw.provenance !== void 0 && typeof raw.provenance !== "string") {
|
|
1617
|
+
shapeErrors.push("draft.provenance must be a string when present");
|
|
1618
|
+
}
|
|
1619
|
+
if (shapeErrors.length > 0) errors.push(kgShapeError(index, value, ...shapeErrors));
|
|
1620
|
+
if (errors.length > 0 || id === void 0 || recordId === void 0 || fragmentId === void 0) {
|
|
1621
|
+
return { errors };
|
|
1622
|
+
}
|
|
1623
|
+
return {
|
|
1624
|
+
draft: Object.freeze({
|
|
1625
|
+
id,
|
|
1626
|
+
recordId,
|
|
1627
|
+
fragmentId,
|
|
1628
|
+
subject: subject.subject,
|
|
1629
|
+
predicate: raw.predicate,
|
|
1630
|
+
object: object.object,
|
|
1631
|
+
...raw.confidence === void 0 ? {} : { confidence: raw.confidence },
|
|
1632
|
+
...raw.sources === void 0 ? {} : { sources: Object.freeze([...raw.sources]) },
|
|
1633
|
+
...raw.provenance === void 0 ? {} : { provenance: raw.provenance }
|
|
1634
|
+
}),
|
|
1635
|
+
errors
|
|
1636
|
+
};
|
|
1637
|
+
}
|
|
1638
|
+
function validateAssertionSubject(value) {
|
|
1639
|
+
if (!isPlainRecord(value)) return { errors: ["subject must be an object"] };
|
|
1640
|
+
const id = value.id;
|
|
1641
|
+
const type = value.type;
|
|
1642
|
+
const errors = [];
|
|
1643
|
+
if (typeof id !== "string" || id.length === 0) errors.push("subject.id must be non-empty");
|
|
1644
|
+
if (type !== void 0 && (typeof type !== "string" || type.length === 0)) {
|
|
1645
|
+
errors.push("subject.type must be a non-empty string when present");
|
|
1646
|
+
}
|
|
1647
|
+
if (errors.length > 0) return { errors };
|
|
1648
|
+
return {
|
|
1649
|
+
subject: Object.freeze({
|
|
1650
|
+
id,
|
|
1651
|
+
...type === void 0 ? {} : { type }
|
|
1652
|
+
}),
|
|
1653
|
+
errors
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
function validateAssertionObject(value) {
|
|
1657
|
+
if (!isPlainRecord(value)) return { errors: ["object must be an object"] };
|
|
1658
|
+
const kind = value.kind;
|
|
1659
|
+
const errors = [];
|
|
1660
|
+
if (kind === "entity") {
|
|
1661
|
+
if (typeof value.id !== "string" || value.id.length === 0) {
|
|
1662
|
+
errors.push("object.id must be non-empty for entity objects");
|
|
1663
|
+
}
|
|
1664
|
+
if (value.type !== void 0 && (typeof value.type !== "string" || value.type.length === 0)) {
|
|
1665
|
+
errors.push("object.type must be a non-empty string when present");
|
|
1666
|
+
}
|
|
1667
|
+
if (Object.hasOwn(value, "value")) errors.push("entity object must not include value");
|
|
1668
|
+
if (errors.length > 0) return { errors };
|
|
1669
|
+
return {
|
|
1670
|
+
object: Object.freeze({
|
|
1671
|
+
kind: "entity",
|
|
1672
|
+
id: value.id,
|
|
1673
|
+
...value.type === void 0 ? {} : { type: value.type }
|
|
1674
|
+
}),
|
|
1675
|
+
errors
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
if (kind === "value") {
|
|
1679
|
+
if (!Object.hasOwn(value, "value")) errors.push("value object must include value");
|
|
1680
|
+
else {
|
|
1681
|
+
try {
|
|
1682
|
+
assertStrictJsonValue(value.value, "object.value");
|
|
1683
|
+
} catch (error) {
|
|
1684
|
+
errors.push(errorMessage2(error));
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
if (value.valueType !== void 0 && (typeof value.valueType !== "string" || value.valueType.length === 0)) {
|
|
1688
|
+
errors.push("object.valueType must be a non-empty string when present");
|
|
1689
|
+
}
|
|
1690
|
+
if (Object.hasOwn(value, "id")) errors.push("value object must not include id");
|
|
1691
|
+
if (errors.length > 0) return { errors };
|
|
1692
|
+
return {
|
|
1693
|
+
object: Object.freeze({
|
|
1694
|
+
kind: "value",
|
|
1695
|
+
value: value.value,
|
|
1696
|
+
...value.valueType === void 0 ? {} : { valueType: value.valueType }
|
|
1697
|
+
}),
|
|
1698
|
+
errors
|
|
1699
|
+
};
|
|
1700
|
+
}
|
|
1701
|
+
return { errors: ["object.kind must be entity or value"] };
|
|
1702
|
+
}
|
|
1703
|
+
function kgShapeError(index, draft, ...validationErrors) {
|
|
1704
|
+
return {
|
|
1705
|
+
code: "invalid-assertion-shape",
|
|
1706
|
+
message: "agenticMemoryKgProjectionBundle: draft assertion shape is invalid",
|
|
1707
|
+
index,
|
|
1708
|
+
draft,
|
|
1709
|
+
validationErrors: Object.freeze([...validationErrors])
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
function kgErrorFromRecordError(error) {
|
|
1713
|
+
return {
|
|
1714
|
+
...error,
|
|
1715
|
+
code: error.code
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
function fragmentFrame(fragment) {
|
|
1719
|
+
return Object.freeze({
|
|
1720
|
+
id: fragment.id,
|
|
1721
|
+
payload: fragment.payload,
|
|
1722
|
+
tNs: decimalBigIntString(fragment.tNs, "fragment.tNs"),
|
|
1723
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: decimalBigIntString(fragment.validFrom, "fragment.validFrom") },
|
|
1724
|
+
...fragment.validTo === void 0 ? {} : { validTo: decimalBigIntString(fragment.validTo, "fragment.validTo") },
|
|
1725
|
+
confidence: fragment.confidence,
|
|
1726
|
+
tags: Object.freeze([...fragment.tags]),
|
|
1727
|
+
sources: Object.freeze([...fragment.sources]),
|
|
1728
|
+
...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
|
|
1729
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
1730
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
function recordFromFrame(frame) {
|
|
1734
|
+
const fragment = frame.record.fragment;
|
|
1735
|
+
const record = {
|
|
1736
|
+
id: assertNonEmptyString(frame.record.id, "record.id"),
|
|
1737
|
+
kind: assertKindValue(frame.record.kind),
|
|
1738
|
+
persistenceLevel: assertPersistenceLevelValue(frame.record.persistenceLevel),
|
|
1739
|
+
artifactKind: assertArtifactKindValue(frame.record.artifactKind),
|
|
1740
|
+
...frame.record.scope === void 0 ? {} : { scope: assertScopeFrame(frame.record.scope) },
|
|
1741
|
+
fragment: {
|
|
1742
|
+
id: assertNonEmptyString(fragment.id, "fragment.id"),
|
|
1743
|
+
payload: assertStrictJsonValue(fragment.payload, "fragment.payload"),
|
|
1744
|
+
tNs: parseDecimalBigInt(fragment.tNs, "fragment.tNs"),
|
|
1745
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: parseDecimalBigInt(fragment.validFrom, "fragment.validFrom") },
|
|
1746
|
+
...fragment.validTo === void 0 ? {} : { validTo: parseDecimalBigInt(fragment.validTo, "fragment.validTo") },
|
|
1747
|
+
confidence: assertConfidence(fragment.confidence, "fragment.confidence"),
|
|
1748
|
+
tags: assertStringArray(fragment.tags, "fragment.tags"),
|
|
1749
|
+
sources: assertStringArray(fragment.sources, "fragment.sources"),
|
|
1750
|
+
...fragment.embedding === void 0 ? {} : { embedding: assertFiniteNumberArray(fragment.embedding, "fragment.embedding") },
|
|
1751
|
+
...fragment.parentFragmentId === void 0 ? {} : {
|
|
1752
|
+
parentFragmentId: assertNonEmptyString(fragment.parentFragmentId, "parentFragmentId")
|
|
1753
|
+
},
|
|
1754
|
+
...fragment.provenance === void 0 ? {} : { provenance: assertString(fragment.provenance, "provenance") }
|
|
1755
|
+
}
|
|
1756
|
+
};
|
|
1757
|
+
const result = validateAndSnapshotRecord(record, 0);
|
|
1758
|
+
if (result.errors.length > 0 || result.record === void 0) {
|
|
1759
|
+
throw new TypeError(
|
|
1760
|
+
`agenticMemoryRecordFrame: decoded record is invalid: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
|
|
1761
|
+
);
|
|
1762
|
+
}
|
|
1763
|
+
return result.record;
|
|
1764
|
+
}
|
|
1765
|
+
function projectRetention(value, records) {
|
|
1766
|
+
const byId = new Map(records.map((record) => [record.id, record]));
|
|
1767
|
+
const view = new Map(records.map((record) => [record.id, record]));
|
|
1768
|
+
const requests = [];
|
|
1769
|
+
const errors = [];
|
|
1770
|
+
let validCommands = 0;
|
|
1771
|
+
let invalidCommands = 0;
|
|
1772
|
+
if (!Array.isArray(value)) {
|
|
1773
|
+
return {
|
|
1774
|
+
activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
|
|
1775
|
+
archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
|
|
1776
|
+
consolidationRequests: requests,
|
|
1777
|
+
validCommands,
|
|
1778
|
+
invalidCommands: 1,
|
|
1779
|
+
errors: [
|
|
1780
|
+
{
|
|
1781
|
+
code: "invalid-commands-input",
|
|
1782
|
+
message: "agenticMemoryRetentionBundle: commands input must be an array",
|
|
1783
|
+
command: value
|
|
1784
|
+
}
|
|
1785
|
+
]
|
|
1786
|
+
};
|
|
1787
|
+
}
|
|
1788
|
+
const length = safeArrayLength2(value);
|
|
1789
|
+
if (length === void 0) {
|
|
1790
|
+
return {
|
|
1791
|
+
activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
|
|
1792
|
+
archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
|
|
1793
|
+
consolidationRequests: requests,
|
|
1794
|
+
validCommands,
|
|
1795
|
+
invalidCommands: 1,
|
|
1796
|
+
errors: [
|
|
1797
|
+
{
|
|
1798
|
+
code: "invalid-commands-input",
|
|
1799
|
+
message: "agenticMemoryRetentionBundle: commands input length could not be read",
|
|
1800
|
+
command: value
|
|
1801
|
+
}
|
|
1802
|
+
]
|
|
1803
|
+
};
|
|
1804
|
+
}
|
|
1805
|
+
const seenCommands = /* @__PURE__ */ new Set();
|
|
1806
|
+
for (let i = 0; i < length; i += 1) {
|
|
1807
|
+
let raw;
|
|
1808
|
+
try {
|
|
1809
|
+
raw = value[i];
|
|
1810
|
+
const result = validateRetentionCommand(raw, i);
|
|
1811
|
+
if (result.errors.length > 0 || result.command === void 0) {
|
|
1812
|
+
invalidCommands += 1;
|
|
1813
|
+
errors.push(...result.errors);
|
|
1814
|
+
continue;
|
|
1815
|
+
}
|
|
1816
|
+
const command = result.command;
|
|
1817
|
+
if (seenCommands.has(command.id)) {
|
|
1818
|
+
invalidCommands += 1;
|
|
1819
|
+
errors.push({
|
|
1820
|
+
code: "duplicate-command-id",
|
|
1821
|
+
message: "agenticMemoryRetentionBundle: duplicate command id",
|
|
1822
|
+
index: i,
|
|
1823
|
+
commandId: command.id,
|
|
1824
|
+
command: raw,
|
|
1825
|
+
validationErrors: [`duplicate command id '${command.id}'`]
|
|
1826
|
+
});
|
|
1827
|
+
continue;
|
|
1828
|
+
}
|
|
1829
|
+
const missing = retentionMissingRecords(command, byId);
|
|
1830
|
+
if (missing.length > 0) {
|
|
1831
|
+
invalidCommands += 1;
|
|
1832
|
+
errors.push({
|
|
1833
|
+
code: "missing-record-ref",
|
|
1834
|
+
message: "agenticMemoryRetentionBundle: command references missing records",
|
|
1835
|
+
index: i,
|
|
1836
|
+
commandId: command.id,
|
|
1837
|
+
recordId: "recordId" in command ? command.recordId : void 0,
|
|
1838
|
+
recordIds: Object.freeze(missing),
|
|
1839
|
+
command: raw,
|
|
1840
|
+
validationErrors: Object.freeze(missing.map((id) => `record '${id}' is not projected`))
|
|
1841
|
+
});
|
|
1842
|
+
continue;
|
|
1843
|
+
}
|
|
1844
|
+
seenCommands.add(command.id);
|
|
1845
|
+
validCommands += 1;
|
|
1846
|
+
applyRetentionCommand(command, byId, view, requests);
|
|
1847
|
+
} catch (error) {
|
|
1848
|
+
invalidCommands += 1;
|
|
1849
|
+
errors.push({
|
|
1850
|
+
code: "invalid-command",
|
|
1851
|
+
message: `agenticMemoryRetentionBundle: command access failed: ${errorMessage2(error)}`,
|
|
1852
|
+
index: i,
|
|
1853
|
+
command: raw,
|
|
1854
|
+
validationErrors: ["command access failed"]
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
const projected = records.map((record) => view.get(record.id) ?? record);
|
|
1859
|
+
return {
|
|
1860
|
+
activeRecords: projected.filter((record) => record.persistenceLevel !== "archived"),
|
|
1861
|
+
archivedRecords: projected.filter((record) => record.persistenceLevel === "archived"),
|
|
1862
|
+
consolidationRequests: requests,
|
|
1863
|
+
errors,
|
|
1864
|
+
validCommands,
|
|
1865
|
+
invalidCommands
|
|
1866
|
+
};
|
|
1867
|
+
}
|
|
1868
|
+
function validateRetentionCommand(value, index) {
|
|
1869
|
+
if (!isPlainRecord(value)) {
|
|
1870
|
+
return {
|
|
1871
|
+
errors: [
|
|
1872
|
+
{
|
|
1873
|
+
code: "invalid-command",
|
|
1874
|
+
message: "agenticMemoryRetentionBundle: command must be an object",
|
|
1875
|
+
index,
|
|
1876
|
+
command: value
|
|
1877
|
+
}
|
|
1878
|
+
]
|
|
1879
|
+
};
|
|
1880
|
+
}
|
|
1881
|
+
const id = typeof value.id === "string" && value.id.length > 0 ? value.id : void 0;
|
|
1882
|
+
const kind = value.kind;
|
|
1883
|
+
const errors = [];
|
|
1884
|
+
if (id === void 0) errors.push("command.id must be a non-empty string");
|
|
1885
|
+
if (kind !== "archive" && kind !== "restore" && kind !== "setPersistenceLevel" && kind !== "requestConsolidation") {
|
|
1886
|
+
errors.push("command.kind is invalid");
|
|
1887
|
+
}
|
|
1888
|
+
if (value.reason !== void 0 && typeof value.reason !== "string") {
|
|
1889
|
+
errors.push("command.reason must be a string when present");
|
|
1890
|
+
}
|
|
1891
|
+
if (kind === "archive") {
|
|
1892
|
+
if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
|
|
1893
|
+
} else if (kind === "restore") {
|
|
1894
|
+
if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
|
|
1895
|
+
if (value.persistenceLevel !== void 0 && (!isAgenticMemoryPersistenceLevel(value.persistenceLevel) || value.persistenceLevel === "archived")) {
|
|
1896
|
+
errors.push("restore.persistenceLevel must be a non-archived persistence level when present");
|
|
1897
|
+
}
|
|
1898
|
+
} else if (kind === "setPersistenceLevel") {
|
|
1899
|
+
if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
|
|
1900
|
+
if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
|
|
1901
|
+
errors.push("setPersistenceLevel.persistenceLevel is invalid");
|
|
1902
|
+
}
|
|
1903
|
+
} else if (kind === "requestConsolidation") {
|
|
1904
|
+
if (!isDenseArrayOf3(value.recordIds, isNonEmptyString) || value.recordIds.length === 0) {
|
|
1905
|
+
errors.push("requestConsolidation.recordIds must be a non-empty string array");
|
|
1906
|
+
}
|
|
1907
|
+
if (value.requestId !== void 0 && (typeof value.requestId !== "string" || value.requestId.length === 0)) {
|
|
1908
|
+
errors.push("requestConsolidation.requestId must be non-empty when present");
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
if (errors.length > 0 || id === void 0) {
|
|
1912
|
+
return {
|
|
1913
|
+
errors: [
|
|
1914
|
+
{
|
|
1915
|
+
code: "invalid-command",
|
|
1916
|
+
message: "agenticMemoryRetentionBundle: command is invalid",
|
|
1917
|
+
index,
|
|
1918
|
+
commandId: id,
|
|
1919
|
+
command: value,
|
|
1920
|
+
validationErrors: Object.freeze(errors)
|
|
1921
|
+
}
|
|
1922
|
+
]
|
|
1923
|
+
};
|
|
1924
|
+
}
|
|
1925
|
+
const base = { id, reason: value.reason };
|
|
1926
|
+
if (kind === "archive") {
|
|
1927
|
+
return {
|
|
1928
|
+
command: Object.freeze({
|
|
1929
|
+
...base,
|
|
1930
|
+
kind,
|
|
1931
|
+
recordId: value.recordId,
|
|
1932
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1933
|
+
}),
|
|
1934
|
+
errors: []
|
|
1935
|
+
};
|
|
1936
|
+
}
|
|
1937
|
+
if (kind === "restore") {
|
|
1938
|
+
return {
|
|
1939
|
+
command: Object.freeze({
|
|
1940
|
+
...base,
|
|
1941
|
+
kind,
|
|
1942
|
+
recordId: value.recordId,
|
|
1943
|
+
...value.persistenceLevel === void 0 ? {} : {
|
|
1944
|
+
persistenceLevel: value.persistenceLevel
|
|
1945
|
+
},
|
|
1946
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1947
|
+
}),
|
|
1948
|
+
errors: []
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
if (kind === "setPersistenceLevel") {
|
|
1952
|
+
return {
|
|
1953
|
+
command: Object.freeze({
|
|
1954
|
+
...base,
|
|
1955
|
+
kind,
|
|
1956
|
+
recordId: value.recordId,
|
|
1957
|
+
persistenceLevel: value.persistenceLevel,
|
|
1958
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1959
|
+
}),
|
|
1960
|
+
errors: []
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1963
|
+
return {
|
|
1964
|
+
command: Object.freeze({
|
|
1965
|
+
...base,
|
|
1966
|
+
kind: "requestConsolidation",
|
|
1967
|
+
recordIds: Object.freeze([...value.recordIds]),
|
|
1968
|
+
...value.requestId === void 0 ? {} : { requestId: value.requestId },
|
|
1969
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1970
|
+
}),
|
|
1971
|
+
errors: []
|
|
1972
|
+
};
|
|
1973
|
+
}
|
|
1974
|
+
function retentionMissingRecords(command, records) {
|
|
1975
|
+
if ("recordId" in command) return records.has(command.recordId) ? [] : [command.recordId];
|
|
1976
|
+
return command.recordIds.filter((recordId) => !records.has(recordId));
|
|
1977
|
+
}
|
|
1978
|
+
function applyRetentionCommand(command, source, view, requests) {
|
|
1979
|
+
if (command.kind === "requestConsolidation") {
|
|
1980
|
+
requests.push(
|
|
1981
|
+
Object.freeze({
|
|
1982
|
+
id: command.requestId ?? command.id,
|
|
1983
|
+
commandId: command.id,
|
|
1984
|
+
recordIds: Object.freeze([...command.recordIds]),
|
|
1985
|
+
...command.reason === void 0 ? {} : { reason: command.reason }
|
|
1986
|
+
})
|
|
1987
|
+
);
|
|
1988
|
+
return;
|
|
1989
|
+
}
|
|
1990
|
+
const record = view.get(command.recordId) ?? source.get(command.recordId);
|
|
1991
|
+
if (record === void 0) return;
|
|
1992
|
+
const persistenceLevel = command.kind === "archive" ? "archived" : command.kind === "restore" ? command.persistenceLevel ?? nonArchivedLevel(source.get(command.recordId) ?? record) : command.persistenceLevel;
|
|
1993
|
+
view.set(command.recordId, withPersistenceLevel(record, persistenceLevel));
|
|
1994
|
+
}
|
|
1995
|
+
function nonArchivedLevel(record) {
|
|
1996
|
+
return record.persistenceLevel === "archived" ? "session" : record.persistenceLevel;
|
|
1997
|
+
}
|
|
1998
|
+
function withPersistenceLevel(record, persistenceLevel) {
|
|
1999
|
+
return Object.freeze({
|
|
2000
|
+
...record,
|
|
2001
|
+
persistenceLevel
|
|
2002
|
+
});
|
|
2003
|
+
}
|
|
2004
|
+
function retentionErrorFromRecordError(error) {
|
|
2005
|
+
return {
|
|
2006
|
+
...error,
|
|
2007
|
+
code: error.code
|
|
2008
|
+
};
|
|
2009
|
+
}
|
|
2010
|
+
function validateConsolidationRequests(value, records) {
|
|
2011
|
+
const byId = new Map(records.map((record) => [record.id, record]));
|
|
2012
|
+
const requests = [];
|
|
2013
|
+
const errors = [];
|
|
2014
|
+
if (!Array.isArray(value)) {
|
|
2015
|
+
return {
|
|
2016
|
+
requests,
|
|
2017
|
+
errors: [
|
|
2018
|
+
{
|
|
2019
|
+
code: "invalid-commands-input",
|
|
2020
|
+
message: "agenticMemoryConsolidationBundle: requests input must be an array",
|
|
2021
|
+
command: value
|
|
2022
|
+
}
|
|
2023
|
+
]
|
|
2024
|
+
};
|
|
2025
|
+
}
|
|
2026
|
+
const length = safeArrayLength2(value);
|
|
2027
|
+
if (length === void 0) {
|
|
2028
|
+
return {
|
|
2029
|
+
requests,
|
|
2030
|
+
errors: [
|
|
2031
|
+
{
|
|
2032
|
+
code: "invalid-commands-input",
|
|
2033
|
+
message: "agenticMemoryConsolidationBundle: requests input length could not be read",
|
|
2034
|
+
command: value
|
|
2035
|
+
}
|
|
2036
|
+
]
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2040
|
+
for (let i = 0; i < length; i += 1) {
|
|
2041
|
+
let raw;
|
|
2042
|
+
try {
|
|
2043
|
+
if (!Object.hasOwn(value, i)) {
|
|
2044
|
+
throw new TypeError("request array must be dense");
|
|
2045
|
+
}
|
|
2046
|
+
raw = value[i];
|
|
2047
|
+
} catch (error) {
|
|
2048
|
+
errors.push({
|
|
2049
|
+
code: "invalid-command",
|
|
2050
|
+
message: `agenticMemoryConsolidationBundle: request access failed: ${errorMessage2(error)}`,
|
|
2051
|
+
index: i,
|
|
2052
|
+
validationErrors: Object.freeze(["request access failed"])
|
|
2053
|
+
});
|
|
2054
|
+
continue;
|
|
2055
|
+
}
|
|
2056
|
+
if (!isPlainRecord(raw)) {
|
|
2057
|
+
errors.push({
|
|
2058
|
+
code: "invalid-command",
|
|
2059
|
+
message: "agenticMemoryConsolidationBundle: request must be an object",
|
|
2060
|
+
index: i,
|
|
2061
|
+
command: raw
|
|
2062
|
+
});
|
|
2063
|
+
continue;
|
|
2064
|
+
}
|
|
2065
|
+
const id = isNonEmptyString(raw.id) ? raw.id : void 0;
|
|
2066
|
+
const commandId = isNonEmptyString(raw.commandId) ? raw.commandId : void 0;
|
|
2067
|
+
const recordIds = isDenseArrayOf3(raw.recordIds, isNonEmptyString) ? Object.freeze([...raw.recordIds]) : void 0;
|
|
2068
|
+
const validationErrors = [];
|
|
2069
|
+
if (id === void 0) validationErrors.push("request.id must be a non-empty string");
|
|
2070
|
+
if (commandId === void 0) {
|
|
2071
|
+
validationErrors.push("request.commandId must be a non-empty string");
|
|
2072
|
+
}
|
|
2073
|
+
if (recordIds === void 0 || recordIds.length === 0) {
|
|
2074
|
+
validationErrors.push("request.recordIds must be a non-empty string array");
|
|
2075
|
+
}
|
|
2076
|
+
if (raw.reason !== void 0 && typeof raw.reason !== "string") {
|
|
2077
|
+
validationErrors.push("request.reason must be a string when present");
|
|
2078
|
+
}
|
|
2079
|
+
if (id !== void 0 && seen.has(id)) {
|
|
2080
|
+
validationErrors.push(`duplicate request id '${id}'`);
|
|
2081
|
+
}
|
|
2082
|
+
const missing = (recordIds ?? []).filter((recordId) => !byId.has(recordId));
|
|
2083
|
+
if (missing.length > 0) {
|
|
2084
|
+
errors.push({
|
|
2085
|
+
code: "missing-record-ref",
|
|
2086
|
+
message: "agenticMemoryConsolidationBundle: request references missing records",
|
|
2087
|
+
index: i,
|
|
2088
|
+
commandId,
|
|
2089
|
+
recordIds: Object.freeze(missing),
|
|
2090
|
+
command: raw,
|
|
2091
|
+
validationErrors: Object.freeze(
|
|
2092
|
+
missing.map((recordId) => `record '${recordId}' is not projected`)
|
|
2093
|
+
)
|
|
2094
|
+
});
|
|
2095
|
+
continue;
|
|
2096
|
+
}
|
|
2097
|
+
if (validationErrors.length > 0 || id === void 0 || commandId === void 0 || recordIds === void 0) {
|
|
2098
|
+
errors.push({
|
|
2099
|
+
code: "invalid-command",
|
|
2100
|
+
message: "agenticMemoryConsolidationBundle: request is invalid",
|
|
2101
|
+
index: i,
|
|
2102
|
+
commandId,
|
|
2103
|
+
recordIds,
|
|
2104
|
+
command: raw,
|
|
2105
|
+
validationErrors: Object.freeze(validationErrors)
|
|
2106
|
+
});
|
|
2107
|
+
continue;
|
|
2108
|
+
}
|
|
2109
|
+
seen.add(id);
|
|
2110
|
+
requests.push(
|
|
2111
|
+
Object.freeze({
|
|
2112
|
+
id,
|
|
2113
|
+
commandId,
|
|
2114
|
+
recordIds,
|
|
2115
|
+
...raw.reason === void 0 ? {} : { reason: raw.reason }
|
|
2116
|
+
})
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
return { requests: Object.freeze(requests), errors };
|
|
2120
|
+
}
|
|
2121
|
+
function projectConsolidationOutcomes(value, requests, evaluation) {
|
|
2122
|
+
const byRequest = new Map(requests.map((request) => [request.id, request]));
|
|
2123
|
+
const results = [];
|
|
2124
|
+
const proposedRecordDrafts = [];
|
|
2125
|
+
const commands = [];
|
|
2126
|
+
const errors = [];
|
|
2127
|
+
let validOutcomes = 0;
|
|
2128
|
+
let invalidOutcomes = 0;
|
|
2129
|
+
if (!Array.isArray(value)) {
|
|
2130
|
+
return {
|
|
2131
|
+
results,
|
|
2132
|
+
proposedRecordDrafts,
|
|
2133
|
+
commands,
|
|
2134
|
+
validOutcomes,
|
|
2135
|
+
invalidOutcomes: 1,
|
|
2136
|
+
errors: [
|
|
2137
|
+
{
|
|
2138
|
+
code: "invalid-outcomes-input",
|
|
2139
|
+
message: "agenticMemoryConsolidationBundle: outcomes input must be an array",
|
|
2140
|
+
outcome: value
|
|
2141
|
+
}
|
|
2142
|
+
]
|
|
2143
|
+
};
|
|
2144
|
+
}
|
|
2145
|
+
const length = safeArrayLength2(value);
|
|
2146
|
+
if (length === void 0) {
|
|
2147
|
+
return {
|
|
2148
|
+
results,
|
|
2149
|
+
proposedRecordDrafts,
|
|
2150
|
+
commands,
|
|
2151
|
+
validOutcomes,
|
|
2152
|
+
invalidOutcomes: 1,
|
|
2153
|
+
errors: [
|
|
2154
|
+
{
|
|
2155
|
+
code: "invalid-outcomes-input",
|
|
2156
|
+
message: "agenticMemoryConsolidationBundle: outcomes input length could not be read",
|
|
2157
|
+
outcome: value
|
|
2158
|
+
}
|
|
2159
|
+
]
|
|
2160
|
+
};
|
|
2161
|
+
}
|
|
2162
|
+
const seenOutcomes = /* @__PURE__ */ new Set();
|
|
2163
|
+
for (let i = 0; i < length; i += 1) {
|
|
2164
|
+
let raw;
|
|
2165
|
+
let outcome;
|
|
2166
|
+
try {
|
|
2167
|
+
if (!Object.hasOwn(value, i)) {
|
|
2168
|
+
throw new TypeError("outcome array must be dense");
|
|
2169
|
+
}
|
|
2170
|
+
raw = value[i];
|
|
2171
|
+
outcome = validateConsolidationOutcome(raw, i);
|
|
2172
|
+
} catch (error) {
|
|
2173
|
+
invalidOutcomes += 1;
|
|
2174
|
+
errors.push({
|
|
2175
|
+
code: "invalid-outcome",
|
|
2176
|
+
message: `agenticMemoryConsolidationBundle: outcome access failed: ${errorMessage2(error)}`,
|
|
2177
|
+
index: i,
|
|
2178
|
+
outcome: raw,
|
|
2179
|
+
validationErrors: Object.freeze(["outcome access failed"])
|
|
2180
|
+
});
|
|
2181
|
+
continue;
|
|
2182
|
+
}
|
|
2183
|
+
if (outcome.error !== void 0 || outcome.outcome === void 0) {
|
|
2184
|
+
invalidOutcomes += 1;
|
|
2185
|
+
if (outcome.error !== void 0) errors.push(outcome.error);
|
|
2186
|
+
continue;
|
|
2187
|
+
}
|
|
2188
|
+
const validOutcome = outcome.outcome;
|
|
2189
|
+
if (seenOutcomes.has(validOutcome.id)) {
|
|
2190
|
+
invalidOutcomes += 1;
|
|
2191
|
+
errors.push({
|
|
2192
|
+
code: "duplicate-outcome-id",
|
|
2193
|
+
message: "agenticMemoryConsolidationBundle: duplicate outcome id",
|
|
2194
|
+
index: i,
|
|
2195
|
+
outcomeId: validOutcome.id,
|
|
2196
|
+
requestId: validOutcome.requestId,
|
|
2197
|
+
outcome: raw,
|
|
2198
|
+
validationErrors: Object.freeze([`duplicate outcome id '${validOutcome.id}'`])
|
|
2199
|
+
});
|
|
2200
|
+
continue;
|
|
2201
|
+
}
|
|
2202
|
+
const request = byRequest.get(validOutcome.requestId);
|
|
2203
|
+
if (request === void 0) {
|
|
2204
|
+
invalidOutcomes += 1;
|
|
2205
|
+
errors.push({
|
|
2206
|
+
code: "missing-request-ref",
|
|
2207
|
+
message: "agenticMemoryConsolidationBundle: outcome references missing request",
|
|
2208
|
+
index: i,
|
|
2209
|
+
outcomeId: validOutcome.id,
|
|
2210
|
+
requestId: validOutcome.requestId,
|
|
2211
|
+
outcome: raw,
|
|
2212
|
+
validationErrors: Object.freeze([`request '${validOutcome.requestId}' is not projected`])
|
|
2213
|
+
});
|
|
2214
|
+
continue;
|
|
2215
|
+
}
|
|
2216
|
+
seenOutcomes.add(validOutcome.id);
|
|
2217
|
+
validOutcomes += 1;
|
|
2218
|
+
if (validOutcome.kind === "failed") {
|
|
2219
|
+
const resultId2 = `${validOutcome.requestId}:${validOutcome.id}`;
|
|
2220
|
+
results.push(
|
|
2221
|
+
Object.freeze({
|
|
2222
|
+
id: resultId2,
|
|
2223
|
+
requestId: validOutcome.requestId,
|
|
2224
|
+
outcomeId: validOutcome.id,
|
|
2225
|
+
state: "failed",
|
|
2226
|
+
sourceRecordIds: request.recordIds,
|
|
2227
|
+
proposedRecordIds: Object.freeze([]),
|
|
2228
|
+
message: validOutcome.message,
|
|
2229
|
+
...validOutcome.provenance === void 0 ? {} : { provenance: validOutcome.provenance }
|
|
2230
|
+
})
|
|
2231
|
+
);
|
|
2232
|
+
commands.push(
|
|
2233
|
+
Object.freeze({
|
|
2234
|
+
id: `${resultId2}:markFailed`,
|
|
2235
|
+
kind: "markFailed",
|
|
2236
|
+
requestId: validOutcome.requestId,
|
|
2237
|
+
outcomeId: validOutcome.id,
|
|
2238
|
+
message: validOutcome.message
|
|
2239
|
+
})
|
|
2240
|
+
);
|
|
2241
|
+
continue;
|
|
2242
|
+
}
|
|
2243
|
+
const draftIds = validOutcome.records.map(
|
|
2244
|
+
(record) => `${validOutcome.requestId}:${validOutcome.id}:${record.id}`
|
|
2245
|
+
);
|
|
2246
|
+
for (let recordIndex = 0; recordIndex < validOutcome.records.length; recordIndex += 1) {
|
|
2247
|
+
proposedRecordDrafts.push(
|
|
2248
|
+
Object.freeze({
|
|
2249
|
+
id: draftIds[recordIndex],
|
|
2250
|
+
requestId: validOutcome.requestId,
|
|
2251
|
+
outcomeId: validOutcome.id,
|
|
2252
|
+
record: validOutcome.records[recordIndex]
|
|
2253
|
+
})
|
|
2254
|
+
);
|
|
2255
|
+
}
|
|
2256
|
+
const resultId = `${validOutcome.requestId}:${validOutcome.id}`;
|
|
2257
|
+
results.push(
|
|
2258
|
+
Object.freeze({
|
|
2259
|
+
id: resultId,
|
|
2260
|
+
requestId: validOutcome.requestId,
|
|
2261
|
+
outcomeId: validOutcome.id,
|
|
2262
|
+
state: "proposed",
|
|
2263
|
+
sourceRecordIds: request.recordIds,
|
|
2264
|
+
proposedRecordIds: Object.freeze(validOutcome.records.map((record) => record.id)),
|
|
2265
|
+
...validOutcome.provenance === void 0 ? {} : { provenance: validOutcome.provenance }
|
|
2266
|
+
})
|
|
2267
|
+
);
|
|
2268
|
+
commands.push(
|
|
2269
|
+
Object.freeze({
|
|
2270
|
+
id: `${resultId}:proposeRecords`,
|
|
2271
|
+
kind: "proposeRecords",
|
|
2272
|
+
requestId: validOutcome.requestId,
|
|
2273
|
+
outcomeId: validOutcome.id,
|
|
2274
|
+
draftIds: Object.freeze(draftIds)
|
|
2275
|
+
})
|
|
2276
|
+
);
|
|
2277
|
+
}
|
|
2278
|
+
void evaluation;
|
|
2279
|
+
return {
|
|
2280
|
+
results: Object.freeze(results),
|
|
2281
|
+
proposedRecordDrafts: Object.freeze(proposedRecordDrafts),
|
|
2282
|
+
commands: Object.freeze(commands),
|
|
2283
|
+
errors,
|
|
2284
|
+
validOutcomes,
|
|
2285
|
+
invalidOutcomes
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
function validateConsolidationOutcome(value, index) {
|
|
2289
|
+
if (!isPlainRecord(value)) {
|
|
2290
|
+
return {
|
|
2291
|
+
error: {
|
|
2292
|
+
code: "invalid-outcome",
|
|
2293
|
+
message: "agenticMemoryConsolidationBundle: outcome must be an object",
|
|
2294
|
+
index,
|
|
2295
|
+
outcome: value
|
|
2296
|
+
}
|
|
2297
|
+
};
|
|
2298
|
+
}
|
|
2299
|
+
const errors = [];
|
|
2300
|
+
const id = isNonEmptyString(value.id) ? value.id : void 0;
|
|
2301
|
+
const requestId = isNonEmptyString(value.requestId) ? value.requestId : void 0;
|
|
2302
|
+
if (id === void 0) errors.push("outcome.id must be a non-empty string");
|
|
2303
|
+
if (requestId === void 0) errors.push("outcome.requestId must be a non-empty string");
|
|
2304
|
+
if (value.kind !== "proposedRecords" && value.kind !== "failed") {
|
|
2305
|
+
errors.push("outcome.kind must be proposedRecords or failed");
|
|
2306
|
+
}
|
|
2307
|
+
if (value.provenance !== void 0 && typeof value.provenance !== "string") {
|
|
2308
|
+
errors.push("outcome.provenance must be a string when present");
|
|
2309
|
+
}
|
|
2310
|
+
if (value.kind === "failed" && !isNonEmptyString(value.message)) {
|
|
2311
|
+
errors.push("failed outcome.message must be a non-empty string");
|
|
2312
|
+
}
|
|
2313
|
+
const records = [];
|
|
2314
|
+
if (value.kind === "proposedRecords") {
|
|
2315
|
+
if (!Array.isArray(value.records)) {
|
|
2316
|
+
errors.push("proposedRecords.records must be a non-empty array");
|
|
2317
|
+
} else {
|
|
2318
|
+
const recordsLength = safeArrayLength2(value.records);
|
|
2319
|
+
const seenRecordIds = /* @__PURE__ */ new Set();
|
|
2320
|
+
if (recordsLength === void 0 || recordsLength === 0) {
|
|
2321
|
+
errors.push("proposedRecords.records must be a non-empty array");
|
|
2322
|
+
}
|
|
2323
|
+
for (let i = 0; i < (recordsLength ?? 0); i += 1) {
|
|
2324
|
+
let result;
|
|
2325
|
+
try {
|
|
2326
|
+
if (!Object.hasOwn(value.records, i)) {
|
|
2327
|
+
throw new TypeError("proposedRecords.records must be dense");
|
|
2328
|
+
}
|
|
2329
|
+
result = validateAndSnapshotRecord(value.records[i], i);
|
|
2330
|
+
} catch (error) {
|
|
2331
|
+
errors.push(`records[${i}]: record access failed: ${errorMessage2(error)}`);
|
|
2332
|
+
continue;
|
|
2333
|
+
}
|
|
2334
|
+
if (result.record === void 0 || result.errors.length > 0) {
|
|
2335
|
+
errors.push(
|
|
2336
|
+
...result.errors.flatMap((error) => error.validationErrors ?? [error.message]).map((error) => `records[${i}]: ${error}`)
|
|
2337
|
+
);
|
|
2338
|
+
} else if (seenRecordIds.has(result.record.id)) {
|
|
2339
|
+
errors.push(`records[${i}]: duplicate proposed record id '${result.record.id}'`);
|
|
2340
|
+
} else {
|
|
2341
|
+
seenRecordIds.add(result.record.id);
|
|
2342
|
+
records.push(result.record);
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
if (errors.length > 0 || id === void 0 || requestId === void 0) {
|
|
2348
|
+
return {
|
|
2349
|
+
error: {
|
|
2350
|
+
code: value.kind === "proposedRecords" ? "invalid-proposed-record" : "invalid-outcome",
|
|
2351
|
+
message: "agenticMemoryConsolidationBundle: outcome is invalid",
|
|
2352
|
+
index,
|
|
2353
|
+
outcomeId: id,
|
|
2354
|
+
requestId,
|
|
2355
|
+
outcome: value,
|
|
2356
|
+
validationErrors: Object.freeze(errors)
|
|
2357
|
+
}
|
|
2358
|
+
};
|
|
2359
|
+
}
|
|
2360
|
+
if (value.kind === "failed") {
|
|
2361
|
+
return {
|
|
2362
|
+
outcome: Object.freeze({
|
|
2363
|
+
id,
|
|
2364
|
+
requestId,
|
|
2365
|
+
kind: "failed",
|
|
2366
|
+
message: value.message,
|
|
2367
|
+
...value.provenance === void 0 ? {} : { provenance: value.provenance }
|
|
2368
|
+
})
|
|
2369
|
+
};
|
|
2370
|
+
}
|
|
2371
|
+
return {
|
|
2372
|
+
outcome: Object.freeze({
|
|
2373
|
+
id,
|
|
2374
|
+
requestId,
|
|
2375
|
+
kind: "proposedRecords",
|
|
2376
|
+
records: Object.freeze(records),
|
|
2377
|
+
...value.provenance === void 0 ? {} : { provenance: value.provenance }
|
|
2378
|
+
})
|
|
2379
|
+
};
|
|
2380
|
+
}
|
|
2381
|
+
function consolidationErrorFromRecordError(error) {
|
|
2382
|
+
return {
|
|
2383
|
+
...error,
|
|
2384
|
+
code: error.code
|
|
2385
|
+
};
|
|
2386
|
+
}
|
|
2387
|
+
function consolidationErrorFromRetentionError(error) {
|
|
2388
|
+
return {
|
|
2389
|
+
...error,
|
|
2390
|
+
code: error.code
|
|
2391
|
+
};
|
|
2392
|
+
}
|
|
2393
|
+
function packContext(contextValue, textsValue, policyValue, evaluation) {
|
|
2394
|
+
const errors = [];
|
|
2395
|
+
const context = validatePackingContext(contextValue, errors);
|
|
2396
|
+
const texts = validateContextTexts(textsValue, errors);
|
|
2397
|
+
const policy = validatePackingPolicy(policyValue, errors);
|
|
2398
|
+
const packedEntries = [];
|
|
2399
|
+
let omittedEntries = 0;
|
|
2400
|
+
let totalChars = 0;
|
|
2401
|
+
let totalCost = 0;
|
|
2402
|
+
if (context !== void 0 && policy !== void 0) {
|
|
2403
|
+
for (const entry of context.entries) {
|
|
2404
|
+
const textFact = texts.get(entry.fragmentId);
|
|
2405
|
+
if (textFact === void 0) {
|
|
2406
|
+
omittedEntries += 1;
|
|
2407
|
+
errors.push({
|
|
2408
|
+
code: "missing-text",
|
|
2409
|
+
message: "agenticMemoryContextPackingBundle: missing text projection for context entry",
|
|
2410
|
+
fragmentId: entry.fragmentId,
|
|
2411
|
+
validationErrors: [`missing text for fragment '${entry.fragmentId}'`]
|
|
2412
|
+
});
|
|
2413
|
+
continue;
|
|
2414
|
+
}
|
|
2415
|
+
const cost = textFact.cost ?? textFact.text.length;
|
|
2416
|
+
const nextEntries = packedEntries.length + 1;
|
|
2417
|
+
const separatorChars = packedEntries.length === 0 ? 0 : 2;
|
|
2418
|
+
const nextChars = totalChars + separatorChars + textFact.text.length;
|
|
2419
|
+
const nextCost = totalCost + cost;
|
|
2420
|
+
const exceeds = policy.maxEntries !== void 0 && nextEntries > policy.maxEntries || policy.maxChars !== void 0 && nextChars > policy.maxChars || policy.maxCost !== void 0 && nextCost > policy.maxCost;
|
|
2421
|
+
if (exceeds) {
|
|
2422
|
+
omittedEntries += 1;
|
|
2423
|
+
continue;
|
|
2424
|
+
}
|
|
2425
|
+
const packedEntry = Object.freeze({
|
|
2426
|
+
fragmentId: entry.fragmentId,
|
|
2427
|
+
text: textFact.text,
|
|
2428
|
+
cost,
|
|
2429
|
+
chars: textFact.text.length,
|
|
2430
|
+
...entry.record === void 0 ? {} : { record: entry.record },
|
|
2431
|
+
...policy.includeMetadata && textFact.metadata !== void 0 ? { metadata: textFact.metadata } : {}
|
|
2432
|
+
});
|
|
2433
|
+
packedEntries.push(packedEntry);
|
|
2434
|
+
totalChars = nextChars;
|
|
2435
|
+
totalCost = nextCost;
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
const cursor = Object.freeze({
|
|
2439
|
+
evaluation,
|
|
2440
|
+
inputEntries: context?.entries.length ?? 0,
|
|
2441
|
+
packedEntries: packedEntries.length,
|
|
2442
|
+
omittedEntries,
|
|
2443
|
+
totalChars,
|
|
2444
|
+
totalCost
|
|
2445
|
+
});
|
|
2446
|
+
const errorFacts = Object.freeze(
|
|
2447
|
+
errors.map(
|
|
2448
|
+
(error) => freezeError({
|
|
2449
|
+
...error,
|
|
2450
|
+
cursor
|
|
2451
|
+
})
|
|
2452
|
+
)
|
|
2453
|
+
);
|
|
2454
|
+
const packedContext = Object.freeze({
|
|
2455
|
+
entries: Object.freeze(packedEntries),
|
|
2456
|
+
text: packedEntries.map((entry) => entry.text).join("\n\n"),
|
|
2457
|
+
totalChars,
|
|
2458
|
+
totalCost,
|
|
2459
|
+
truncated: omittedEntries > 0
|
|
2460
|
+
});
|
|
2461
|
+
const status = Object.freeze({
|
|
2462
|
+
state: agenticStatusState(errorFacts.length, packedEntries.length),
|
|
2463
|
+
cursor
|
|
2464
|
+
});
|
|
2465
|
+
return Object.freeze({
|
|
2466
|
+
packedContext,
|
|
2467
|
+
status,
|
|
2468
|
+
errors: errorFacts,
|
|
2469
|
+
cursor
|
|
2470
|
+
});
|
|
2471
|
+
}
|
|
2472
|
+
function validatePackingContext(value, errors) {
|
|
2473
|
+
if (!isPlainRecord(value)) {
|
|
2474
|
+
errors.push({
|
|
2475
|
+
code: "invalid-context",
|
|
2476
|
+
message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
|
|
2477
|
+
value
|
|
2478
|
+
});
|
|
2479
|
+
return void 0;
|
|
2480
|
+
}
|
|
2481
|
+
let entriesValue;
|
|
2482
|
+
try {
|
|
2483
|
+
entriesValue = value.entries;
|
|
2484
|
+
} catch (error) {
|
|
2485
|
+
errors.push({
|
|
2486
|
+
code: "invalid-context",
|
|
2487
|
+
message: `agenticMemoryContextPackingBundle: context entries access failed: ${errorMessage2(error)}`,
|
|
2488
|
+
value,
|
|
2489
|
+
validationErrors: ["context entries access failed"]
|
|
2490
|
+
});
|
|
2491
|
+
return void 0;
|
|
2492
|
+
}
|
|
2493
|
+
if (!Array.isArray(entriesValue)) {
|
|
2494
|
+
errors.push({
|
|
2495
|
+
code: "invalid-context",
|
|
2496
|
+
message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
|
|
2497
|
+
value,
|
|
2498
|
+
validationErrors: ["context.entries must be an array"]
|
|
2499
|
+
});
|
|
2500
|
+
return void 0;
|
|
2501
|
+
}
|
|
2502
|
+
const length = safeArrayLength2(entriesValue);
|
|
2503
|
+
if (length === void 0) {
|
|
2504
|
+
errors.push({
|
|
2505
|
+
code: "invalid-context",
|
|
2506
|
+
message: "agenticMemoryContextPackingBundle: context entries length could not be read",
|
|
2507
|
+
value,
|
|
2508
|
+
validationErrors: ["context.entries length could not be read"]
|
|
2509
|
+
});
|
|
2510
|
+
return void 0;
|
|
2511
|
+
}
|
|
2512
|
+
const entries = [];
|
|
2513
|
+
for (let i = 0; i < length; i += 1) {
|
|
2514
|
+
let raw;
|
|
2515
|
+
try {
|
|
2516
|
+
raw = entriesValue[i];
|
|
2517
|
+
if (!isPlainRecord(raw) || !isNonEmptyString(raw.fragmentId)) {
|
|
2518
|
+
errors.push({
|
|
2519
|
+
code: "invalid-context",
|
|
2520
|
+
message: "agenticMemoryContextPackingBundle: context entry is invalid",
|
|
2521
|
+
index: i,
|
|
2522
|
+
value: raw,
|
|
2523
|
+
validationErrors: ["context entry fragmentId must be a non-empty string"]
|
|
2524
|
+
});
|
|
2525
|
+
continue;
|
|
2526
|
+
}
|
|
2527
|
+
const record = validateRecordMetadata(raw.record);
|
|
2528
|
+
if (!record.ok) {
|
|
2529
|
+
errors.push({
|
|
2530
|
+
code: "invalid-context",
|
|
2531
|
+
message: "agenticMemoryContextPackingBundle: context entry record metadata is invalid",
|
|
2532
|
+
index: i,
|
|
2533
|
+
fragmentId: raw.fragmentId,
|
|
2534
|
+
value: raw,
|
|
2535
|
+
validationErrors: Object.freeze(record.errors)
|
|
2536
|
+
});
|
|
2537
|
+
continue;
|
|
2538
|
+
}
|
|
2539
|
+
entries.push(
|
|
2540
|
+
Object.freeze({
|
|
2541
|
+
fragmentId: raw.fragmentId,
|
|
2542
|
+
...record.metadata === void 0 ? {} : { record: record.metadata }
|
|
2543
|
+
})
|
|
2544
|
+
);
|
|
2545
|
+
} catch (error) {
|
|
2546
|
+
errors.push({
|
|
2547
|
+
code: "invalid-context",
|
|
2548
|
+
message: `agenticMemoryContextPackingBundle: context entry access failed: ${errorMessage2(error)}`,
|
|
2549
|
+
index: i,
|
|
2550
|
+
value: raw,
|
|
2551
|
+
validationErrors: ["context entry access failed"]
|
|
2552
|
+
});
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
return Object.freeze({
|
|
2556
|
+
entries: Object.freeze(entries)
|
|
2557
|
+
});
|
|
2558
|
+
}
|
|
2559
|
+
function validateContextTexts(value, errors) {
|
|
2560
|
+
const out = /* @__PURE__ */ new Map();
|
|
2561
|
+
if (!Array.isArray(value)) {
|
|
2562
|
+
errors.push({
|
|
2563
|
+
code: "invalid-texts-input",
|
|
2564
|
+
message: "agenticMemoryContextPackingBundle: texts input must be an array",
|
|
2565
|
+
value
|
|
2566
|
+
});
|
|
2567
|
+
return out;
|
|
2568
|
+
}
|
|
2569
|
+
const length = safeArrayLength2(value);
|
|
2570
|
+
if (length === void 0) {
|
|
2571
|
+
errors.push({
|
|
2572
|
+
code: "invalid-texts-input",
|
|
2573
|
+
message: "agenticMemoryContextPackingBundle: texts input length could not be read",
|
|
2574
|
+
value
|
|
2575
|
+
});
|
|
2576
|
+
return out;
|
|
2577
|
+
}
|
|
2578
|
+
for (let i = 0; i < length; i += 1) {
|
|
2579
|
+
try {
|
|
2580
|
+
const raw = value[i];
|
|
2581
|
+
const result = validateContextText(raw, i);
|
|
2582
|
+
if (result.error !== void 0) {
|
|
2583
|
+
errors.push(result.error);
|
|
2584
|
+
continue;
|
|
2585
|
+
}
|
|
2586
|
+
if (result.text === void 0) {
|
|
2587
|
+
errors.push({
|
|
2588
|
+
code: "invalid-text",
|
|
2589
|
+
message: "agenticMemoryContextPackingBundle: text fact is invalid",
|
|
2590
|
+
index: i,
|
|
2591
|
+
value: raw,
|
|
2592
|
+
validationErrors: ["text validation returned no fact"]
|
|
2593
|
+
});
|
|
2594
|
+
continue;
|
|
2595
|
+
}
|
|
2596
|
+
if (out.has(result.text.fragmentId)) {
|
|
2597
|
+
errors.push({
|
|
2598
|
+
code: "duplicate-text-fragment-id",
|
|
2599
|
+
message: "agenticMemoryContextPackingBundle: duplicate text fragment id",
|
|
2600
|
+
index: i,
|
|
2601
|
+
fragmentId: result.text.fragmentId,
|
|
2602
|
+
value: raw,
|
|
2603
|
+
validationErrors: [`duplicate text fragment id '${result.text.fragmentId}'`]
|
|
2604
|
+
});
|
|
2605
|
+
continue;
|
|
2606
|
+
}
|
|
2607
|
+
out.set(result.text.fragmentId, result.text);
|
|
2608
|
+
} catch (error) {
|
|
2609
|
+
errors.push({
|
|
2610
|
+
code: "invalid-text",
|
|
2611
|
+
message: `agenticMemoryContextPackingBundle: text access failed: ${errorMessage2(error)}`,
|
|
2612
|
+
index: i,
|
|
2613
|
+
validationErrors: ["text access failed"]
|
|
2614
|
+
});
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
return out;
|
|
2618
|
+
}
|
|
2619
|
+
function validateContextText(value, index) {
|
|
2620
|
+
if (!isPlainRecord(value)) {
|
|
2621
|
+
return {
|
|
2622
|
+
error: {
|
|
2623
|
+
code: "invalid-text",
|
|
2624
|
+
message: "agenticMemoryContextPackingBundle: text fact must be an object",
|
|
2625
|
+
index,
|
|
2626
|
+
value
|
|
2627
|
+
}
|
|
2628
|
+
};
|
|
2629
|
+
}
|
|
2630
|
+
const errors = [];
|
|
2631
|
+
if (!isNonEmptyString(value.fragmentId)) errors.push("fragmentId must be a non-empty string");
|
|
2632
|
+
if (typeof value.text !== "string") errors.push("text must be a string");
|
|
2633
|
+
if (value.cost !== void 0 && (typeof value.cost !== "number" || !Number.isFinite(value.cost) || value.cost < 0)) {
|
|
2634
|
+
errors.push("cost must be a finite number >= 0");
|
|
2635
|
+
}
|
|
2636
|
+
if (value.metadata !== void 0) {
|
|
2637
|
+
try {
|
|
2638
|
+
if (!isPlainRecord(value.metadata)) {
|
|
2639
|
+
throw new TypeError("metadata must be a plain object when present");
|
|
2640
|
+
}
|
|
2641
|
+
assertStrictJsonValue(value.metadata, "metadata");
|
|
2642
|
+
} catch (error) {
|
|
2643
|
+
errors.push(errorMessage2(error));
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
if (errors.length > 0) {
|
|
2647
|
+
return {
|
|
2648
|
+
error: {
|
|
2649
|
+
code: "invalid-text",
|
|
2650
|
+
message: "agenticMemoryContextPackingBundle: text fact is invalid",
|
|
2651
|
+
index,
|
|
2652
|
+
fragmentId: typeof value.fragmentId === "string" ? value.fragmentId : void 0,
|
|
2653
|
+
value,
|
|
2654
|
+
validationErrors: Object.freeze(errors)
|
|
2655
|
+
}
|
|
2656
|
+
};
|
|
2657
|
+
}
|
|
2658
|
+
return {
|
|
2659
|
+
text: Object.freeze({
|
|
2660
|
+
fragmentId: value.fragmentId,
|
|
2661
|
+
text: value.text,
|
|
2662
|
+
...value.cost === void 0 ? {} : { cost: value.cost },
|
|
2663
|
+
...value.metadata === void 0 ? {} : { metadata: Object.freeze({ ...value.metadata }) }
|
|
2664
|
+
})
|
|
2665
|
+
};
|
|
2666
|
+
}
|
|
2667
|
+
function validatePackingPolicy(value, errors) {
|
|
2668
|
+
if (!isPlainRecord(value)) {
|
|
2669
|
+
errors.push({
|
|
2670
|
+
code: "invalid-policy",
|
|
2671
|
+
message: "agenticMemoryContextPackingBundle: policy must be an object",
|
|
2672
|
+
value
|
|
2673
|
+
});
|
|
2674
|
+
return void 0;
|
|
2675
|
+
}
|
|
2676
|
+
const validation = [];
|
|
2677
|
+
let maxEntries;
|
|
2678
|
+
let maxChars;
|
|
2679
|
+
let maxCost;
|
|
2680
|
+
let includeMetadata;
|
|
2681
|
+
try {
|
|
2682
|
+
maxEntries = value.maxEntries;
|
|
2683
|
+
maxChars = value.maxChars;
|
|
2684
|
+
maxCost = value.maxCost;
|
|
2685
|
+
includeMetadata = value.includeMetadata;
|
|
2686
|
+
} catch (error) {
|
|
2687
|
+
errors.push({
|
|
2688
|
+
code: "invalid-policy",
|
|
2689
|
+
message: `agenticMemoryContextPackingBundle: policy access failed: ${errorMessage2(error)}`,
|
|
2690
|
+
value,
|
|
2691
|
+
validationErrors: ["policy access failed"]
|
|
2692
|
+
});
|
|
2693
|
+
return void 0;
|
|
2694
|
+
}
|
|
2695
|
+
if (maxEntries !== void 0 && (typeof maxEntries !== "number" || !Number.isSafeInteger(maxEntries) || maxEntries < 0)) {
|
|
2696
|
+
validation.push("maxEntries must be a safe integer >= 0");
|
|
2697
|
+
}
|
|
2698
|
+
if (maxChars !== void 0 && (typeof maxChars !== "number" || !Number.isSafeInteger(maxChars) || maxChars < 0)) {
|
|
2699
|
+
validation.push("maxChars must be a safe integer >= 0");
|
|
2700
|
+
}
|
|
2701
|
+
if (maxCost !== void 0 && (typeof maxCost !== "number" || !Number.isFinite(maxCost) || maxCost < 0)) {
|
|
2702
|
+
validation.push("maxCost must be a finite number >= 0");
|
|
2703
|
+
}
|
|
2704
|
+
if (includeMetadata !== void 0 && typeof includeMetadata !== "boolean") {
|
|
2705
|
+
validation.push("includeMetadata must be a boolean when present");
|
|
2706
|
+
}
|
|
2707
|
+
if (validation.length > 0) {
|
|
2708
|
+
errors.push({
|
|
2709
|
+
code: "invalid-policy",
|
|
2710
|
+
message: "agenticMemoryContextPackingBundle: policy is invalid",
|
|
2711
|
+
value,
|
|
2712
|
+
validationErrors: Object.freeze(validation)
|
|
2713
|
+
});
|
|
2714
|
+
return void 0;
|
|
2715
|
+
}
|
|
2716
|
+
return Object.freeze({
|
|
2717
|
+
...maxEntries === void 0 ? {} : { maxEntries },
|
|
2718
|
+
...maxChars === void 0 ? {} : { maxChars },
|
|
2719
|
+
...maxCost === void 0 ? {} : { maxCost },
|
|
2720
|
+
...includeMetadata === void 0 ? {} : { includeMetadata }
|
|
2721
|
+
});
|
|
2722
|
+
}
|
|
2723
|
+
function validateAndProjectRecords(value) {
|
|
2724
|
+
const records = [];
|
|
2725
|
+
const fragments = [];
|
|
2726
|
+
const metadataByFragmentId = /* @__PURE__ */ Object.create(null);
|
|
2727
|
+
const errors = [];
|
|
2728
|
+
const invalidRecordIndexes = /* @__PURE__ */ new Set();
|
|
2729
|
+
const seenRecordIds = /* @__PURE__ */ new Set();
|
|
2730
|
+
const seenFragmentIds = /* @__PURE__ */ new Set();
|
|
2731
|
+
if (!Array.isArray(value)) {
|
|
2732
|
+
errors.push({
|
|
2733
|
+
code: "invalid-records-input",
|
|
2734
|
+
message: "agenticMemoryBundle: records input must be an array",
|
|
2735
|
+
record: value
|
|
2736
|
+
});
|
|
2737
|
+
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
2738
|
+
}
|
|
2739
|
+
const length = safeArrayLength2(value);
|
|
2740
|
+
if (length === void 0) {
|
|
2741
|
+
errors.push({
|
|
2742
|
+
code: "invalid-records-input",
|
|
2743
|
+
message: "agenticMemoryBundle: records input length could not be read",
|
|
2744
|
+
record: value
|
|
2745
|
+
});
|
|
2746
|
+
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
2747
|
+
}
|
|
2748
|
+
for (let i = 0; i < length; i += 1) {
|
|
2749
|
+
let raw;
|
|
2750
|
+
try {
|
|
2751
|
+
raw = value[i];
|
|
2752
|
+
} catch (error) {
|
|
2753
|
+
invalidRecordIndexes.add(i);
|
|
2754
|
+
errors.push({
|
|
2755
|
+
code: "invalid-record",
|
|
2756
|
+
message: `agenticMemoryBundle: record access failed: ${errorMessage2(error)}`,
|
|
2757
|
+
index: i,
|
|
2758
|
+
validationErrors: Object.freeze(["record access failed"])
|
|
2759
|
+
});
|
|
2760
|
+
continue;
|
|
2761
|
+
}
|
|
2762
|
+
const result = validateAndSnapshotRecord(raw, i);
|
|
2763
|
+
if (result.errors.length > 0) {
|
|
2764
|
+
invalidRecordIndexes.add(i);
|
|
2765
|
+
errors.push(...result.errors);
|
|
2766
|
+
continue;
|
|
2767
|
+
}
|
|
2768
|
+
if (result.record === void 0) continue;
|
|
2769
|
+
if (seenRecordIds.has(result.record.id)) {
|
|
2770
|
+
invalidRecordIndexes.add(i);
|
|
2771
|
+
errors.push({
|
|
2772
|
+
code: "duplicate-record-id",
|
|
2773
|
+
message: "agenticMemoryBundle: duplicate record id",
|
|
2774
|
+
index: i,
|
|
2775
|
+
recordId: result.record.id,
|
|
2776
|
+
record: raw,
|
|
2777
|
+
validationErrors: [`duplicate record id '${result.record.id}'`]
|
|
2778
|
+
});
|
|
2779
|
+
continue;
|
|
2780
|
+
}
|
|
2781
|
+
if (seenFragmentIds.has(result.record.fragment.id)) {
|
|
2782
|
+
invalidRecordIndexes.add(i);
|
|
2783
|
+
errors.push({
|
|
2784
|
+
code: "duplicate-fragment-id",
|
|
2785
|
+
message: "agenticMemoryBundle: duplicate fragment id",
|
|
2786
|
+
index: i,
|
|
2787
|
+
recordId: result.record.id,
|
|
2788
|
+
fragmentId: result.record.fragment.id,
|
|
2789
|
+
record: raw,
|
|
2790
|
+
validationErrors: [`duplicate fragment id '${result.record.fragment.id}'`]
|
|
2791
|
+
});
|
|
2792
|
+
continue;
|
|
2793
|
+
}
|
|
2794
|
+
seenRecordIds.add(result.record.id);
|
|
2795
|
+
seenFragmentIds.add(result.record.fragment.id);
|
|
2796
|
+
records.push(result.record);
|
|
2797
|
+
fragments.push(result.record.fragment);
|
|
2798
|
+
metadataByFragmentId[result.record.fragment.id] = recordMetadata(result.record);
|
|
2799
|
+
}
|
|
2800
|
+
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
2801
|
+
}
|
|
2802
|
+
function validateAndSnapshotRecord(value, index) {
|
|
2803
|
+
try {
|
|
2804
|
+
return validateAndSnapshotRecordInner(value, index);
|
|
2805
|
+
} catch (error) {
|
|
2806
|
+
return {
|
|
2807
|
+
errors: [
|
|
2808
|
+
{
|
|
2809
|
+
code: "invalid-record",
|
|
2810
|
+
message: `agenticMemoryBundle: record access failed: ${errorMessage2(error)}`,
|
|
2811
|
+
index,
|
|
2812
|
+
record: value,
|
|
2813
|
+
validationErrors: Object.freeze(["record access failed"])
|
|
2814
|
+
}
|
|
2815
|
+
]
|
|
2816
|
+
};
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
function validateAndSnapshotRecordInner(value, index) {
|
|
2820
|
+
const errors = [];
|
|
2821
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2822
|
+
return {
|
|
2823
|
+
errors: [
|
|
2824
|
+
{
|
|
2825
|
+
code: "invalid-record",
|
|
2826
|
+
message: "agenticMemoryBundle: record must be an object",
|
|
2827
|
+
index,
|
|
2828
|
+
record: value
|
|
2829
|
+
}
|
|
2830
|
+
]
|
|
2831
|
+
};
|
|
2832
|
+
}
|
|
2833
|
+
const record = value;
|
|
2834
|
+
const recordId = typeof record.id === "string" ? record.id : void 0;
|
|
2835
|
+
if (recordId === void 0 || recordId.length === 0) {
|
|
2836
|
+
errors.push({
|
|
2837
|
+
code: "invalid-record",
|
|
2838
|
+
message: "agenticMemoryBundle: record.id must be a non-empty string",
|
|
2839
|
+
index,
|
|
2840
|
+
record: value,
|
|
2841
|
+
validationErrors: ["record.id must be a non-empty string"]
|
|
2842
|
+
});
|
|
2843
|
+
}
|
|
2844
|
+
if (!isAgenticMemoryKind(record.kind)) {
|
|
2845
|
+
errors.push({
|
|
2846
|
+
code: "invalid-record-kind",
|
|
2847
|
+
message: "agenticMemoryBundle: record.kind is invalid",
|
|
2848
|
+
index,
|
|
2849
|
+
recordId,
|
|
2850
|
+
record: value,
|
|
2851
|
+
validationErrors: ["kind must be one of working, episodic, semantic, procedural, profile"]
|
|
2852
|
+
});
|
|
2853
|
+
}
|
|
2854
|
+
if (!isAgenticMemoryPersistenceLevel(record.persistenceLevel)) {
|
|
2855
|
+
errors.push({
|
|
2856
|
+
code: "invalid-persistence-level",
|
|
2857
|
+
message: "agenticMemoryBundle: record.persistenceLevel is invalid",
|
|
2858
|
+
index,
|
|
2859
|
+
recordId,
|
|
2860
|
+
record: value,
|
|
2861
|
+
validationErrors: [
|
|
2862
|
+
"persistenceLevel must be one of turn, session, project, longTerm, permanent, archived"
|
|
2863
|
+
]
|
|
2864
|
+
});
|
|
2865
|
+
}
|
|
2866
|
+
if (!isAgenticMemoryArtifactKind(record.artifactKind)) {
|
|
2867
|
+
errors.push({
|
|
2868
|
+
code: "invalid-artifact-kind",
|
|
2869
|
+
message: "agenticMemoryBundle: record.artifactKind is invalid",
|
|
2870
|
+
index,
|
|
2871
|
+
recordId,
|
|
2872
|
+
record: value,
|
|
2873
|
+
validationErrors: ["artifactKind must be one of raw, insight, profile, procedure"]
|
|
2874
|
+
});
|
|
2875
|
+
}
|
|
2876
|
+
const scopeValidation = validateScope(record.scope);
|
|
2877
|
+
if (!scopeValidation.ok) {
|
|
2878
|
+
errors.push({
|
|
2879
|
+
code: "invalid-scope",
|
|
2880
|
+
message: "agenticMemoryBundle: record.scope is invalid",
|
|
2881
|
+
index,
|
|
2882
|
+
recordId,
|
|
2883
|
+
record: value,
|
|
2884
|
+
validationErrors: Object.freeze(scopeValidation.errors)
|
|
2885
|
+
});
|
|
2886
|
+
}
|
|
2887
|
+
const fragmentValidation = validateMemoryFragment(record.fragment);
|
|
2888
|
+
if (!fragmentValidation.ok) {
|
|
2889
|
+
errors.push({
|
|
2890
|
+
code: "invalid-fragment",
|
|
2891
|
+
message: "agenticMemoryBundle: record.fragment is invalid",
|
|
2892
|
+
index,
|
|
2893
|
+
recordId,
|
|
2894
|
+
fragmentId: typeof record.fragment === "object" && record.fragment !== null && typeof record.fragment.id === "string" ? record.fragment.id : void 0,
|
|
2895
|
+
record: value,
|
|
2896
|
+
validationErrors: Object.freeze([...fragmentValidation.errors])
|
|
2897
|
+
});
|
|
2898
|
+
}
|
|
2899
|
+
const forbiddenFields = [
|
|
2900
|
+
"storageTier",
|
|
2901
|
+
"storageKey",
|
|
2902
|
+
"adapter",
|
|
2903
|
+
"collection",
|
|
2904
|
+
"collections",
|
|
2905
|
+
"ttl",
|
|
2906
|
+
"ttlMs",
|
|
2907
|
+
"ttlNs",
|
|
2908
|
+
"expiresAt",
|
|
2909
|
+
"timer",
|
|
2910
|
+
"scheduler",
|
|
2911
|
+
"schedule",
|
|
2912
|
+
"retentionTimer",
|
|
2913
|
+
"consolidationSchedule",
|
|
2914
|
+
"reflectionSchedule",
|
|
2915
|
+
"llm",
|
|
2916
|
+
"llmHandle",
|
|
2917
|
+
"tool",
|
|
2918
|
+
"toolHandle",
|
|
2919
|
+
"runner",
|
|
2920
|
+
"runnerHandle",
|
|
2921
|
+
"restore",
|
|
2922
|
+
"hydrate",
|
|
2923
|
+
"hydration",
|
|
2924
|
+
"graphMutation",
|
|
2925
|
+
"protocol"
|
|
2926
|
+
];
|
|
2927
|
+
const presentForbidden = forbiddenFields.filter((field) => Object.hasOwn(record, field));
|
|
2928
|
+
if (presentForbidden.length > 0) {
|
|
2929
|
+
errors.push({
|
|
2930
|
+
code: "invalid-record",
|
|
2931
|
+
message: "agenticMemoryBundle: record contains forbidden runtime/persistence fields",
|
|
2932
|
+
index,
|
|
2933
|
+
recordId,
|
|
2934
|
+
record: value,
|
|
2935
|
+
validationErrors: Object.freeze(
|
|
2936
|
+
presentForbidden.map((field) => `${field} is not part of AgenticMemoryRecord`)
|
|
2937
|
+
)
|
|
2938
|
+
});
|
|
2939
|
+
}
|
|
2940
|
+
if (errors.length > 0) return { errors };
|
|
2941
|
+
const scope = scopeValidation.scope;
|
|
2942
|
+
const fragment = snapshotFragment2(record.fragment);
|
|
2943
|
+
return {
|
|
2944
|
+
record: Object.freeze({
|
|
2945
|
+
id: recordId,
|
|
2946
|
+
kind: record.kind,
|
|
2947
|
+
persistenceLevel: record.persistenceLevel,
|
|
2948
|
+
artifactKind: record.artifactKind,
|
|
2949
|
+
...scope === void 0 ? {} : { scope },
|
|
2950
|
+
fragment
|
|
2951
|
+
}),
|
|
2952
|
+
errors
|
|
2953
|
+
};
|
|
2954
|
+
}
|
|
2955
|
+
function snapshotFragment2(fragment) {
|
|
2956
|
+
return Object.freeze({
|
|
2957
|
+
id: fragment.id,
|
|
2958
|
+
payload: fragment.payload,
|
|
2959
|
+
tNs: fragment.tNs,
|
|
2960
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: fragment.validFrom },
|
|
2961
|
+
...fragment.validTo === void 0 ? {} : { validTo: fragment.validTo },
|
|
2962
|
+
confidence: fragment.confidence,
|
|
2963
|
+
tags: Object.freeze([...fragment.tags]),
|
|
2964
|
+
sources: Object.freeze([...fragment.sources]),
|
|
2965
|
+
...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
|
|
2966
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
2967
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
2968
|
+
});
|
|
2969
|
+
}
|
|
2970
|
+
function recordMetadata(record) {
|
|
2971
|
+
return Object.freeze({
|
|
2972
|
+
recordId: record.id,
|
|
2973
|
+
kind: record.kind,
|
|
2974
|
+
persistenceLevel: record.persistenceLevel,
|
|
2975
|
+
artifactKind: record.artifactKind,
|
|
2976
|
+
...record.scope === void 0 ? {} : { scope: record.scope }
|
|
2977
|
+
});
|
|
2978
|
+
}
|
|
2979
|
+
function validateRecordMetadata(value) {
|
|
2980
|
+
if (value === void 0) return { ok: true, errors: [] };
|
|
2981
|
+
if (!isPlainRecord(value)) {
|
|
2982
|
+
return { ok: false, errors: ["record metadata must be an object when present"] };
|
|
2983
|
+
}
|
|
2984
|
+
const errors = [];
|
|
2985
|
+
for (const key of Object.keys(value)) {
|
|
2986
|
+
if (key !== "recordId" && key !== "kind" && key !== "persistenceLevel" && key !== "artifactKind" && key !== "scope") {
|
|
2987
|
+
errors.push(`record.${key} is not part of AgenticMemoryRecordMetadata`);
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
if (!isNonEmptyString(value.recordId)) {
|
|
2991
|
+
errors.push("record.recordId must be a non-empty string");
|
|
2992
|
+
}
|
|
2993
|
+
if (!isAgenticMemoryKind(value.kind)) {
|
|
2994
|
+
errors.push("record.kind is invalid");
|
|
2995
|
+
}
|
|
2996
|
+
if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
|
|
2997
|
+
errors.push("record.persistenceLevel is invalid");
|
|
2998
|
+
}
|
|
2999
|
+
if (!isAgenticMemoryArtifactKind(value.artifactKind)) {
|
|
3000
|
+
errors.push("record.artifactKind is invalid");
|
|
3001
|
+
}
|
|
3002
|
+
const scopeValidation = validateScope(value.scope);
|
|
3003
|
+
if (!scopeValidation.ok) {
|
|
3004
|
+
errors.push(...scopeValidation.errors.map((error) => `record.${error}`));
|
|
3005
|
+
}
|
|
3006
|
+
if (errors.length > 0) return { ok: false, errors };
|
|
3007
|
+
return {
|
|
3008
|
+
ok: true,
|
|
3009
|
+
errors,
|
|
3010
|
+
metadata: Object.freeze({
|
|
3011
|
+
recordId: value.recordId,
|
|
3012
|
+
kind: value.kind,
|
|
3013
|
+
persistenceLevel: value.persistenceLevel,
|
|
3014
|
+
artifactKind: value.artifactKind,
|
|
3015
|
+
...scopeValidation.scope === void 0 ? {} : { scope: scopeValidation.scope }
|
|
3016
|
+
})
|
|
3017
|
+
};
|
|
3018
|
+
}
|
|
3019
|
+
function contextState(projection, retrieval) {
|
|
3020
|
+
if (projection === "error" || retrieval === "error") return "error";
|
|
3021
|
+
if (projection === "partial" || retrieval === "partial") return "partial";
|
|
3022
|
+
return retrieval;
|
|
3023
|
+
}
|
|
3024
|
+
function agenticStatusState(errorCount, validRecords) {
|
|
3025
|
+
if (errorCount > 0 && validRecords === 0) return "error";
|
|
3026
|
+
if (errorCount > 0) return "partial";
|
|
3027
|
+
return validRecords > 0 ? "ready" : "empty";
|
|
3028
|
+
}
|
|
3029
|
+
function isAgenticMemoryKind(value) {
|
|
3030
|
+
return value === "working" || value === "episodic" || value === "semantic" || value === "procedural" || value === "profile";
|
|
3031
|
+
}
|
|
3032
|
+
function isAgenticMemoryPersistenceLevel(value) {
|
|
3033
|
+
return value === "turn" || value === "session" || value === "project" || value === "longTerm" || value === "permanent" || value === "archived";
|
|
3034
|
+
}
|
|
3035
|
+
function isAgenticMemoryArtifactKind(value) {
|
|
3036
|
+
return value === "raw" || value === "insight" || value === "profile" || value === "procedure";
|
|
3037
|
+
}
|
|
3038
|
+
function validateScope(value) {
|
|
3039
|
+
if (value === void 0) return { ok: true, errors: [] };
|
|
3040
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
3041
|
+
return { ok: false, errors: ["scope must be an object when present"] };
|
|
3042
|
+
}
|
|
3043
|
+
const scope = value;
|
|
3044
|
+
const errors = [];
|
|
3045
|
+
const allowed = /* @__PURE__ */ new Set(["sessionId", "projectId", "userId", "tenantId"]);
|
|
3046
|
+
for (const key of Object.keys(scope)) {
|
|
3047
|
+
if (!allowed.has(key)) errors.push(`scope.${key} is not part of AgenticMemoryScope`);
|
|
3048
|
+
}
|
|
3049
|
+
for (const key of allowed) {
|
|
3050
|
+
if (scope[key] !== void 0 && (typeof scope[key] !== "string" || scope[key].length === 0)) {
|
|
3051
|
+
errors.push(`scope.${key} must be a non-empty string when present`);
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
if (errors.length > 0) return { ok: false, errors };
|
|
3055
|
+
return {
|
|
3056
|
+
ok: true,
|
|
3057
|
+
errors,
|
|
3058
|
+
scope: Object.freeze({
|
|
3059
|
+
...scope.sessionId === void 0 ? {} : { sessionId: scope.sessionId },
|
|
3060
|
+
...scope.projectId === void 0 ? {} : { projectId: scope.projectId },
|
|
3061
|
+
...scope.userId === void 0 ? {} : { userId: scope.userId },
|
|
3062
|
+
...scope.tenantId === void 0 ? {} : { tenantId: scope.tenantId }
|
|
3063
|
+
})
|
|
3064
|
+
};
|
|
3065
|
+
}
|
|
3066
|
+
function isPlainRecord(value) {
|
|
3067
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3068
|
+
}
|
|
3069
|
+
function ownKeys(value) {
|
|
3070
|
+
return Object.keys(value).sort();
|
|
3071
|
+
}
|
|
3072
|
+
function assertExactKeys(value, expected, label) {
|
|
3073
|
+
const actual = ownKeys(value);
|
|
3074
|
+
const want = [...expected].sort();
|
|
3075
|
+
if (actual.length !== want.length || actual.some((key, i) => key !== want[i])) {
|
|
3076
|
+
throw new TypeError(`${label}: unexpected fields ${actual.join(",")}`);
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
function assertAgenticMemoryRecordCodecShape(value) {
|
|
3080
|
+
if (!isPlainRecord(value)) {
|
|
3081
|
+
throw new TypeError("agenticMemoryRecordFrame: record must be an object");
|
|
3082
|
+
}
|
|
3083
|
+
assertNoSymbolKeys(value, "agenticMemoryRecordFrame.record");
|
|
3084
|
+
assertExactKeys(
|
|
3085
|
+
value,
|
|
3086
|
+
value.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
|
|
3087
|
+
"agenticMemoryRecordFrame.record"
|
|
3088
|
+
);
|
|
3089
|
+
const fragment = value.fragment;
|
|
3090
|
+
if (!isPlainRecord(fragment)) {
|
|
3091
|
+
throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
|
|
3092
|
+
}
|
|
3093
|
+
assertNoSymbolKeys(fragment, "agenticMemoryRecordFrame.record.fragment");
|
|
3094
|
+
assertExactKeys(
|
|
3095
|
+
fragment,
|
|
3096
|
+
[
|
|
3097
|
+
"id",
|
|
3098
|
+
"payload",
|
|
3099
|
+
"tNs",
|
|
3100
|
+
...fragment.validFrom === void 0 ? [] : ["validFrom"],
|
|
3101
|
+
...fragment.validTo === void 0 ? [] : ["validTo"],
|
|
3102
|
+
"confidence",
|
|
3103
|
+
"tags",
|
|
3104
|
+
"sources",
|
|
3105
|
+
...fragment.embedding === void 0 ? [] : ["embedding"],
|
|
3106
|
+
...fragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
|
|
3107
|
+
...fragment.provenance === void 0 ? [] : ["provenance"]
|
|
3108
|
+
],
|
|
3109
|
+
"agenticMemoryRecordFrame.record.fragment"
|
|
3110
|
+
);
|
|
3111
|
+
assertStrictJsonValue(fragment.tags, "record.fragment.tags");
|
|
3112
|
+
assertStrictJsonValue(fragment.sources, "record.fragment.sources");
|
|
3113
|
+
if (fragment.embedding !== void 0) {
|
|
3114
|
+
assertStrictJsonValue(fragment.embedding, "record.fragment.embedding");
|
|
3115
|
+
}
|
|
3116
|
+
if (value.scope !== void 0) assertScopeFrame(value.scope);
|
|
3117
|
+
}
|
|
3118
|
+
function assertNoSymbolKeys(value, label) {
|
|
3119
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
3120
|
+
throw new TypeError(`${label}: unexpected symbol fields`);
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
function decimalBigIntString(value, label) {
|
|
3124
|
+
const out = value.toString(10);
|
|
3125
|
+
if (!/^-?(0|[1-9]\d*)$/.test(out)) {
|
|
3126
|
+
throw new TypeError(`${label} must encode as a canonical decimal bigint string`);
|
|
3127
|
+
}
|
|
3128
|
+
return out;
|
|
3129
|
+
}
|
|
3130
|
+
function parseDecimalBigInt(value, label) {
|
|
3131
|
+
if (typeof value !== "string" || !/^(0|-?[1-9]\d*)$/.test(value)) {
|
|
3132
|
+
throw new TypeError(`${label} must be a canonical decimal bigint string`);
|
|
3133
|
+
}
|
|
3134
|
+
return BigInt(value);
|
|
3135
|
+
}
|
|
3136
|
+
function assertStrictJsonValue(value, label) {
|
|
3137
|
+
try {
|
|
3138
|
+
strictJsonCodec.encode(value);
|
|
3139
|
+
return value;
|
|
3140
|
+
} catch (error) {
|
|
3141
|
+
throw new TypeError(`${label} must be strict JSON: ${errorMessage2(error)}`);
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
function assertScopeFrame(value) {
|
|
3145
|
+
if (!isPlainRecord(value)) {
|
|
3146
|
+
throw new TypeError("agenticMemoryRecordFrame: scope must be an object when present");
|
|
3147
|
+
}
|
|
3148
|
+
assertStrictJsonValue(value, "record.scope");
|
|
3149
|
+
const validation = validateScope(value);
|
|
3150
|
+
if (!validation.ok || validation.scope === void 0) {
|
|
3151
|
+
throw new TypeError(`agenticMemoryRecordFrame: invalid scope: ${validation.errors.join("; ")}`);
|
|
3152
|
+
}
|
|
3153
|
+
assertExactKeys(
|
|
3154
|
+
value,
|
|
3155
|
+
[
|
|
3156
|
+
...value.sessionId === void 0 ? [] : ["sessionId"],
|
|
3157
|
+
...value.projectId === void 0 ? [] : ["projectId"],
|
|
3158
|
+
...value.userId === void 0 ? [] : ["userId"],
|
|
3159
|
+
...value.tenantId === void 0 ? [] : ["tenantId"]
|
|
3160
|
+
],
|
|
3161
|
+
"agenticMemoryRecordFrame.record.scope"
|
|
3162
|
+
);
|
|
3163
|
+
return validation.scope;
|
|
3164
|
+
}
|
|
3165
|
+
function assertKindValue(value) {
|
|
3166
|
+
if (!isAgenticMemoryKind(value)) {
|
|
3167
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid memory kind");
|
|
3168
|
+
}
|
|
3169
|
+
return value;
|
|
3170
|
+
}
|
|
3171
|
+
function assertPersistenceLevelValue(value) {
|
|
3172
|
+
if (!isAgenticMemoryPersistenceLevel(value)) {
|
|
3173
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid persistence level");
|
|
3174
|
+
}
|
|
3175
|
+
return value;
|
|
3176
|
+
}
|
|
3177
|
+
function assertArtifactKindValue(value) {
|
|
3178
|
+
if (!isAgenticMemoryArtifactKind(value)) {
|
|
3179
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid artifact kind");
|
|
3180
|
+
}
|
|
3181
|
+
return value;
|
|
3182
|
+
}
|
|
3183
|
+
function assertNonEmptyString(value, label) {
|
|
3184
|
+
if (!isNonEmptyString(value)) throw new TypeError(`${label} must be a non-empty string`);
|
|
3185
|
+
return value;
|
|
3186
|
+
}
|
|
3187
|
+
function assertString(value, label) {
|
|
3188
|
+
if (typeof value !== "string") throw new TypeError(`${label} must be a string`);
|
|
3189
|
+
return value;
|
|
3190
|
+
}
|
|
3191
|
+
function assertConfidence(value, label) {
|
|
3192
|
+
if (!Number.isFinite(value) || value < 0 || value > 1) {
|
|
3193
|
+
throw new TypeError(`${label} must be a finite number in [0, 1]`);
|
|
3194
|
+
}
|
|
3195
|
+
return value;
|
|
3196
|
+
}
|
|
3197
|
+
function assertStringArray(value, label) {
|
|
3198
|
+
if (!isDenseArrayOf3(value, (item) => typeof item === "string")) {
|
|
3199
|
+
throw new TypeError(`${label} must be a readonly string array`);
|
|
3200
|
+
}
|
|
3201
|
+
return Object.freeze([...value]);
|
|
3202
|
+
}
|
|
3203
|
+
function assertFiniteNumberArray(value, label) {
|
|
3204
|
+
if (!isDenseArrayOf3(value, (item) => Number.isFinite(item))) {
|
|
3205
|
+
throw new TypeError(`${label} must be a finite number array`);
|
|
3206
|
+
}
|
|
3207
|
+
return Object.freeze([...value]);
|
|
3208
|
+
}
|
|
3209
|
+
function isNonEmptyString(value) {
|
|
3210
|
+
return typeof value === "string" && value.length > 0;
|
|
3211
|
+
}
|
|
3212
|
+
function isDenseArrayOf3(value, predicate) {
|
|
3213
|
+
if (!Array.isArray(value)) return false;
|
|
3214
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
3215
|
+
if (!Object.hasOwn(value, i) || !predicate(value[i])) return false;
|
|
3216
|
+
}
|
|
3217
|
+
return true;
|
|
3218
|
+
}
|
|
3219
|
+
function freezeError(error) {
|
|
3220
|
+
return Object.freeze({
|
|
3221
|
+
...error,
|
|
3222
|
+
...error.validationErrors === void 0 ? {} : { validationErrors: Object.freeze([...error.validationErrors]) }
|
|
3223
|
+
});
|
|
3224
|
+
}
|
|
3225
|
+
function safeArrayLength2(value) {
|
|
3226
|
+
try {
|
|
3227
|
+
return value.length;
|
|
3228
|
+
} catch {
|
|
3229
|
+
return void 0;
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
function errorMessage2(error) {
|
|
3233
|
+
return error instanceof Error ? error.message : String(error);
|
|
3234
|
+
}
|
|
3235
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
3236
|
+
0 && (module.exports = {
|
|
3237
|
+
AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
|
|
3238
|
+
AGENTIC_MEMORY_RECORD_FRAME_VERSION,
|
|
3239
|
+
agenticMemoryBundle,
|
|
3240
|
+
agenticMemoryConsolidationBundle,
|
|
3241
|
+
agenticMemoryContextPackingBundle,
|
|
3242
|
+
agenticMemoryKgProjectionBundle,
|
|
3243
|
+
agenticMemoryRecordCodec,
|
|
3244
|
+
agenticMemoryRecordFrame,
|
|
3245
|
+
agenticMemoryRecordFrameCodec,
|
|
3246
|
+
agenticMemoryRetentionBundle,
|
|
3247
|
+
assertAgenticMemoryRecordFrame
|
|
3248
|
+
});
|
|
3249
|
+
//# sourceMappingURL=index.cjs.map
|