@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,2449 @@
|
|
|
1
|
+
import {
|
|
2
|
+
memoryRetrievalBundle,
|
|
3
|
+
validateMemoryFragment
|
|
4
|
+
} from "./chunk-JIMUDQN3.js";
|
|
5
|
+
import {
|
|
6
|
+
strictJsonCodec
|
|
7
|
+
} from "./chunk-4VLAQHZI.js";
|
|
8
|
+
import {
|
|
9
|
+
depBatch,
|
|
10
|
+
depLatest
|
|
11
|
+
} from "./chunk-SWTLEQL6.js";
|
|
12
|
+
|
|
13
|
+
// src/solutions/agentic-memory.ts
|
|
14
|
+
var AGENTIC_MEMORY_RECORD_FRAME_FORMAT = "graphrefly.agenticMemoryRecord";
|
|
15
|
+
var AGENTIC_MEMORY_RECORD_FRAME_VERSION = 1;
|
|
16
|
+
function agenticMemoryBundle(graph, opts) {
|
|
17
|
+
const name = opts.name ?? "agenticMemory";
|
|
18
|
+
const projection = agenticMemoryRecordProjection(graph, opts.records, `${name}/projection`);
|
|
19
|
+
const projectedRecords = agenticMemoryProjection(
|
|
20
|
+
graph,
|
|
21
|
+
projection,
|
|
22
|
+
`${name}/records`,
|
|
23
|
+
"agenticMemoryRecords",
|
|
24
|
+
(fact) => fact.records
|
|
25
|
+
);
|
|
26
|
+
const projectedFragments = agenticMemoryProjection(
|
|
27
|
+
graph,
|
|
28
|
+
projection,
|
|
29
|
+
`${name}/fragments`,
|
|
30
|
+
"agenticMemoryFragments",
|
|
31
|
+
(fact) => fact.fragments
|
|
32
|
+
);
|
|
33
|
+
const status = agenticMemoryProjection(
|
|
34
|
+
graph,
|
|
35
|
+
projection,
|
|
36
|
+
`${name}/status`,
|
|
37
|
+
"agenticMemoryStatus",
|
|
38
|
+
(fact) => fact.status
|
|
39
|
+
);
|
|
40
|
+
const errors = agenticMemoryProjection(
|
|
41
|
+
graph,
|
|
42
|
+
projection,
|
|
43
|
+
`${name}/errors`,
|
|
44
|
+
"agenticMemoryErrors",
|
|
45
|
+
(fact) => fact.errors
|
|
46
|
+
);
|
|
47
|
+
const retrieval = memoryRetrievalBundle(graph, {
|
|
48
|
+
name: `${name}/retrieval`,
|
|
49
|
+
fragments: projectedFragments,
|
|
50
|
+
query: opts.query
|
|
51
|
+
});
|
|
52
|
+
const sources = agenticMemoryProjection(
|
|
53
|
+
graph,
|
|
54
|
+
projection,
|
|
55
|
+
`${name}/sources`,
|
|
56
|
+
"agenticMemorySources",
|
|
57
|
+
(fact) => Object.freeze(
|
|
58
|
+
fact.fragments.map(
|
|
59
|
+
(fragment) => Object.freeze({
|
|
60
|
+
fragmentId: fragment.id,
|
|
61
|
+
...fact.metadataByFragmentId[fragment.id] === void 0 ? {} : { record: fact.metadataByFragmentId[fragment.id] },
|
|
62
|
+
sources: Object.freeze([...fragment.sources]),
|
|
63
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
64
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
65
|
+
})
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
);
|
|
69
|
+
const context = agenticMemoryContextProjection(
|
|
70
|
+
graph,
|
|
71
|
+
projection,
|
|
72
|
+
retrieval.snapshot,
|
|
73
|
+
`${name}/context`
|
|
74
|
+
);
|
|
75
|
+
return {
|
|
76
|
+
input: { records: opts.records, query: opts.query },
|
|
77
|
+
projection,
|
|
78
|
+
retrieval,
|
|
79
|
+
retrievalSnapshot: retrieval.snapshot,
|
|
80
|
+
records: projectedRecords,
|
|
81
|
+
fragments: projectedFragments,
|
|
82
|
+
sources,
|
|
83
|
+
indexed: retrieval.indexed,
|
|
84
|
+
ranked: retrieval.ranked,
|
|
85
|
+
context,
|
|
86
|
+
status,
|
|
87
|
+
errors,
|
|
88
|
+
retrievalStatus: retrieval.status,
|
|
89
|
+
retrievalErrors: retrieval.errors,
|
|
90
|
+
cursor: retrieval.cursor
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function agenticMemoryKgProjectionBundle(graph, opts) {
|
|
94
|
+
const name = opts.name ?? "agenticMemoryKgProjection";
|
|
95
|
+
const projection = graph.node(
|
|
96
|
+
[opts.records, opts.drafts],
|
|
97
|
+
(ctx) => {
|
|
98
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
99
|
+
state.evaluation += 1;
|
|
100
|
+
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
101
|
+
const draftProjection = validateAndProjectKgDrafts(
|
|
102
|
+
depLatest(ctx, 1),
|
|
103
|
+
recordProjection.records
|
|
104
|
+
);
|
|
105
|
+
const cursor = Object.freeze({
|
|
106
|
+
evaluation: state.evaluation,
|
|
107
|
+
validRecords: recordProjection.records.length,
|
|
108
|
+
validDrafts: draftProjection.assertions.length,
|
|
109
|
+
invalidDrafts: draftProjection.invalidDrafts,
|
|
110
|
+
projectedAssertions: draftProjection.assertions.length
|
|
111
|
+
});
|
|
112
|
+
const errors = Object.freeze(
|
|
113
|
+
[...recordProjection.errors.map(kgErrorFromRecordError), ...draftProjection.errors].map(
|
|
114
|
+
(error) => freezeError({ ...error, cursor })
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
const status = Object.freeze({
|
|
118
|
+
state: agenticStatusState(errors.length, draftProjection.assertions.length),
|
|
119
|
+
cursor
|
|
120
|
+
});
|
|
121
|
+
ctx.state.set(state);
|
|
122
|
+
ctx.down([
|
|
123
|
+
[
|
|
124
|
+
"DATA",
|
|
125
|
+
Object.freeze({
|
|
126
|
+
assertions: Object.freeze(draftProjection.assertions),
|
|
127
|
+
status,
|
|
128
|
+
errors,
|
|
129
|
+
cursor
|
|
130
|
+
})
|
|
131
|
+
]
|
|
132
|
+
]);
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: `${name}/projection`,
|
|
136
|
+
factory: "agenticMemoryKgProjection",
|
|
137
|
+
completeWhenDepsComplete: false,
|
|
138
|
+
errorWhenDepsError: false
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
return {
|
|
142
|
+
input: { records: opts.records, drafts: opts.drafts },
|
|
143
|
+
projection,
|
|
144
|
+
assertions: solutionProjection(
|
|
145
|
+
graph,
|
|
146
|
+
projection,
|
|
147
|
+
`${name}/assertions`,
|
|
148
|
+
"agenticMemoryKgAssertions",
|
|
149
|
+
(fact) => fact.assertions
|
|
150
|
+
),
|
|
151
|
+
status: solutionProjection(
|
|
152
|
+
graph,
|
|
153
|
+
projection,
|
|
154
|
+
`${name}/status`,
|
|
155
|
+
"agenticMemoryKgStatus",
|
|
156
|
+
(fact) => fact.status
|
|
157
|
+
),
|
|
158
|
+
errors: solutionProjection(
|
|
159
|
+
graph,
|
|
160
|
+
projection,
|
|
161
|
+
`${name}/errors`,
|
|
162
|
+
"agenticMemoryKgErrors",
|
|
163
|
+
(fact) => fact.errors
|
|
164
|
+
),
|
|
165
|
+
cursor: solutionProjection(
|
|
166
|
+
graph,
|
|
167
|
+
projection,
|
|
168
|
+
`${name}/cursor`,
|
|
169
|
+
"agenticMemoryKgCursor",
|
|
170
|
+
(fact) => fact.cursor
|
|
171
|
+
)
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function agenticMemoryRecordFrame(record) {
|
|
175
|
+
const result = validateAndSnapshotRecord(record, 0);
|
|
176
|
+
if (result.errors.length > 0 || result.record === void 0) {
|
|
177
|
+
throw new TypeError(
|
|
178
|
+
`agenticMemoryRecordFrame: invalid record: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
assertAgenticMemoryRecordCodecShape(record);
|
|
182
|
+
assertStrictJsonValue(result.record.fragment.payload, "record.fragment.payload");
|
|
183
|
+
return Object.freeze({
|
|
184
|
+
format: AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
|
|
185
|
+
version: AGENTIC_MEMORY_RECORD_FRAME_VERSION,
|
|
186
|
+
record: Object.freeze({
|
|
187
|
+
id: result.record.id,
|
|
188
|
+
kind: result.record.kind,
|
|
189
|
+
persistenceLevel: result.record.persistenceLevel,
|
|
190
|
+
artifactKind: result.record.artifactKind,
|
|
191
|
+
...result.record.scope === void 0 ? {} : { scope: result.record.scope },
|
|
192
|
+
fragment: fragmentFrame(result.record.fragment)
|
|
193
|
+
})
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function assertAgenticMemoryRecordFrame(value) {
|
|
197
|
+
if (!isPlainRecord(value))
|
|
198
|
+
throw new TypeError("agenticMemoryRecordFrame: frame must be an object");
|
|
199
|
+
assertStrictJsonValue(value, "agenticMemoryRecordFrame");
|
|
200
|
+
assertExactKeys(value, ["format", "record", "version"], "agenticMemoryRecordFrame");
|
|
201
|
+
if (value.format !== AGENTIC_MEMORY_RECORD_FRAME_FORMAT) {
|
|
202
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid format");
|
|
203
|
+
}
|
|
204
|
+
if (value.version !== AGENTIC_MEMORY_RECORD_FRAME_VERSION) {
|
|
205
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid version");
|
|
206
|
+
}
|
|
207
|
+
const rawRecord = value.record;
|
|
208
|
+
if (!isPlainRecord(rawRecord)) {
|
|
209
|
+
throw new TypeError("agenticMemoryRecordFrame: record must be an object");
|
|
210
|
+
}
|
|
211
|
+
assertExactKeys(
|
|
212
|
+
rawRecord,
|
|
213
|
+
rawRecord.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
|
|
214
|
+
"agenticMemoryRecordFrame.record"
|
|
215
|
+
);
|
|
216
|
+
const rawFragment = rawRecord.fragment;
|
|
217
|
+
if (!isPlainRecord(rawFragment)) {
|
|
218
|
+
throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
|
|
219
|
+
}
|
|
220
|
+
assertExactKeys(
|
|
221
|
+
rawFragment,
|
|
222
|
+
[
|
|
223
|
+
"id",
|
|
224
|
+
"payload",
|
|
225
|
+
"tNs",
|
|
226
|
+
...rawFragment.validFrom === void 0 ? [] : ["validFrom"],
|
|
227
|
+
...rawFragment.validTo === void 0 ? [] : ["validTo"],
|
|
228
|
+
"confidence",
|
|
229
|
+
"tags",
|
|
230
|
+
"sources",
|
|
231
|
+
...rawFragment.embedding === void 0 ? [] : ["embedding"],
|
|
232
|
+
...rawFragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
|
|
233
|
+
...rawFragment.provenance === void 0 ? [] : ["provenance"]
|
|
234
|
+
],
|
|
235
|
+
"agenticMemoryRecordFrame.record.fragment"
|
|
236
|
+
);
|
|
237
|
+
if (rawRecord.scope !== void 0) assertScopeFrame(rawRecord.scope);
|
|
238
|
+
const frame = value;
|
|
239
|
+
const decoded = recordFromFrame(frame);
|
|
240
|
+
const roundtrip = agenticMemoryRecordFrame(decoded);
|
|
241
|
+
return roundtrip;
|
|
242
|
+
}
|
|
243
|
+
function agenticMemoryRecordFrameCodec() {
|
|
244
|
+
return {
|
|
245
|
+
encode(value) {
|
|
246
|
+
return strictJsonCodec.encode(assertAgenticMemoryRecordFrame(value));
|
|
247
|
+
},
|
|
248
|
+
decode(bytes) {
|
|
249
|
+
return assertAgenticMemoryRecordFrame(strictJsonCodec.decode(bytes));
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function agenticMemoryRecordCodec() {
|
|
254
|
+
const frameCodec = agenticMemoryRecordFrameCodec();
|
|
255
|
+
return {
|
|
256
|
+
encode(value) {
|
|
257
|
+
return frameCodec.encode(agenticMemoryRecordFrame(value));
|
|
258
|
+
},
|
|
259
|
+
decode(bytes) {
|
|
260
|
+
return recordFromFrame(frameCodec.decode(bytes));
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function agenticMemoryRetentionBundle(graph, opts) {
|
|
265
|
+
const name = opts.name ?? "agenticMemoryRetention";
|
|
266
|
+
const projection = graph.node(
|
|
267
|
+
[opts.records, opts.commands],
|
|
268
|
+
(ctx) => {
|
|
269
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
270
|
+
state.evaluation += 1;
|
|
271
|
+
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
272
|
+
const retention = projectRetention(depLatest(ctx, 1), recordProjection.records);
|
|
273
|
+
const cursor = Object.freeze({
|
|
274
|
+
evaluation: state.evaluation,
|
|
275
|
+
validRecords: recordProjection.records.length,
|
|
276
|
+
validCommands: retention.validCommands,
|
|
277
|
+
invalidCommands: retention.invalidCommands,
|
|
278
|
+
activeRecords: retention.activeRecords.length,
|
|
279
|
+
archivedRecords: retention.archivedRecords.length,
|
|
280
|
+
consolidationRequests: retention.consolidationRequests.length
|
|
281
|
+
});
|
|
282
|
+
const errors = Object.freeze(
|
|
283
|
+
[...recordProjection.errors.map(retentionErrorFromRecordError), ...retention.errors].map(
|
|
284
|
+
(error) => freezeError({ ...error, cursor })
|
|
285
|
+
)
|
|
286
|
+
);
|
|
287
|
+
const status = Object.freeze({
|
|
288
|
+
state: agenticStatusState(errors.length, recordProjection.records.length),
|
|
289
|
+
cursor
|
|
290
|
+
});
|
|
291
|
+
ctx.state.set(state);
|
|
292
|
+
ctx.down([
|
|
293
|
+
[
|
|
294
|
+
"DATA",
|
|
295
|
+
Object.freeze({
|
|
296
|
+
activeRecords: Object.freeze(retention.activeRecords),
|
|
297
|
+
archivedRecords: Object.freeze(retention.archivedRecords),
|
|
298
|
+
consolidationRequests: Object.freeze(retention.consolidationRequests),
|
|
299
|
+
status,
|
|
300
|
+
errors,
|
|
301
|
+
cursor
|
|
302
|
+
})
|
|
303
|
+
]
|
|
304
|
+
]);
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: `${name}/projection`,
|
|
308
|
+
factory: "agenticMemoryRetention",
|
|
309
|
+
completeWhenDepsComplete: false,
|
|
310
|
+
errorWhenDepsError: false
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
return {
|
|
314
|
+
input: { records: opts.records, commands: opts.commands },
|
|
315
|
+
projection,
|
|
316
|
+
activeRecords: solutionProjection(
|
|
317
|
+
graph,
|
|
318
|
+
projection,
|
|
319
|
+
`${name}/activeRecords`,
|
|
320
|
+
"agenticMemoryRetentionActiveRecords",
|
|
321
|
+
(fact) => fact.activeRecords
|
|
322
|
+
),
|
|
323
|
+
archivedRecords: solutionProjection(
|
|
324
|
+
graph,
|
|
325
|
+
projection,
|
|
326
|
+
`${name}/archivedRecords`,
|
|
327
|
+
"agenticMemoryRetentionArchivedRecords",
|
|
328
|
+
(fact) => fact.archivedRecords
|
|
329
|
+
),
|
|
330
|
+
consolidationRequests: solutionProjection(
|
|
331
|
+
graph,
|
|
332
|
+
projection,
|
|
333
|
+
`${name}/consolidationRequests`,
|
|
334
|
+
"agenticMemoryRetentionConsolidationRequests",
|
|
335
|
+
(fact) => fact.consolidationRequests
|
|
336
|
+
),
|
|
337
|
+
status: solutionProjection(
|
|
338
|
+
graph,
|
|
339
|
+
projection,
|
|
340
|
+
`${name}/status`,
|
|
341
|
+
"agenticMemoryRetentionStatus",
|
|
342
|
+
(fact) => fact.status
|
|
343
|
+
),
|
|
344
|
+
errors: solutionProjection(
|
|
345
|
+
graph,
|
|
346
|
+
projection,
|
|
347
|
+
`${name}/errors`,
|
|
348
|
+
"agenticMemoryRetentionErrors",
|
|
349
|
+
(fact) => fact.errors
|
|
350
|
+
),
|
|
351
|
+
cursor: solutionProjection(
|
|
352
|
+
graph,
|
|
353
|
+
projection,
|
|
354
|
+
`${name}/cursor`,
|
|
355
|
+
"agenticMemoryRetentionCursor",
|
|
356
|
+
(fact) => fact.cursor
|
|
357
|
+
)
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function agenticMemoryConsolidationBundle(graph, opts) {
|
|
361
|
+
const name = opts.name ?? "agenticMemoryConsolidation";
|
|
362
|
+
const projection = graph.node(
|
|
363
|
+
[opts.records, opts.requests, opts.outcomes],
|
|
364
|
+
(ctx) => {
|
|
365
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
366
|
+
state.evaluation += 1;
|
|
367
|
+
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
368
|
+
const requests = validateConsolidationRequests(depLatest(ctx, 1), recordProjection.records);
|
|
369
|
+
const outcomes = projectConsolidationOutcomes(
|
|
370
|
+
depLatest(ctx, 2),
|
|
371
|
+
requests.requests,
|
|
372
|
+
state.evaluation
|
|
373
|
+
);
|
|
374
|
+
const cursor = Object.freeze({
|
|
375
|
+
evaluation: state.evaluation,
|
|
376
|
+
validRequests: requests.requests.length,
|
|
377
|
+
validOutcomes: outcomes.validOutcomes,
|
|
378
|
+
invalidOutcomes: outcomes.invalidOutcomes,
|
|
379
|
+
results: outcomes.results.length,
|
|
380
|
+
proposedRecordDrafts: outcomes.proposedRecordDrafts.length
|
|
381
|
+
});
|
|
382
|
+
const errors = Object.freeze(
|
|
383
|
+
[
|
|
384
|
+
...recordProjection.errors.map(consolidationErrorFromRecordError),
|
|
385
|
+
...requests.errors.map(consolidationErrorFromRetentionError),
|
|
386
|
+
...outcomes.errors
|
|
387
|
+
].map((error) => freezeError({ ...error, cursor }))
|
|
388
|
+
);
|
|
389
|
+
const status = Object.freeze({
|
|
390
|
+
state: agenticStatusState(errors.length, outcomes.results.length),
|
|
391
|
+
cursor
|
|
392
|
+
});
|
|
393
|
+
ctx.state.set(state);
|
|
394
|
+
ctx.down([
|
|
395
|
+
[
|
|
396
|
+
"DATA",
|
|
397
|
+
Object.freeze({
|
|
398
|
+
results: Object.freeze(outcomes.results),
|
|
399
|
+
proposedRecordDrafts: Object.freeze(outcomes.proposedRecordDrafts),
|
|
400
|
+
commands: Object.freeze(outcomes.commands),
|
|
401
|
+
status,
|
|
402
|
+
errors,
|
|
403
|
+
cursor
|
|
404
|
+
})
|
|
405
|
+
]
|
|
406
|
+
]);
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
name: `${name}/projection`,
|
|
410
|
+
factory: "agenticMemoryConsolidation",
|
|
411
|
+
completeWhenDepsComplete: false,
|
|
412
|
+
errorWhenDepsError: false
|
|
413
|
+
}
|
|
414
|
+
);
|
|
415
|
+
return {
|
|
416
|
+
input: { records: opts.records, requests: opts.requests, outcomes: opts.outcomes },
|
|
417
|
+
projection,
|
|
418
|
+
results: solutionProjection(
|
|
419
|
+
graph,
|
|
420
|
+
projection,
|
|
421
|
+
`${name}/results`,
|
|
422
|
+
"agenticMemoryConsolidationResults",
|
|
423
|
+
(fact) => fact.results
|
|
424
|
+
),
|
|
425
|
+
proposedRecordDrafts: solutionProjection(
|
|
426
|
+
graph,
|
|
427
|
+
projection,
|
|
428
|
+
`${name}/proposedRecordDrafts`,
|
|
429
|
+
"agenticMemoryConsolidationRecordDrafts",
|
|
430
|
+
(fact) => fact.proposedRecordDrafts
|
|
431
|
+
),
|
|
432
|
+
commands: solutionProjection(
|
|
433
|
+
graph,
|
|
434
|
+
projection,
|
|
435
|
+
`${name}/commands`,
|
|
436
|
+
"agenticMemoryConsolidationCommands",
|
|
437
|
+
(fact) => fact.commands
|
|
438
|
+
),
|
|
439
|
+
status: solutionProjection(
|
|
440
|
+
graph,
|
|
441
|
+
projection,
|
|
442
|
+
`${name}/status`,
|
|
443
|
+
"agenticMemoryConsolidationStatus",
|
|
444
|
+
(fact) => fact.status
|
|
445
|
+
),
|
|
446
|
+
errors: solutionProjection(
|
|
447
|
+
graph,
|
|
448
|
+
projection,
|
|
449
|
+
`${name}/errors`,
|
|
450
|
+
"agenticMemoryConsolidationErrors",
|
|
451
|
+
(fact) => fact.errors
|
|
452
|
+
),
|
|
453
|
+
cursor: solutionProjection(
|
|
454
|
+
graph,
|
|
455
|
+
projection,
|
|
456
|
+
`${name}/cursor`,
|
|
457
|
+
"agenticMemoryConsolidationCursor",
|
|
458
|
+
(fact) => fact.cursor
|
|
459
|
+
)
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
function agenticMemoryContextPackingBundle(graph, opts) {
|
|
463
|
+
const name = opts.name ?? "agenticMemoryContextPacking";
|
|
464
|
+
const projection = graph.node(
|
|
465
|
+
[opts.context, opts.texts, opts.policy],
|
|
466
|
+
(ctx) => {
|
|
467
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
468
|
+
state.evaluation += 1;
|
|
469
|
+
const packed = packContext(
|
|
470
|
+
depLatest(ctx, 0),
|
|
471
|
+
depLatest(ctx, 1),
|
|
472
|
+
depLatest(ctx, 2),
|
|
473
|
+
state.evaluation
|
|
474
|
+
);
|
|
475
|
+
ctx.state.set(state);
|
|
476
|
+
ctx.down([["DATA", packed]]);
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
name: `${name}/projection`,
|
|
480
|
+
factory: "agenticMemoryContextPacking",
|
|
481
|
+
completeWhenDepsComplete: false,
|
|
482
|
+
errorWhenDepsError: false
|
|
483
|
+
}
|
|
484
|
+
);
|
|
485
|
+
return {
|
|
486
|
+
input: { context: opts.context, texts: opts.texts, policy: opts.policy },
|
|
487
|
+
projection,
|
|
488
|
+
packedContext: solutionProjection(
|
|
489
|
+
graph,
|
|
490
|
+
projection,
|
|
491
|
+
`${name}/packedContext`,
|
|
492
|
+
"agenticMemoryPackedContext",
|
|
493
|
+
(fact) => fact.packedContext
|
|
494
|
+
),
|
|
495
|
+
status: solutionProjection(
|
|
496
|
+
graph,
|
|
497
|
+
projection,
|
|
498
|
+
`${name}/status`,
|
|
499
|
+
"agenticMemoryContextPackingStatus",
|
|
500
|
+
(fact) => fact.status
|
|
501
|
+
),
|
|
502
|
+
errors: solutionProjection(
|
|
503
|
+
graph,
|
|
504
|
+
projection,
|
|
505
|
+
`${name}/errors`,
|
|
506
|
+
"agenticMemoryContextPackingErrors",
|
|
507
|
+
(fact) => fact.errors
|
|
508
|
+
),
|
|
509
|
+
cursor: solutionProjection(
|
|
510
|
+
graph,
|
|
511
|
+
projection,
|
|
512
|
+
`${name}/cursor`,
|
|
513
|
+
"agenticMemoryContextPackingCursor",
|
|
514
|
+
(fact) => fact.cursor
|
|
515
|
+
)
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
function solutionProjection(graph, snapshot, name, factory, select) {
|
|
519
|
+
return graph.node(
|
|
520
|
+
[snapshot],
|
|
521
|
+
(ctx) => {
|
|
522
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
523
|
+
ctx.down([["DATA", select(raw)]]);
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
name,
|
|
528
|
+
factory,
|
|
529
|
+
completeWhenDepsComplete: false,
|
|
530
|
+
errorWhenDepsError: false
|
|
531
|
+
}
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
function agenticMemoryProjection(graph, snapshot, name, factory, select) {
|
|
535
|
+
return graph.node(
|
|
536
|
+
[snapshot],
|
|
537
|
+
(ctx) => {
|
|
538
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
539
|
+
ctx.down([["DATA", select(raw)]]);
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
name,
|
|
544
|
+
factory,
|
|
545
|
+
completeWhenDepsComplete: false,
|
|
546
|
+
errorWhenDepsError: false
|
|
547
|
+
}
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
function agenticMemoryContextProjection(graph, projection, retrieval, name) {
|
|
551
|
+
return graph.node(
|
|
552
|
+
[projection, retrieval],
|
|
553
|
+
(ctx) => {
|
|
554
|
+
const projectionFact = depLatest(ctx, 0);
|
|
555
|
+
const retrievalFacts = depBatch(ctx, 1) ?? [];
|
|
556
|
+
if (projectionFact === void 0 || retrievalFacts.length === 0) return;
|
|
557
|
+
for (const raw of retrievalFacts) {
|
|
558
|
+
ctx.down([
|
|
559
|
+
["DATA", contextFromSnapshot(projectionFact, raw)]
|
|
560
|
+
]);
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
name,
|
|
565
|
+
factory: "agenticMemoryContext",
|
|
566
|
+
completeWhenDepsComplete: false,
|
|
567
|
+
errorWhenDepsError: false
|
|
568
|
+
}
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
function contextFromSnapshot(projection, retrieval) {
|
|
572
|
+
const entries = retrieval.ranked.results.map(
|
|
573
|
+
(fragment) => Object.freeze({
|
|
574
|
+
fragmentId: fragment.id,
|
|
575
|
+
payload: fragment.payload,
|
|
576
|
+
confidence: fragment.confidence,
|
|
577
|
+
tags: fragment.tags,
|
|
578
|
+
sources: fragment.sources,
|
|
579
|
+
...projection.metadataByFragmentId[fragment.id] === void 0 ? {} : { record: projection.metadataByFragmentId[fragment.id] },
|
|
580
|
+
fragment
|
|
581
|
+
})
|
|
582
|
+
);
|
|
583
|
+
const hasContext = entries.length > 0;
|
|
584
|
+
const state = contextState(projection.status.state, retrieval.status.state);
|
|
585
|
+
return Object.freeze({
|
|
586
|
+
state,
|
|
587
|
+
query: retrieval.ranked.query,
|
|
588
|
+
entries: Object.freeze(entries),
|
|
589
|
+
cursor: retrieval.cursor,
|
|
590
|
+
errors: projection.errors,
|
|
591
|
+
retrievalErrors: retrieval.errors,
|
|
592
|
+
contextReady: hasContext && (state === "ready" || state === "partial")
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
function agenticMemoryRecordProjection(graph, records, name) {
|
|
596
|
+
return graph.node(
|
|
597
|
+
[records],
|
|
598
|
+
(ctx) => {
|
|
599
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
600
|
+
state.evaluation += 1;
|
|
601
|
+
const rawRecords = (depBatch(ctx, 0) ?? []).at(-1);
|
|
602
|
+
const projected = validateAndProjectRecords(rawRecords);
|
|
603
|
+
const cursor = Object.freeze({
|
|
604
|
+
evaluation: state.evaluation,
|
|
605
|
+
validRecords: projected.records.length,
|
|
606
|
+
invalidRecords: projected.invalidRecordIndexes.size,
|
|
607
|
+
projectedFragments: projected.fragments.length
|
|
608
|
+
});
|
|
609
|
+
const status = Object.freeze({
|
|
610
|
+
state: agenticStatusState(projected.errors.length, projected.records.length),
|
|
611
|
+
cursor
|
|
612
|
+
});
|
|
613
|
+
const errors = Object.freeze(
|
|
614
|
+
projected.errors.map(
|
|
615
|
+
(error) => Object.freeze({
|
|
616
|
+
...error,
|
|
617
|
+
...error.validationErrors === void 0 ? {} : { validationErrors: Object.freeze([...error.validationErrors]) },
|
|
618
|
+
cursor
|
|
619
|
+
})
|
|
620
|
+
)
|
|
621
|
+
);
|
|
622
|
+
ctx.state.set(state);
|
|
623
|
+
ctx.down([
|
|
624
|
+
[
|
|
625
|
+
"DATA",
|
|
626
|
+
Object.freeze({
|
|
627
|
+
records: Object.freeze(projected.records),
|
|
628
|
+
fragments: Object.freeze(projected.fragments),
|
|
629
|
+
metadataByFragmentId: Object.freeze(projected.metadataByFragmentId),
|
|
630
|
+
status,
|
|
631
|
+
errors,
|
|
632
|
+
cursor
|
|
633
|
+
})
|
|
634
|
+
]
|
|
635
|
+
]);
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
name,
|
|
639
|
+
factory: "agenticMemoryProjection",
|
|
640
|
+
completeWhenDepsComplete: false,
|
|
641
|
+
errorWhenDepsError: false
|
|
642
|
+
}
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
function validateAndProjectKgDrafts(value, records) {
|
|
646
|
+
const assertions = [];
|
|
647
|
+
const errors = [];
|
|
648
|
+
let invalidDrafts = 0;
|
|
649
|
+
if (!Array.isArray(value)) {
|
|
650
|
+
return {
|
|
651
|
+
assertions,
|
|
652
|
+
invalidDrafts: 1,
|
|
653
|
+
errors: [
|
|
654
|
+
{
|
|
655
|
+
code: "invalid-drafts-input",
|
|
656
|
+
message: "agenticMemoryKgProjectionBundle: drafts input must be an array",
|
|
657
|
+
draft: value
|
|
658
|
+
}
|
|
659
|
+
]
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
const length = safeArrayLength(value);
|
|
663
|
+
if (length === void 0) {
|
|
664
|
+
return {
|
|
665
|
+
assertions,
|
|
666
|
+
invalidDrafts: 1,
|
|
667
|
+
errors: [
|
|
668
|
+
{
|
|
669
|
+
code: "invalid-drafts-input",
|
|
670
|
+
message: "agenticMemoryKgProjectionBundle: drafts input length could not be read",
|
|
671
|
+
draft: value
|
|
672
|
+
}
|
|
673
|
+
]
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
const recordById = new Map(records.map((record) => [record.id, record]));
|
|
677
|
+
const fragmentToRecord = new Map(records.map((record) => [record.fragment.id, record.id]));
|
|
678
|
+
const seenAssertions = /* @__PURE__ */ new Set();
|
|
679
|
+
for (let i = 0; i < length; i += 1) {
|
|
680
|
+
let raw;
|
|
681
|
+
try {
|
|
682
|
+
raw = value[i];
|
|
683
|
+
const result = validateKgDraft(raw, i);
|
|
684
|
+
if (result.errors.length > 0 || result.draft === void 0) {
|
|
685
|
+
invalidDrafts += 1;
|
|
686
|
+
errors.push(...result.errors);
|
|
687
|
+
continue;
|
|
688
|
+
}
|
|
689
|
+
const draft = result.draft;
|
|
690
|
+
if (seenAssertions.has(draft.id)) {
|
|
691
|
+
invalidDrafts += 1;
|
|
692
|
+
errors.push({
|
|
693
|
+
code: "duplicate-assertion-id",
|
|
694
|
+
message: "agenticMemoryKgProjectionBundle: duplicate assertion id",
|
|
695
|
+
index: i,
|
|
696
|
+
assertionId: draft.id,
|
|
697
|
+
recordId: draft.recordId,
|
|
698
|
+
fragmentId: draft.fragmentId,
|
|
699
|
+
draft: raw,
|
|
700
|
+
validationErrors: [`duplicate assertion id '${draft.id}'`]
|
|
701
|
+
});
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
const record = recordById.get(draft.recordId);
|
|
705
|
+
if (record === void 0) {
|
|
706
|
+
invalidDrafts += 1;
|
|
707
|
+
errors.push({
|
|
708
|
+
code: "missing-record-ref",
|
|
709
|
+
message: "agenticMemoryKgProjectionBundle: draft references a missing record",
|
|
710
|
+
index: i,
|
|
711
|
+
assertionId: draft.id,
|
|
712
|
+
recordId: draft.recordId,
|
|
713
|
+
fragmentId: draft.fragmentId,
|
|
714
|
+
draft: raw,
|
|
715
|
+
validationErrors: [`record '${draft.recordId}' is not projected`]
|
|
716
|
+
});
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
const owner = fragmentToRecord.get(draft.fragmentId);
|
|
720
|
+
if (owner === void 0) {
|
|
721
|
+
invalidDrafts += 1;
|
|
722
|
+
errors.push({
|
|
723
|
+
code: "missing-fragment-ref",
|
|
724
|
+
message: "agenticMemoryKgProjectionBundle: draft references a missing fragment",
|
|
725
|
+
index: i,
|
|
726
|
+
assertionId: draft.id,
|
|
727
|
+
recordId: draft.recordId,
|
|
728
|
+
fragmentId: draft.fragmentId,
|
|
729
|
+
draft: raw,
|
|
730
|
+
validationErrors: [`fragment '${draft.fragmentId}' is not projected`]
|
|
731
|
+
});
|
|
732
|
+
continue;
|
|
733
|
+
}
|
|
734
|
+
if (owner !== draft.recordId || record.fragment.id !== draft.fragmentId) {
|
|
735
|
+
invalidDrafts += 1;
|
|
736
|
+
errors.push({
|
|
737
|
+
code: "fragment-record-mismatch",
|
|
738
|
+
message: "agenticMemoryKgProjectionBundle: draft record and fragment refs disagree",
|
|
739
|
+
index: i,
|
|
740
|
+
assertionId: draft.id,
|
|
741
|
+
recordId: draft.recordId,
|
|
742
|
+
fragmentId: draft.fragmentId,
|
|
743
|
+
draft: raw,
|
|
744
|
+
validationErrors: [
|
|
745
|
+
`fragment '${draft.fragmentId}' belongs to record '${owner}', not '${draft.recordId}'`
|
|
746
|
+
]
|
|
747
|
+
});
|
|
748
|
+
continue;
|
|
749
|
+
}
|
|
750
|
+
seenAssertions.add(draft.id);
|
|
751
|
+
assertions.push(
|
|
752
|
+
Object.freeze({
|
|
753
|
+
id: draft.id,
|
|
754
|
+
recordId: draft.recordId,
|
|
755
|
+
fragmentId: draft.fragmentId,
|
|
756
|
+
subject: draft.subject,
|
|
757
|
+
predicate: draft.predicate,
|
|
758
|
+
object: draft.object,
|
|
759
|
+
...draft.confidence === void 0 ? {} : { confidence: draft.confidence },
|
|
760
|
+
sources: Object.freeze(draft.sources ?? [draft.fragmentId]),
|
|
761
|
+
...draft.provenance === void 0 ? {} : { provenance: draft.provenance }
|
|
762
|
+
})
|
|
763
|
+
);
|
|
764
|
+
} catch (error) {
|
|
765
|
+
invalidDrafts += 1;
|
|
766
|
+
errors.push({
|
|
767
|
+
code: "invalid-draft",
|
|
768
|
+
message: `agenticMemoryKgProjectionBundle: draft access failed: ${errorMessage(error)}`,
|
|
769
|
+
index: i,
|
|
770
|
+
draft: raw,
|
|
771
|
+
validationErrors: ["draft access failed"]
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
return { assertions, errors, invalidDrafts };
|
|
776
|
+
}
|
|
777
|
+
function validateKgDraft(value, index) {
|
|
778
|
+
const errors = [];
|
|
779
|
+
if (!isPlainRecord(value)) {
|
|
780
|
+
return {
|
|
781
|
+
errors: [
|
|
782
|
+
{
|
|
783
|
+
code: "invalid-draft",
|
|
784
|
+
message: "agenticMemoryKgProjectionBundle: draft must be an object",
|
|
785
|
+
index,
|
|
786
|
+
draft: value
|
|
787
|
+
}
|
|
788
|
+
]
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
const raw = value;
|
|
792
|
+
const id = typeof raw.id === "string" && raw.id.length > 0 ? raw.id : void 0;
|
|
793
|
+
const recordId = typeof raw.recordId === "string" && raw.recordId.length > 0 ? raw.recordId : void 0;
|
|
794
|
+
const fragmentId = typeof raw.fragmentId === "string" && raw.fragmentId.length > 0 ? raw.fragmentId : void 0;
|
|
795
|
+
const subject = validateAssertionSubject(raw.subject);
|
|
796
|
+
const object = validateAssertionObject(raw.object);
|
|
797
|
+
const shapeErrors = [];
|
|
798
|
+
if (id === void 0) shapeErrors.push("draft.id must be a non-empty string");
|
|
799
|
+
if (recordId === void 0) {
|
|
800
|
+
shapeErrors.push("draft.recordId must be a non-empty string");
|
|
801
|
+
}
|
|
802
|
+
if (fragmentId === void 0) {
|
|
803
|
+
shapeErrors.push("draft.fragmentId must be a non-empty string");
|
|
804
|
+
}
|
|
805
|
+
shapeErrors.push(...subject.errors);
|
|
806
|
+
if (typeof raw.predicate !== "string" || raw.predicate.length === 0) {
|
|
807
|
+
shapeErrors.push("draft.predicate must be a non-empty string");
|
|
808
|
+
}
|
|
809
|
+
shapeErrors.push(...object.errors);
|
|
810
|
+
if (raw.confidence !== void 0 && (!Number.isFinite(raw.confidence) || raw.confidence < 0 || raw.confidence > 1)) {
|
|
811
|
+
shapeErrors.push("draft.confidence must be a finite number in [0, 1]");
|
|
812
|
+
}
|
|
813
|
+
if (raw.sources !== void 0 && !isDenseArrayOf(raw.sources, isNonEmptyString)) {
|
|
814
|
+
shapeErrors.push("draft.sources must be a readonly string array");
|
|
815
|
+
}
|
|
816
|
+
if (raw.provenance !== void 0 && typeof raw.provenance !== "string") {
|
|
817
|
+
shapeErrors.push("draft.provenance must be a string when present");
|
|
818
|
+
}
|
|
819
|
+
if (shapeErrors.length > 0) errors.push(kgShapeError(index, value, ...shapeErrors));
|
|
820
|
+
if (errors.length > 0 || id === void 0 || recordId === void 0 || fragmentId === void 0) {
|
|
821
|
+
return { errors };
|
|
822
|
+
}
|
|
823
|
+
return {
|
|
824
|
+
draft: Object.freeze({
|
|
825
|
+
id,
|
|
826
|
+
recordId,
|
|
827
|
+
fragmentId,
|
|
828
|
+
subject: subject.subject,
|
|
829
|
+
predicate: raw.predicate,
|
|
830
|
+
object: object.object,
|
|
831
|
+
...raw.confidence === void 0 ? {} : { confidence: raw.confidence },
|
|
832
|
+
...raw.sources === void 0 ? {} : { sources: Object.freeze([...raw.sources]) },
|
|
833
|
+
...raw.provenance === void 0 ? {} : { provenance: raw.provenance }
|
|
834
|
+
}),
|
|
835
|
+
errors
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
function validateAssertionSubject(value) {
|
|
839
|
+
if (!isPlainRecord(value)) return { errors: ["subject must be an object"] };
|
|
840
|
+
const id = value.id;
|
|
841
|
+
const type = value.type;
|
|
842
|
+
const errors = [];
|
|
843
|
+
if (typeof id !== "string" || id.length === 0) errors.push("subject.id must be non-empty");
|
|
844
|
+
if (type !== void 0 && (typeof type !== "string" || type.length === 0)) {
|
|
845
|
+
errors.push("subject.type must be a non-empty string when present");
|
|
846
|
+
}
|
|
847
|
+
if (errors.length > 0) return { errors };
|
|
848
|
+
return {
|
|
849
|
+
subject: Object.freeze({
|
|
850
|
+
id,
|
|
851
|
+
...type === void 0 ? {} : { type }
|
|
852
|
+
}),
|
|
853
|
+
errors
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
function validateAssertionObject(value) {
|
|
857
|
+
if (!isPlainRecord(value)) return { errors: ["object must be an object"] };
|
|
858
|
+
const kind = value.kind;
|
|
859
|
+
const errors = [];
|
|
860
|
+
if (kind === "entity") {
|
|
861
|
+
if (typeof value.id !== "string" || value.id.length === 0) {
|
|
862
|
+
errors.push("object.id must be non-empty for entity objects");
|
|
863
|
+
}
|
|
864
|
+
if (value.type !== void 0 && (typeof value.type !== "string" || value.type.length === 0)) {
|
|
865
|
+
errors.push("object.type must be a non-empty string when present");
|
|
866
|
+
}
|
|
867
|
+
if (Object.hasOwn(value, "value")) errors.push("entity object must not include value");
|
|
868
|
+
if (errors.length > 0) return { errors };
|
|
869
|
+
return {
|
|
870
|
+
object: Object.freeze({
|
|
871
|
+
kind: "entity",
|
|
872
|
+
id: value.id,
|
|
873
|
+
...value.type === void 0 ? {} : { type: value.type }
|
|
874
|
+
}),
|
|
875
|
+
errors
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
if (kind === "value") {
|
|
879
|
+
if (!Object.hasOwn(value, "value")) errors.push("value object must include value");
|
|
880
|
+
else {
|
|
881
|
+
try {
|
|
882
|
+
assertStrictJsonValue(value.value, "object.value");
|
|
883
|
+
} catch (error) {
|
|
884
|
+
errors.push(errorMessage(error));
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
if (value.valueType !== void 0 && (typeof value.valueType !== "string" || value.valueType.length === 0)) {
|
|
888
|
+
errors.push("object.valueType must be a non-empty string when present");
|
|
889
|
+
}
|
|
890
|
+
if (Object.hasOwn(value, "id")) errors.push("value object must not include id");
|
|
891
|
+
if (errors.length > 0) return { errors };
|
|
892
|
+
return {
|
|
893
|
+
object: Object.freeze({
|
|
894
|
+
kind: "value",
|
|
895
|
+
value: value.value,
|
|
896
|
+
...value.valueType === void 0 ? {} : { valueType: value.valueType }
|
|
897
|
+
}),
|
|
898
|
+
errors
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
return { errors: ["object.kind must be entity or value"] };
|
|
902
|
+
}
|
|
903
|
+
function kgShapeError(index, draft, ...validationErrors) {
|
|
904
|
+
return {
|
|
905
|
+
code: "invalid-assertion-shape",
|
|
906
|
+
message: "agenticMemoryKgProjectionBundle: draft assertion shape is invalid",
|
|
907
|
+
index,
|
|
908
|
+
draft,
|
|
909
|
+
validationErrors: Object.freeze([...validationErrors])
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
function kgErrorFromRecordError(error) {
|
|
913
|
+
return {
|
|
914
|
+
...error,
|
|
915
|
+
code: error.code
|
|
916
|
+
};
|
|
917
|
+
}
|
|
918
|
+
function fragmentFrame(fragment) {
|
|
919
|
+
return Object.freeze({
|
|
920
|
+
id: fragment.id,
|
|
921
|
+
payload: fragment.payload,
|
|
922
|
+
tNs: decimalBigIntString(fragment.tNs, "fragment.tNs"),
|
|
923
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: decimalBigIntString(fragment.validFrom, "fragment.validFrom") },
|
|
924
|
+
...fragment.validTo === void 0 ? {} : { validTo: decimalBigIntString(fragment.validTo, "fragment.validTo") },
|
|
925
|
+
confidence: fragment.confidence,
|
|
926
|
+
tags: Object.freeze([...fragment.tags]),
|
|
927
|
+
sources: Object.freeze([...fragment.sources]),
|
|
928
|
+
...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
|
|
929
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
930
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
function recordFromFrame(frame) {
|
|
934
|
+
const fragment = frame.record.fragment;
|
|
935
|
+
const record = {
|
|
936
|
+
id: assertNonEmptyString(frame.record.id, "record.id"),
|
|
937
|
+
kind: assertKindValue(frame.record.kind),
|
|
938
|
+
persistenceLevel: assertPersistenceLevelValue(frame.record.persistenceLevel),
|
|
939
|
+
artifactKind: assertArtifactKindValue(frame.record.artifactKind),
|
|
940
|
+
...frame.record.scope === void 0 ? {} : { scope: assertScopeFrame(frame.record.scope) },
|
|
941
|
+
fragment: {
|
|
942
|
+
id: assertNonEmptyString(fragment.id, "fragment.id"),
|
|
943
|
+
payload: assertStrictJsonValue(fragment.payload, "fragment.payload"),
|
|
944
|
+
tNs: parseDecimalBigInt(fragment.tNs, "fragment.tNs"),
|
|
945
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: parseDecimalBigInt(fragment.validFrom, "fragment.validFrom") },
|
|
946
|
+
...fragment.validTo === void 0 ? {} : { validTo: parseDecimalBigInt(fragment.validTo, "fragment.validTo") },
|
|
947
|
+
confidence: assertConfidence(fragment.confidence, "fragment.confidence"),
|
|
948
|
+
tags: assertStringArray(fragment.tags, "fragment.tags"),
|
|
949
|
+
sources: assertStringArray(fragment.sources, "fragment.sources"),
|
|
950
|
+
...fragment.embedding === void 0 ? {} : { embedding: assertFiniteNumberArray(fragment.embedding, "fragment.embedding") },
|
|
951
|
+
...fragment.parentFragmentId === void 0 ? {} : {
|
|
952
|
+
parentFragmentId: assertNonEmptyString(fragment.parentFragmentId, "parentFragmentId")
|
|
953
|
+
},
|
|
954
|
+
...fragment.provenance === void 0 ? {} : { provenance: assertString(fragment.provenance, "provenance") }
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
const result = validateAndSnapshotRecord(record, 0);
|
|
958
|
+
if (result.errors.length > 0 || result.record === void 0) {
|
|
959
|
+
throw new TypeError(
|
|
960
|
+
`agenticMemoryRecordFrame: decoded record is invalid: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
return result.record;
|
|
964
|
+
}
|
|
965
|
+
function projectRetention(value, records) {
|
|
966
|
+
const byId = new Map(records.map((record) => [record.id, record]));
|
|
967
|
+
const view = new Map(records.map((record) => [record.id, record]));
|
|
968
|
+
const requests = [];
|
|
969
|
+
const errors = [];
|
|
970
|
+
let validCommands = 0;
|
|
971
|
+
let invalidCommands = 0;
|
|
972
|
+
if (!Array.isArray(value)) {
|
|
973
|
+
return {
|
|
974
|
+
activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
|
|
975
|
+
archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
|
|
976
|
+
consolidationRequests: requests,
|
|
977
|
+
validCommands,
|
|
978
|
+
invalidCommands: 1,
|
|
979
|
+
errors: [
|
|
980
|
+
{
|
|
981
|
+
code: "invalid-commands-input",
|
|
982
|
+
message: "agenticMemoryRetentionBundle: commands input must be an array",
|
|
983
|
+
command: value
|
|
984
|
+
}
|
|
985
|
+
]
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
const length = safeArrayLength(value);
|
|
989
|
+
if (length === void 0) {
|
|
990
|
+
return {
|
|
991
|
+
activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
|
|
992
|
+
archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
|
|
993
|
+
consolidationRequests: requests,
|
|
994
|
+
validCommands,
|
|
995
|
+
invalidCommands: 1,
|
|
996
|
+
errors: [
|
|
997
|
+
{
|
|
998
|
+
code: "invalid-commands-input",
|
|
999
|
+
message: "agenticMemoryRetentionBundle: commands input length could not be read",
|
|
1000
|
+
command: value
|
|
1001
|
+
}
|
|
1002
|
+
]
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
const seenCommands = /* @__PURE__ */ new Set();
|
|
1006
|
+
for (let i = 0; i < length; i += 1) {
|
|
1007
|
+
let raw;
|
|
1008
|
+
try {
|
|
1009
|
+
raw = value[i];
|
|
1010
|
+
const result = validateRetentionCommand(raw, i);
|
|
1011
|
+
if (result.errors.length > 0 || result.command === void 0) {
|
|
1012
|
+
invalidCommands += 1;
|
|
1013
|
+
errors.push(...result.errors);
|
|
1014
|
+
continue;
|
|
1015
|
+
}
|
|
1016
|
+
const command = result.command;
|
|
1017
|
+
if (seenCommands.has(command.id)) {
|
|
1018
|
+
invalidCommands += 1;
|
|
1019
|
+
errors.push({
|
|
1020
|
+
code: "duplicate-command-id",
|
|
1021
|
+
message: "agenticMemoryRetentionBundle: duplicate command id",
|
|
1022
|
+
index: i,
|
|
1023
|
+
commandId: command.id,
|
|
1024
|
+
command: raw,
|
|
1025
|
+
validationErrors: [`duplicate command id '${command.id}'`]
|
|
1026
|
+
});
|
|
1027
|
+
continue;
|
|
1028
|
+
}
|
|
1029
|
+
const missing = retentionMissingRecords(command, byId);
|
|
1030
|
+
if (missing.length > 0) {
|
|
1031
|
+
invalidCommands += 1;
|
|
1032
|
+
errors.push({
|
|
1033
|
+
code: "missing-record-ref",
|
|
1034
|
+
message: "agenticMemoryRetentionBundle: command references missing records",
|
|
1035
|
+
index: i,
|
|
1036
|
+
commandId: command.id,
|
|
1037
|
+
recordId: "recordId" in command ? command.recordId : void 0,
|
|
1038
|
+
recordIds: Object.freeze(missing),
|
|
1039
|
+
command: raw,
|
|
1040
|
+
validationErrors: Object.freeze(missing.map((id) => `record '${id}' is not projected`))
|
|
1041
|
+
});
|
|
1042
|
+
continue;
|
|
1043
|
+
}
|
|
1044
|
+
seenCommands.add(command.id);
|
|
1045
|
+
validCommands += 1;
|
|
1046
|
+
applyRetentionCommand(command, byId, view, requests);
|
|
1047
|
+
} catch (error) {
|
|
1048
|
+
invalidCommands += 1;
|
|
1049
|
+
errors.push({
|
|
1050
|
+
code: "invalid-command",
|
|
1051
|
+
message: `agenticMemoryRetentionBundle: command access failed: ${errorMessage(error)}`,
|
|
1052
|
+
index: i,
|
|
1053
|
+
command: raw,
|
|
1054
|
+
validationErrors: ["command access failed"]
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
const projected = records.map((record) => view.get(record.id) ?? record);
|
|
1059
|
+
return {
|
|
1060
|
+
activeRecords: projected.filter((record) => record.persistenceLevel !== "archived"),
|
|
1061
|
+
archivedRecords: projected.filter((record) => record.persistenceLevel === "archived"),
|
|
1062
|
+
consolidationRequests: requests,
|
|
1063
|
+
errors,
|
|
1064
|
+
validCommands,
|
|
1065
|
+
invalidCommands
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
function validateRetentionCommand(value, index) {
|
|
1069
|
+
if (!isPlainRecord(value)) {
|
|
1070
|
+
return {
|
|
1071
|
+
errors: [
|
|
1072
|
+
{
|
|
1073
|
+
code: "invalid-command",
|
|
1074
|
+
message: "agenticMemoryRetentionBundle: command must be an object",
|
|
1075
|
+
index,
|
|
1076
|
+
command: value
|
|
1077
|
+
}
|
|
1078
|
+
]
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
const id = typeof value.id === "string" && value.id.length > 0 ? value.id : void 0;
|
|
1082
|
+
const kind = value.kind;
|
|
1083
|
+
const errors = [];
|
|
1084
|
+
if (id === void 0) errors.push("command.id must be a non-empty string");
|
|
1085
|
+
if (kind !== "archive" && kind !== "restore" && kind !== "setPersistenceLevel" && kind !== "requestConsolidation") {
|
|
1086
|
+
errors.push("command.kind is invalid");
|
|
1087
|
+
}
|
|
1088
|
+
if (value.reason !== void 0 && typeof value.reason !== "string") {
|
|
1089
|
+
errors.push("command.reason must be a string when present");
|
|
1090
|
+
}
|
|
1091
|
+
if (kind === "archive") {
|
|
1092
|
+
if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
|
|
1093
|
+
} else if (kind === "restore") {
|
|
1094
|
+
if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
|
|
1095
|
+
if (value.persistenceLevel !== void 0 && (!isAgenticMemoryPersistenceLevel(value.persistenceLevel) || value.persistenceLevel === "archived")) {
|
|
1096
|
+
errors.push("restore.persistenceLevel must be a non-archived persistence level when present");
|
|
1097
|
+
}
|
|
1098
|
+
} else if (kind === "setPersistenceLevel") {
|
|
1099
|
+
if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
|
|
1100
|
+
if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
|
|
1101
|
+
errors.push("setPersistenceLevel.persistenceLevel is invalid");
|
|
1102
|
+
}
|
|
1103
|
+
} else if (kind === "requestConsolidation") {
|
|
1104
|
+
if (!isDenseArrayOf(value.recordIds, isNonEmptyString) || value.recordIds.length === 0) {
|
|
1105
|
+
errors.push("requestConsolidation.recordIds must be a non-empty string array");
|
|
1106
|
+
}
|
|
1107
|
+
if (value.requestId !== void 0 && (typeof value.requestId !== "string" || value.requestId.length === 0)) {
|
|
1108
|
+
errors.push("requestConsolidation.requestId must be non-empty when present");
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
if (errors.length > 0 || id === void 0) {
|
|
1112
|
+
return {
|
|
1113
|
+
errors: [
|
|
1114
|
+
{
|
|
1115
|
+
code: "invalid-command",
|
|
1116
|
+
message: "agenticMemoryRetentionBundle: command is invalid",
|
|
1117
|
+
index,
|
|
1118
|
+
commandId: id,
|
|
1119
|
+
command: value,
|
|
1120
|
+
validationErrors: Object.freeze(errors)
|
|
1121
|
+
}
|
|
1122
|
+
]
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
const base = { id, reason: value.reason };
|
|
1126
|
+
if (kind === "archive") {
|
|
1127
|
+
return {
|
|
1128
|
+
command: Object.freeze({
|
|
1129
|
+
...base,
|
|
1130
|
+
kind,
|
|
1131
|
+
recordId: value.recordId,
|
|
1132
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1133
|
+
}),
|
|
1134
|
+
errors: []
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
if (kind === "restore") {
|
|
1138
|
+
return {
|
|
1139
|
+
command: Object.freeze({
|
|
1140
|
+
...base,
|
|
1141
|
+
kind,
|
|
1142
|
+
recordId: value.recordId,
|
|
1143
|
+
...value.persistenceLevel === void 0 ? {} : {
|
|
1144
|
+
persistenceLevel: value.persistenceLevel
|
|
1145
|
+
},
|
|
1146
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1147
|
+
}),
|
|
1148
|
+
errors: []
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
if (kind === "setPersistenceLevel") {
|
|
1152
|
+
return {
|
|
1153
|
+
command: Object.freeze({
|
|
1154
|
+
...base,
|
|
1155
|
+
kind,
|
|
1156
|
+
recordId: value.recordId,
|
|
1157
|
+
persistenceLevel: value.persistenceLevel,
|
|
1158
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1159
|
+
}),
|
|
1160
|
+
errors: []
|
|
1161
|
+
};
|
|
1162
|
+
}
|
|
1163
|
+
return {
|
|
1164
|
+
command: Object.freeze({
|
|
1165
|
+
...base,
|
|
1166
|
+
kind: "requestConsolidation",
|
|
1167
|
+
recordIds: Object.freeze([...value.recordIds]),
|
|
1168
|
+
...value.requestId === void 0 ? {} : { requestId: value.requestId },
|
|
1169
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1170
|
+
}),
|
|
1171
|
+
errors: []
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
function retentionMissingRecords(command, records) {
|
|
1175
|
+
if ("recordId" in command) return records.has(command.recordId) ? [] : [command.recordId];
|
|
1176
|
+
return command.recordIds.filter((recordId) => !records.has(recordId));
|
|
1177
|
+
}
|
|
1178
|
+
function applyRetentionCommand(command, source, view, requests) {
|
|
1179
|
+
if (command.kind === "requestConsolidation") {
|
|
1180
|
+
requests.push(
|
|
1181
|
+
Object.freeze({
|
|
1182
|
+
id: command.requestId ?? command.id,
|
|
1183
|
+
commandId: command.id,
|
|
1184
|
+
recordIds: Object.freeze([...command.recordIds]),
|
|
1185
|
+
...command.reason === void 0 ? {} : { reason: command.reason }
|
|
1186
|
+
})
|
|
1187
|
+
);
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
const record = view.get(command.recordId) ?? source.get(command.recordId);
|
|
1191
|
+
if (record === void 0) return;
|
|
1192
|
+
const persistenceLevel = command.kind === "archive" ? "archived" : command.kind === "restore" ? command.persistenceLevel ?? nonArchivedLevel(source.get(command.recordId) ?? record) : command.persistenceLevel;
|
|
1193
|
+
view.set(command.recordId, withPersistenceLevel(record, persistenceLevel));
|
|
1194
|
+
}
|
|
1195
|
+
function nonArchivedLevel(record) {
|
|
1196
|
+
return record.persistenceLevel === "archived" ? "session" : record.persistenceLevel;
|
|
1197
|
+
}
|
|
1198
|
+
function withPersistenceLevel(record, persistenceLevel) {
|
|
1199
|
+
return Object.freeze({
|
|
1200
|
+
...record,
|
|
1201
|
+
persistenceLevel
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
function retentionErrorFromRecordError(error) {
|
|
1205
|
+
return {
|
|
1206
|
+
...error,
|
|
1207
|
+
code: error.code
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
function validateConsolidationRequests(value, records) {
|
|
1211
|
+
const byId = new Map(records.map((record) => [record.id, record]));
|
|
1212
|
+
const requests = [];
|
|
1213
|
+
const errors = [];
|
|
1214
|
+
if (!Array.isArray(value)) {
|
|
1215
|
+
return {
|
|
1216
|
+
requests,
|
|
1217
|
+
errors: [
|
|
1218
|
+
{
|
|
1219
|
+
code: "invalid-commands-input",
|
|
1220
|
+
message: "agenticMemoryConsolidationBundle: requests input must be an array",
|
|
1221
|
+
command: value
|
|
1222
|
+
}
|
|
1223
|
+
]
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
const length = safeArrayLength(value);
|
|
1227
|
+
if (length === void 0) {
|
|
1228
|
+
return {
|
|
1229
|
+
requests,
|
|
1230
|
+
errors: [
|
|
1231
|
+
{
|
|
1232
|
+
code: "invalid-commands-input",
|
|
1233
|
+
message: "agenticMemoryConsolidationBundle: requests input length could not be read",
|
|
1234
|
+
command: value
|
|
1235
|
+
}
|
|
1236
|
+
]
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1240
|
+
for (let i = 0; i < length; i += 1) {
|
|
1241
|
+
let raw;
|
|
1242
|
+
try {
|
|
1243
|
+
if (!Object.hasOwn(value, i)) {
|
|
1244
|
+
throw new TypeError("request array must be dense");
|
|
1245
|
+
}
|
|
1246
|
+
raw = value[i];
|
|
1247
|
+
} catch (error) {
|
|
1248
|
+
errors.push({
|
|
1249
|
+
code: "invalid-command",
|
|
1250
|
+
message: `agenticMemoryConsolidationBundle: request access failed: ${errorMessage(error)}`,
|
|
1251
|
+
index: i,
|
|
1252
|
+
validationErrors: Object.freeze(["request access failed"])
|
|
1253
|
+
});
|
|
1254
|
+
continue;
|
|
1255
|
+
}
|
|
1256
|
+
if (!isPlainRecord(raw)) {
|
|
1257
|
+
errors.push({
|
|
1258
|
+
code: "invalid-command",
|
|
1259
|
+
message: "agenticMemoryConsolidationBundle: request must be an object",
|
|
1260
|
+
index: i,
|
|
1261
|
+
command: raw
|
|
1262
|
+
});
|
|
1263
|
+
continue;
|
|
1264
|
+
}
|
|
1265
|
+
const id = isNonEmptyString(raw.id) ? raw.id : void 0;
|
|
1266
|
+
const commandId = isNonEmptyString(raw.commandId) ? raw.commandId : void 0;
|
|
1267
|
+
const recordIds = isDenseArrayOf(raw.recordIds, isNonEmptyString) ? Object.freeze([...raw.recordIds]) : void 0;
|
|
1268
|
+
const validationErrors = [];
|
|
1269
|
+
if (id === void 0) validationErrors.push("request.id must be a non-empty string");
|
|
1270
|
+
if (commandId === void 0) {
|
|
1271
|
+
validationErrors.push("request.commandId must be a non-empty string");
|
|
1272
|
+
}
|
|
1273
|
+
if (recordIds === void 0 || recordIds.length === 0) {
|
|
1274
|
+
validationErrors.push("request.recordIds must be a non-empty string array");
|
|
1275
|
+
}
|
|
1276
|
+
if (raw.reason !== void 0 && typeof raw.reason !== "string") {
|
|
1277
|
+
validationErrors.push("request.reason must be a string when present");
|
|
1278
|
+
}
|
|
1279
|
+
if (id !== void 0 && seen.has(id)) {
|
|
1280
|
+
validationErrors.push(`duplicate request id '${id}'`);
|
|
1281
|
+
}
|
|
1282
|
+
const missing = (recordIds ?? []).filter((recordId) => !byId.has(recordId));
|
|
1283
|
+
if (missing.length > 0) {
|
|
1284
|
+
errors.push({
|
|
1285
|
+
code: "missing-record-ref",
|
|
1286
|
+
message: "agenticMemoryConsolidationBundle: request references missing records",
|
|
1287
|
+
index: i,
|
|
1288
|
+
commandId,
|
|
1289
|
+
recordIds: Object.freeze(missing),
|
|
1290
|
+
command: raw,
|
|
1291
|
+
validationErrors: Object.freeze(
|
|
1292
|
+
missing.map((recordId) => `record '${recordId}' is not projected`)
|
|
1293
|
+
)
|
|
1294
|
+
});
|
|
1295
|
+
continue;
|
|
1296
|
+
}
|
|
1297
|
+
if (validationErrors.length > 0 || id === void 0 || commandId === void 0 || recordIds === void 0) {
|
|
1298
|
+
errors.push({
|
|
1299
|
+
code: "invalid-command",
|
|
1300
|
+
message: "agenticMemoryConsolidationBundle: request is invalid",
|
|
1301
|
+
index: i,
|
|
1302
|
+
commandId,
|
|
1303
|
+
recordIds,
|
|
1304
|
+
command: raw,
|
|
1305
|
+
validationErrors: Object.freeze(validationErrors)
|
|
1306
|
+
});
|
|
1307
|
+
continue;
|
|
1308
|
+
}
|
|
1309
|
+
seen.add(id);
|
|
1310
|
+
requests.push(
|
|
1311
|
+
Object.freeze({
|
|
1312
|
+
id,
|
|
1313
|
+
commandId,
|
|
1314
|
+
recordIds,
|
|
1315
|
+
...raw.reason === void 0 ? {} : { reason: raw.reason }
|
|
1316
|
+
})
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
return { requests: Object.freeze(requests), errors };
|
|
1320
|
+
}
|
|
1321
|
+
function projectConsolidationOutcomes(value, requests, evaluation) {
|
|
1322
|
+
const byRequest = new Map(requests.map((request) => [request.id, request]));
|
|
1323
|
+
const results = [];
|
|
1324
|
+
const proposedRecordDrafts = [];
|
|
1325
|
+
const commands = [];
|
|
1326
|
+
const errors = [];
|
|
1327
|
+
let validOutcomes = 0;
|
|
1328
|
+
let invalidOutcomes = 0;
|
|
1329
|
+
if (!Array.isArray(value)) {
|
|
1330
|
+
return {
|
|
1331
|
+
results,
|
|
1332
|
+
proposedRecordDrafts,
|
|
1333
|
+
commands,
|
|
1334
|
+
validOutcomes,
|
|
1335
|
+
invalidOutcomes: 1,
|
|
1336
|
+
errors: [
|
|
1337
|
+
{
|
|
1338
|
+
code: "invalid-outcomes-input",
|
|
1339
|
+
message: "agenticMemoryConsolidationBundle: outcomes input must be an array",
|
|
1340
|
+
outcome: value
|
|
1341
|
+
}
|
|
1342
|
+
]
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
const length = safeArrayLength(value);
|
|
1346
|
+
if (length === void 0) {
|
|
1347
|
+
return {
|
|
1348
|
+
results,
|
|
1349
|
+
proposedRecordDrafts,
|
|
1350
|
+
commands,
|
|
1351
|
+
validOutcomes,
|
|
1352
|
+
invalidOutcomes: 1,
|
|
1353
|
+
errors: [
|
|
1354
|
+
{
|
|
1355
|
+
code: "invalid-outcomes-input",
|
|
1356
|
+
message: "agenticMemoryConsolidationBundle: outcomes input length could not be read",
|
|
1357
|
+
outcome: value
|
|
1358
|
+
}
|
|
1359
|
+
]
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
const seenOutcomes = /* @__PURE__ */ new Set();
|
|
1363
|
+
for (let i = 0; i < length; i += 1) {
|
|
1364
|
+
let raw;
|
|
1365
|
+
let outcome;
|
|
1366
|
+
try {
|
|
1367
|
+
if (!Object.hasOwn(value, i)) {
|
|
1368
|
+
throw new TypeError("outcome array must be dense");
|
|
1369
|
+
}
|
|
1370
|
+
raw = value[i];
|
|
1371
|
+
outcome = validateConsolidationOutcome(raw, i);
|
|
1372
|
+
} catch (error) {
|
|
1373
|
+
invalidOutcomes += 1;
|
|
1374
|
+
errors.push({
|
|
1375
|
+
code: "invalid-outcome",
|
|
1376
|
+
message: `agenticMemoryConsolidationBundle: outcome access failed: ${errorMessage(error)}`,
|
|
1377
|
+
index: i,
|
|
1378
|
+
outcome: raw,
|
|
1379
|
+
validationErrors: Object.freeze(["outcome access failed"])
|
|
1380
|
+
});
|
|
1381
|
+
continue;
|
|
1382
|
+
}
|
|
1383
|
+
if (outcome.error !== void 0 || outcome.outcome === void 0) {
|
|
1384
|
+
invalidOutcomes += 1;
|
|
1385
|
+
if (outcome.error !== void 0) errors.push(outcome.error);
|
|
1386
|
+
continue;
|
|
1387
|
+
}
|
|
1388
|
+
const validOutcome = outcome.outcome;
|
|
1389
|
+
if (seenOutcomes.has(validOutcome.id)) {
|
|
1390
|
+
invalidOutcomes += 1;
|
|
1391
|
+
errors.push({
|
|
1392
|
+
code: "duplicate-outcome-id",
|
|
1393
|
+
message: "agenticMemoryConsolidationBundle: duplicate outcome id",
|
|
1394
|
+
index: i,
|
|
1395
|
+
outcomeId: validOutcome.id,
|
|
1396
|
+
requestId: validOutcome.requestId,
|
|
1397
|
+
outcome: raw,
|
|
1398
|
+
validationErrors: Object.freeze([`duplicate outcome id '${validOutcome.id}'`])
|
|
1399
|
+
});
|
|
1400
|
+
continue;
|
|
1401
|
+
}
|
|
1402
|
+
const request = byRequest.get(validOutcome.requestId);
|
|
1403
|
+
if (request === void 0) {
|
|
1404
|
+
invalidOutcomes += 1;
|
|
1405
|
+
errors.push({
|
|
1406
|
+
code: "missing-request-ref",
|
|
1407
|
+
message: "agenticMemoryConsolidationBundle: outcome references missing request",
|
|
1408
|
+
index: i,
|
|
1409
|
+
outcomeId: validOutcome.id,
|
|
1410
|
+
requestId: validOutcome.requestId,
|
|
1411
|
+
outcome: raw,
|
|
1412
|
+
validationErrors: Object.freeze([`request '${validOutcome.requestId}' is not projected`])
|
|
1413
|
+
});
|
|
1414
|
+
continue;
|
|
1415
|
+
}
|
|
1416
|
+
seenOutcomes.add(validOutcome.id);
|
|
1417
|
+
validOutcomes += 1;
|
|
1418
|
+
if (validOutcome.kind === "failed") {
|
|
1419
|
+
const resultId2 = `${validOutcome.requestId}:${validOutcome.id}`;
|
|
1420
|
+
results.push(
|
|
1421
|
+
Object.freeze({
|
|
1422
|
+
id: resultId2,
|
|
1423
|
+
requestId: validOutcome.requestId,
|
|
1424
|
+
outcomeId: validOutcome.id,
|
|
1425
|
+
state: "failed",
|
|
1426
|
+
sourceRecordIds: request.recordIds,
|
|
1427
|
+
proposedRecordIds: Object.freeze([]),
|
|
1428
|
+
message: validOutcome.message,
|
|
1429
|
+
...validOutcome.provenance === void 0 ? {} : { provenance: validOutcome.provenance }
|
|
1430
|
+
})
|
|
1431
|
+
);
|
|
1432
|
+
commands.push(
|
|
1433
|
+
Object.freeze({
|
|
1434
|
+
id: `${resultId2}:markFailed`,
|
|
1435
|
+
kind: "markFailed",
|
|
1436
|
+
requestId: validOutcome.requestId,
|
|
1437
|
+
outcomeId: validOutcome.id,
|
|
1438
|
+
message: validOutcome.message
|
|
1439
|
+
})
|
|
1440
|
+
);
|
|
1441
|
+
continue;
|
|
1442
|
+
}
|
|
1443
|
+
const draftIds = validOutcome.records.map(
|
|
1444
|
+
(record) => `${validOutcome.requestId}:${validOutcome.id}:${record.id}`
|
|
1445
|
+
);
|
|
1446
|
+
for (let recordIndex = 0; recordIndex < validOutcome.records.length; recordIndex += 1) {
|
|
1447
|
+
proposedRecordDrafts.push(
|
|
1448
|
+
Object.freeze({
|
|
1449
|
+
id: draftIds[recordIndex],
|
|
1450
|
+
requestId: validOutcome.requestId,
|
|
1451
|
+
outcomeId: validOutcome.id,
|
|
1452
|
+
record: validOutcome.records[recordIndex]
|
|
1453
|
+
})
|
|
1454
|
+
);
|
|
1455
|
+
}
|
|
1456
|
+
const resultId = `${validOutcome.requestId}:${validOutcome.id}`;
|
|
1457
|
+
results.push(
|
|
1458
|
+
Object.freeze({
|
|
1459
|
+
id: resultId,
|
|
1460
|
+
requestId: validOutcome.requestId,
|
|
1461
|
+
outcomeId: validOutcome.id,
|
|
1462
|
+
state: "proposed",
|
|
1463
|
+
sourceRecordIds: request.recordIds,
|
|
1464
|
+
proposedRecordIds: Object.freeze(validOutcome.records.map((record) => record.id)),
|
|
1465
|
+
...validOutcome.provenance === void 0 ? {} : { provenance: validOutcome.provenance }
|
|
1466
|
+
})
|
|
1467
|
+
);
|
|
1468
|
+
commands.push(
|
|
1469
|
+
Object.freeze({
|
|
1470
|
+
id: `${resultId}:proposeRecords`,
|
|
1471
|
+
kind: "proposeRecords",
|
|
1472
|
+
requestId: validOutcome.requestId,
|
|
1473
|
+
outcomeId: validOutcome.id,
|
|
1474
|
+
draftIds: Object.freeze(draftIds)
|
|
1475
|
+
})
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1478
|
+
void evaluation;
|
|
1479
|
+
return {
|
|
1480
|
+
results: Object.freeze(results),
|
|
1481
|
+
proposedRecordDrafts: Object.freeze(proposedRecordDrafts),
|
|
1482
|
+
commands: Object.freeze(commands),
|
|
1483
|
+
errors,
|
|
1484
|
+
validOutcomes,
|
|
1485
|
+
invalidOutcomes
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
function validateConsolidationOutcome(value, index) {
|
|
1489
|
+
if (!isPlainRecord(value)) {
|
|
1490
|
+
return {
|
|
1491
|
+
error: {
|
|
1492
|
+
code: "invalid-outcome",
|
|
1493
|
+
message: "agenticMemoryConsolidationBundle: outcome must be an object",
|
|
1494
|
+
index,
|
|
1495
|
+
outcome: value
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
const errors = [];
|
|
1500
|
+
const id = isNonEmptyString(value.id) ? value.id : void 0;
|
|
1501
|
+
const requestId = isNonEmptyString(value.requestId) ? value.requestId : void 0;
|
|
1502
|
+
if (id === void 0) errors.push("outcome.id must be a non-empty string");
|
|
1503
|
+
if (requestId === void 0) errors.push("outcome.requestId must be a non-empty string");
|
|
1504
|
+
if (value.kind !== "proposedRecords" && value.kind !== "failed") {
|
|
1505
|
+
errors.push("outcome.kind must be proposedRecords or failed");
|
|
1506
|
+
}
|
|
1507
|
+
if (value.provenance !== void 0 && typeof value.provenance !== "string") {
|
|
1508
|
+
errors.push("outcome.provenance must be a string when present");
|
|
1509
|
+
}
|
|
1510
|
+
if (value.kind === "failed" && !isNonEmptyString(value.message)) {
|
|
1511
|
+
errors.push("failed outcome.message must be a non-empty string");
|
|
1512
|
+
}
|
|
1513
|
+
const records = [];
|
|
1514
|
+
if (value.kind === "proposedRecords") {
|
|
1515
|
+
if (!Array.isArray(value.records)) {
|
|
1516
|
+
errors.push("proposedRecords.records must be a non-empty array");
|
|
1517
|
+
} else {
|
|
1518
|
+
const recordsLength = safeArrayLength(value.records);
|
|
1519
|
+
const seenRecordIds = /* @__PURE__ */ new Set();
|
|
1520
|
+
if (recordsLength === void 0 || recordsLength === 0) {
|
|
1521
|
+
errors.push("proposedRecords.records must be a non-empty array");
|
|
1522
|
+
}
|
|
1523
|
+
for (let i = 0; i < (recordsLength ?? 0); i += 1) {
|
|
1524
|
+
let result;
|
|
1525
|
+
try {
|
|
1526
|
+
if (!Object.hasOwn(value.records, i)) {
|
|
1527
|
+
throw new TypeError("proposedRecords.records must be dense");
|
|
1528
|
+
}
|
|
1529
|
+
result = validateAndSnapshotRecord(value.records[i], i);
|
|
1530
|
+
} catch (error) {
|
|
1531
|
+
errors.push(`records[${i}]: record access failed: ${errorMessage(error)}`);
|
|
1532
|
+
continue;
|
|
1533
|
+
}
|
|
1534
|
+
if (result.record === void 0 || result.errors.length > 0) {
|
|
1535
|
+
errors.push(
|
|
1536
|
+
...result.errors.flatMap((error) => error.validationErrors ?? [error.message]).map((error) => `records[${i}]: ${error}`)
|
|
1537
|
+
);
|
|
1538
|
+
} else if (seenRecordIds.has(result.record.id)) {
|
|
1539
|
+
errors.push(`records[${i}]: duplicate proposed record id '${result.record.id}'`);
|
|
1540
|
+
} else {
|
|
1541
|
+
seenRecordIds.add(result.record.id);
|
|
1542
|
+
records.push(result.record);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
if (errors.length > 0 || id === void 0 || requestId === void 0) {
|
|
1548
|
+
return {
|
|
1549
|
+
error: {
|
|
1550
|
+
code: value.kind === "proposedRecords" ? "invalid-proposed-record" : "invalid-outcome",
|
|
1551
|
+
message: "agenticMemoryConsolidationBundle: outcome is invalid",
|
|
1552
|
+
index,
|
|
1553
|
+
outcomeId: id,
|
|
1554
|
+
requestId,
|
|
1555
|
+
outcome: value,
|
|
1556
|
+
validationErrors: Object.freeze(errors)
|
|
1557
|
+
}
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
if (value.kind === "failed") {
|
|
1561
|
+
return {
|
|
1562
|
+
outcome: Object.freeze({
|
|
1563
|
+
id,
|
|
1564
|
+
requestId,
|
|
1565
|
+
kind: "failed",
|
|
1566
|
+
message: value.message,
|
|
1567
|
+
...value.provenance === void 0 ? {} : { provenance: value.provenance }
|
|
1568
|
+
})
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
return {
|
|
1572
|
+
outcome: Object.freeze({
|
|
1573
|
+
id,
|
|
1574
|
+
requestId,
|
|
1575
|
+
kind: "proposedRecords",
|
|
1576
|
+
records: Object.freeze(records),
|
|
1577
|
+
...value.provenance === void 0 ? {} : { provenance: value.provenance }
|
|
1578
|
+
})
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
function consolidationErrorFromRecordError(error) {
|
|
1582
|
+
return {
|
|
1583
|
+
...error,
|
|
1584
|
+
code: error.code
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
function consolidationErrorFromRetentionError(error) {
|
|
1588
|
+
return {
|
|
1589
|
+
...error,
|
|
1590
|
+
code: error.code
|
|
1591
|
+
};
|
|
1592
|
+
}
|
|
1593
|
+
function packContext(contextValue, textsValue, policyValue, evaluation) {
|
|
1594
|
+
const errors = [];
|
|
1595
|
+
const context = validatePackingContext(contextValue, errors);
|
|
1596
|
+
const texts = validateContextTexts(textsValue, errors);
|
|
1597
|
+
const policy = validatePackingPolicy(policyValue, errors);
|
|
1598
|
+
const packedEntries = [];
|
|
1599
|
+
let omittedEntries = 0;
|
|
1600
|
+
let totalChars = 0;
|
|
1601
|
+
let totalCost = 0;
|
|
1602
|
+
if (context !== void 0 && policy !== void 0) {
|
|
1603
|
+
for (const entry of context.entries) {
|
|
1604
|
+
const textFact = texts.get(entry.fragmentId);
|
|
1605
|
+
if (textFact === void 0) {
|
|
1606
|
+
omittedEntries += 1;
|
|
1607
|
+
errors.push({
|
|
1608
|
+
code: "missing-text",
|
|
1609
|
+
message: "agenticMemoryContextPackingBundle: missing text projection for context entry",
|
|
1610
|
+
fragmentId: entry.fragmentId,
|
|
1611
|
+
validationErrors: [`missing text for fragment '${entry.fragmentId}'`]
|
|
1612
|
+
});
|
|
1613
|
+
continue;
|
|
1614
|
+
}
|
|
1615
|
+
const cost = textFact.cost ?? textFact.text.length;
|
|
1616
|
+
const nextEntries = packedEntries.length + 1;
|
|
1617
|
+
const separatorChars = packedEntries.length === 0 ? 0 : 2;
|
|
1618
|
+
const nextChars = totalChars + separatorChars + textFact.text.length;
|
|
1619
|
+
const nextCost = totalCost + cost;
|
|
1620
|
+
const exceeds = policy.maxEntries !== void 0 && nextEntries > policy.maxEntries || policy.maxChars !== void 0 && nextChars > policy.maxChars || policy.maxCost !== void 0 && nextCost > policy.maxCost;
|
|
1621
|
+
if (exceeds) {
|
|
1622
|
+
omittedEntries += 1;
|
|
1623
|
+
continue;
|
|
1624
|
+
}
|
|
1625
|
+
const packedEntry = Object.freeze({
|
|
1626
|
+
fragmentId: entry.fragmentId,
|
|
1627
|
+
text: textFact.text,
|
|
1628
|
+
cost,
|
|
1629
|
+
chars: textFact.text.length,
|
|
1630
|
+
...entry.record === void 0 ? {} : { record: entry.record },
|
|
1631
|
+
...policy.includeMetadata && textFact.metadata !== void 0 ? { metadata: textFact.metadata } : {}
|
|
1632
|
+
});
|
|
1633
|
+
packedEntries.push(packedEntry);
|
|
1634
|
+
totalChars = nextChars;
|
|
1635
|
+
totalCost = nextCost;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
const cursor = Object.freeze({
|
|
1639
|
+
evaluation,
|
|
1640
|
+
inputEntries: context?.entries.length ?? 0,
|
|
1641
|
+
packedEntries: packedEntries.length,
|
|
1642
|
+
omittedEntries,
|
|
1643
|
+
totalChars,
|
|
1644
|
+
totalCost
|
|
1645
|
+
});
|
|
1646
|
+
const errorFacts = Object.freeze(
|
|
1647
|
+
errors.map(
|
|
1648
|
+
(error) => freezeError({
|
|
1649
|
+
...error,
|
|
1650
|
+
cursor
|
|
1651
|
+
})
|
|
1652
|
+
)
|
|
1653
|
+
);
|
|
1654
|
+
const packedContext = Object.freeze({
|
|
1655
|
+
entries: Object.freeze(packedEntries),
|
|
1656
|
+
text: packedEntries.map((entry) => entry.text).join("\n\n"),
|
|
1657
|
+
totalChars,
|
|
1658
|
+
totalCost,
|
|
1659
|
+
truncated: omittedEntries > 0
|
|
1660
|
+
});
|
|
1661
|
+
const status = Object.freeze({
|
|
1662
|
+
state: agenticStatusState(errorFacts.length, packedEntries.length),
|
|
1663
|
+
cursor
|
|
1664
|
+
});
|
|
1665
|
+
return Object.freeze({
|
|
1666
|
+
packedContext,
|
|
1667
|
+
status,
|
|
1668
|
+
errors: errorFacts,
|
|
1669
|
+
cursor
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1672
|
+
function validatePackingContext(value, errors) {
|
|
1673
|
+
if (!isPlainRecord(value)) {
|
|
1674
|
+
errors.push({
|
|
1675
|
+
code: "invalid-context",
|
|
1676
|
+
message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
|
|
1677
|
+
value
|
|
1678
|
+
});
|
|
1679
|
+
return void 0;
|
|
1680
|
+
}
|
|
1681
|
+
let entriesValue;
|
|
1682
|
+
try {
|
|
1683
|
+
entriesValue = value.entries;
|
|
1684
|
+
} catch (error) {
|
|
1685
|
+
errors.push({
|
|
1686
|
+
code: "invalid-context",
|
|
1687
|
+
message: `agenticMemoryContextPackingBundle: context entries access failed: ${errorMessage(error)}`,
|
|
1688
|
+
value,
|
|
1689
|
+
validationErrors: ["context entries access failed"]
|
|
1690
|
+
});
|
|
1691
|
+
return void 0;
|
|
1692
|
+
}
|
|
1693
|
+
if (!Array.isArray(entriesValue)) {
|
|
1694
|
+
errors.push({
|
|
1695
|
+
code: "invalid-context",
|
|
1696
|
+
message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
|
|
1697
|
+
value,
|
|
1698
|
+
validationErrors: ["context.entries must be an array"]
|
|
1699
|
+
});
|
|
1700
|
+
return void 0;
|
|
1701
|
+
}
|
|
1702
|
+
const length = safeArrayLength(entriesValue);
|
|
1703
|
+
if (length === void 0) {
|
|
1704
|
+
errors.push({
|
|
1705
|
+
code: "invalid-context",
|
|
1706
|
+
message: "agenticMemoryContextPackingBundle: context entries length could not be read",
|
|
1707
|
+
value,
|
|
1708
|
+
validationErrors: ["context.entries length could not be read"]
|
|
1709
|
+
});
|
|
1710
|
+
return void 0;
|
|
1711
|
+
}
|
|
1712
|
+
const entries = [];
|
|
1713
|
+
for (let i = 0; i < length; i += 1) {
|
|
1714
|
+
let raw;
|
|
1715
|
+
try {
|
|
1716
|
+
raw = entriesValue[i];
|
|
1717
|
+
if (!isPlainRecord(raw) || !isNonEmptyString(raw.fragmentId)) {
|
|
1718
|
+
errors.push({
|
|
1719
|
+
code: "invalid-context",
|
|
1720
|
+
message: "agenticMemoryContextPackingBundle: context entry is invalid",
|
|
1721
|
+
index: i,
|
|
1722
|
+
value: raw,
|
|
1723
|
+
validationErrors: ["context entry fragmentId must be a non-empty string"]
|
|
1724
|
+
});
|
|
1725
|
+
continue;
|
|
1726
|
+
}
|
|
1727
|
+
const record = validateRecordMetadata(raw.record);
|
|
1728
|
+
if (!record.ok) {
|
|
1729
|
+
errors.push({
|
|
1730
|
+
code: "invalid-context",
|
|
1731
|
+
message: "agenticMemoryContextPackingBundle: context entry record metadata is invalid",
|
|
1732
|
+
index: i,
|
|
1733
|
+
fragmentId: raw.fragmentId,
|
|
1734
|
+
value: raw,
|
|
1735
|
+
validationErrors: Object.freeze(record.errors)
|
|
1736
|
+
});
|
|
1737
|
+
continue;
|
|
1738
|
+
}
|
|
1739
|
+
entries.push(
|
|
1740
|
+
Object.freeze({
|
|
1741
|
+
fragmentId: raw.fragmentId,
|
|
1742
|
+
...record.metadata === void 0 ? {} : { record: record.metadata }
|
|
1743
|
+
})
|
|
1744
|
+
);
|
|
1745
|
+
} catch (error) {
|
|
1746
|
+
errors.push({
|
|
1747
|
+
code: "invalid-context",
|
|
1748
|
+
message: `agenticMemoryContextPackingBundle: context entry access failed: ${errorMessage(error)}`,
|
|
1749
|
+
index: i,
|
|
1750
|
+
value: raw,
|
|
1751
|
+
validationErrors: ["context entry access failed"]
|
|
1752
|
+
});
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
return Object.freeze({
|
|
1756
|
+
entries: Object.freeze(entries)
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
function validateContextTexts(value, errors) {
|
|
1760
|
+
const out = /* @__PURE__ */ new Map();
|
|
1761
|
+
if (!Array.isArray(value)) {
|
|
1762
|
+
errors.push({
|
|
1763
|
+
code: "invalid-texts-input",
|
|
1764
|
+
message: "agenticMemoryContextPackingBundle: texts input must be an array",
|
|
1765
|
+
value
|
|
1766
|
+
});
|
|
1767
|
+
return out;
|
|
1768
|
+
}
|
|
1769
|
+
const length = safeArrayLength(value);
|
|
1770
|
+
if (length === void 0) {
|
|
1771
|
+
errors.push({
|
|
1772
|
+
code: "invalid-texts-input",
|
|
1773
|
+
message: "agenticMemoryContextPackingBundle: texts input length could not be read",
|
|
1774
|
+
value
|
|
1775
|
+
});
|
|
1776
|
+
return out;
|
|
1777
|
+
}
|
|
1778
|
+
for (let i = 0; i < length; i += 1) {
|
|
1779
|
+
try {
|
|
1780
|
+
const raw = value[i];
|
|
1781
|
+
const result = validateContextText(raw, i);
|
|
1782
|
+
if (result.error !== void 0) {
|
|
1783
|
+
errors.push(result.error);
|
|
1784
|
+
continue;
|
|
1785
|
+
}
|
|
1786
|
+
if (result.text === void 0) {
|
|
1787
|
+
errors.push({
|
|
1788
|
+
code: "invalid-text",
|
|
1789
|
+
message: "agenticMemoryContextPackingBundle: text fact is invalid",
|
|
1790
|
+
index: i,
|
|
1791
|
+
value: raw,
|
|
1792
|
+
validationErrors: ["text validation returned no fact"]
|
|
1793
|
+
});
|
|
1794
|
+
continue;
|
|
1795
|
+
}
|
|
1796
|
+
if (out.has(result.text.fragmentId)) {
|
|
1797
|
+
errors.push({
|
|
1798
|
+
code: "duplicate-text-fragment-id",
|
|
1799
|
+
message: "agenticMemoryContextPackingBundle: duplicate text fragment id",
|
|
1800
|
+
index: i,
|
|
1801
|
+
fragmentId: result.text.fragmentId,
|
|
1802
|
+
value: raw,
|
|
1803
|
+
validationErrors: [`duplicate text fragment id '${result.text.fragmentId}'`]
|
|
1804
|
+
});
|
|
1805
|
+
continue;
|
|
1806
|
+
}
|
|
1807
|
+
out.set(result.text.fragmentId, result.text);
|
|
1808
|
+
} catch (error) {
|
|
1809
|
+
errors.push({
|
|
1810
|
+
code: "invalid-text",
|
|
1811
|
+
message: `agenticMemoryContextPackingBundle: text access failed: ${errorMessage(error)}`,
|
|
1812
|
+
index: i,
|
|
1813
|
+
validationErrors: ["text access failed"]
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
return out;
|
|
1818
|
+
}
|
|
1819
|
+
function validateContextText(value, index) {
|
|
1820
|
+
if (!isPlainRecord(value)) {
|
|
1821
|
+
return {
|
|
1822
|
+
error: {
|
|
1823
|
+
code: "invalid-text",
|
|
1824
|
+
message: "agenticMemoryContextPackingBundle: text fact must be an object",
|
|
1825
|
+
index,
|
|
1826
|
+
value
|
|
1827
|
+
}
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
const errors = [];
|
|
1831
|
+
if (!isNonEmptyString(value.fragmentId)) errors.push("fragmentId must be a non-empty string");
|
|
1832
|
+
if (typeof value.text !== "string") errors.push("text must be a string");
|
|
1833
|
+
if (value.cost !== void 0 && (typeof value.cost !== "number" || !Number.isFinite(value.cost) || value.cost < 0)) {
|
|
1834
|
+
errors.push("cost must be a finite number >= 0");
|
|
1835
|
+
}
|
|
1836
|
+
if (value.metadata !== void 0) {
|
|
1837
|
+
try {
|
|
1838
|
+
if (!isPlainRecord(value.metadata)) {
|
|
1839
|
+
throw new TypeError("metadata must be a plain object when present");
|
|
1840
|
+
}
|
|
1841
|
+
assertStrictJsonValue(value.metadata, "metadata");
|
|
1842
|
+
} catch (error) {
|
|
1843
|
+
errors.push(errorMessage(error));
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
if (errors.length > 0) {
|
|
1847
|
+
return {
|
|
1848
|
+
error: {
|
|
1849
|
+
code: "invalid-text",
|
|
1850
|
+
message: "agenticMemoryContextPackingBundle: text fact is invalid",
|
|
1851
|
+
index,
|
|
1852
|
+
fragmentId: typeof value.fragmentId === "string" ? value.fragmentId : void 0,
|
|
1853
|
+
value,
|
|
1854
|
+
validationErrors: Object.freeze(errors)
|
|
1855
|
+
}
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1858
|
+
return {
|
|
1859
|
+
text: Object.freeze({
|
|
1860
|
+
fragmentId: value.fragmentId,
|
|
1861
|
+
text: value.text,
|
|
1862
|
+
...value.cost === void 0 ? {} : { cost: value.cost },
|
|
1863
|
+
...value.metadata === void 0 ? {} : { metadata: Object.freeze({ ...value.metadata }) }
|
|
1864
|
+
})
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1867
|
+
function validatePackingPolicy(value, errors) {
|
|
1868
|
+
if (!isPlainRecord(value)) {
|
|
1869
|
+
errors.push({
|
|
1870
|
+
code: "invalid-policy",
|
|
1871
|
+
message: "agenticMemoryContextPackingBundle: policy must be an object",
|
|
1872
|
+
value
|
|
1873
|
+
});
|
|
1874
|
+
return void 0;
|
|
1875
|
+
}
|
|
1876
|
+
const validation = [];
|
|
1877
|
+
let maxEntries;
|
|
1878
|
+
let maxChars;
|
|
1879
|
+
let maxCost;
|
|
1880
|
+
let includeMetadata;
|
|
1881
|
+
try {
|
|
1882
|
+
maxEntries = value.maxEntries;
|
|
1883
|
+
maxChars = value.maxChars;
|
|
1884
|
+
maxCost = value.maxCost;
|
|
1885
|
+
includeMetadata = value.includeMetadata;
|
|
1886
|
+
} catch (error) {
|
|
1887
|
+
errors.push({
|
|
1888
|
+
code: "invalid-policy",
|
|
1889
|
+
message: `agenticMemoryContextPackingBundle: policy access failed: ${errorMessage(error)}`,
|
|
1890
|
+
value,
|
|
1891
|
+
validationErrors: ["policy access failed"]
|
|
1892
|
+
});
|
|
1893
|
+
return void 0;
|
|
1894
|
+
}
|
|
1895
|
+
if (maxEntries !== void 0 && (typeof maxEntries !== "number" || !Number.isSafeInteger(maxEntries) || maxEntries < 0)) {
|
|
1896
|
+
validation.push("maxEntries must be a safe integer >= 0");
|
|
1897
|
+
}
|
|
1898
|
+
if (maxChars !== void 0 && (typeof maxChars !== "number" || !Number.isSafeInteger(maxChars) || maxChars < 0)) {
|
|
1899
|
+
validation.push("maxChars must be a safe integer >= 0");
|
|
1900
|
+
}
|
|
1901
|
+
if (maxCost !== void 0 && (typeof maxCost !== "number" || !Number.isFinite(maxCost) || maxCost < 0)) {
|
|
1902
|
+
validation.push("maxCost must be a finite number >= 0");
|
|
1903
|
+
}
|
|
1904
|
+
if (includeMetadata !== void 0 && typeof includeMetadata !== "boolean") {
|
|
1905
|
+
validation.push("includeMetadata must be a boolean when present");
|
|
1906
|
+
}
|
|
1907
|
+
if (validation.length > 0) {
|
|
1908
|
+
errors.push({
|
|
1909
|
+
code: "invalid-policy",
|
|
1910
|
+
message: "agenticMemoryContextPackingBundle: policy is invalid",
|
|
1911
|
+
value,
|
|
1912
|
+
validationErrors: Object.freeze(validation)
|
|
1913
|
+
});
|
|
1914
|
+
return void 0;
|
|
1915
|
+
}
|
|
1916
|
+
return Object.freeze({
|
|
1917
|
+
...maxEntries === void 0 ? {} : { maxEntries },
|
|
1918
|
+
...maxChars === void 0 ? {} : { maxChars },
|
|
1919
|
+
...maxCost === void 0 ? {} : { maxCost },
|
|
1920
|
+
...includeMetadata === void 0 ? {} : { includeMetadata }
|
|
1921
|
+
});
|
|
1922
|
+
}
|
|
1923
|
+
function validateAndProjectRecords(value) {
|
|
1924
|
+
const records = [];
|
|
1925
|
+
const fragments = [];
|
|
1926
|
+
const metadataByFragmentId = /* @__PURE__ */ Object.create(null);
|
|
1927
|
+
const errors = [];
|
|
1928
|
+
const invalidRecordIndexes = /* @__PURE__ */ new Set();
|
|
1929
|
+
const seenRecordIds = /* @__PURE__ */ new Set();
|
|
1930
|
+
const seenFragmentIds = /* @__PURE__ */ new Set();
|
|
1931
|
+
if (!Array.isArray(value)) {
|
|
1932
|
+
errors.push({
|
|
1933
|
+
code: "invalid-records-input",
|
|
1934
|
+
message: "agenticMemoryBundle: records input must be an array",
|
|
1935
|
+
record: value
|
|
1936
|
+
});
|
|
1937
|
+
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
1938
|
+
}
|
|
1939
|
+
const length = safeArrayLength(value);
|
|
1940
|
+
if (length === void 0) {
|
|
1941
|
+
errors.push({
|
|
1942
|
+
code: "invalid-records-input",
|
|
1943
|
+
message: "agenticMemoryBundle: records input length could not be read",
|
|
1944
|
+
record: value
|
|
1945
|
+
});
|
|
1946
|
+
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
1947
|
+
}
|
|
1948
|
+
for (let i = 0; i < length; i += 1) {
|
|
1949
|
+
let raw;
|
|
1950
|
+
try {
|
|
1951
|
+
raw = value[i];
|
|
1952
|
+
} catch (error) {
|
|
1953
|
+
invalidRecordIndexes.add(i);
|
|
1954
|
+
errors.push({
|
|
1955
|
+
code: "invalid-record",
|
|
1956
|
+
message: `agenticMemoryBundle: record access failed: ${errorMessage(error)}`,
|
|
1957
|
+
index: i,
|
|
1958
|
+
validationErrors: Object.freeze(["record access failed"])
|
|
1959
|
+
});
|
|
1960
|
+
continue;
|
|
1961
|
+
}
|
|
1962
|
+
const result = validateAndSnapshotRecord(raw, i);
|
|
1963
|
+
if (result.errors.length > 0) {
|
|
1964
|
+
invalidRecordIndexes.add(i);
|
|
1965
|
+
errors.push(...result.errors);
|
|
1966
|
+
continue;
|
|
1967
|
+
}
|
|
1968
|
+
if (result.record === void 0) continue;
|
|
1969
|
+
if (seenRecordIds.has(result.record.id)) {
|
|
1970
|
+
invalidRecordIndexes.add(i);
|
|
1971
|
+
errors.push({
|
|
1972
|
+
code: "duplicate-record-id",
|
|
1973
|
+
message: "agenticMemoryBundle: duplicate record id",
|
|
1974
|
+
index: i,
|
|
1975
|
+
recordId: result.record.id,
|
|
1976
|
+
record: raw,
|
|
1977
|
+
validationErrors: [`duplicate record id '${result.record.id}'`]
|
|
1978
|
+
});
|
|
1979
|
+
continue;
|
|
1980
|
+
}
|
|
1981
|
+
if (seenFragmentIds.has(result.record.fragment.id)) {
|
|
1982
|
+
invalidRecordIndexes.add(i);
|
|
1983
|
+
errors.push({
|
|
1984
|
+
code: "duplicate-fragment-id",
|
|
1985
|
+
message: "agenticMemoryBundle: duplicate fragment id",
|
|
1986
|
+
index: i,
|
|
1987
|
+
recordId: result.record.id,
|
|
1988
|
+
fragmentId: result.record.fragment.id,
|
|
1989
|
+
record: raw,
|
|
1990
|
+
validationErrors: [`duplicate fragment id '${result.record.fragment.id}'`]
|
|
1991
|
+
});
|
|
1992
|
+
continue;
|
|
1993
|
+
}
|
|
1994
|
+
seenRecordIds.add(result.record.id);
|
|
1995
|
+
seenFragmentIds.add(result.record.fragment.id);
|
|
1996
|
+
records.push(result.record);
|
|
1997
|
+
fragments.push(result.record.fragment);
|
|
1998
|
+
metadataByFragmentId[result.record.fragment.id] = recordMetadata(result.record);
|
|
1999
|
+
}
|
|
2000
|
+
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
2001
|
+
}
|
|
2002
|
+
function validateAndSnapshotRecord(value, index) {
|
|
2003
|
+
try {
|
|
2004
|
+
return validateAndSnapshotRecordInner(value, index);
|
|
2005
|
+
} catch (error) {
|
|
2006
|
+
return {
|
|
2007
|
+
errors: [
|
|
2008
|
+
{
|
|
2009
|
+
code: "invalid-record",
|
|
2010
|
+
message: `agenticMemoryBundle: record access failed: ${errorMessage(error)}`,
|
|
2011
|
+
index,
|
|
2012
|
+
record: value,
|
|
2013
|
+
validationErrors: Object.freeze(["record access failed"])
|
|
2014
|
+
}
|
|
2015
|
+
]
|
|
2016
|
+
};
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
function validateAndSnapshotRecordInner(value, index) {
|
|
2020
|
+
const errors = [];
|
|
2021
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2022
|
+
return {
|
|
2023
|
+
errors: [
|
|
2024
|
+
{
|
|
2025
|
+
code: "invalid-record",
|
|
2026
|
+
message: "agenticMemoryBundle: record must be an object",
|
|
2027
|
+
index,
|
|
2028
|
+
record: value
|
|
2029
|
+
}
|
|
2030
|
+
]
|
|
2031
|
+
};
|
|
2032
|
+
}
|
|
2033
|
+
const record = value;
|
|
2034
|
+
const recordId = typeof record.id === "string" ? record.id : void 0;
|
|
2035
|
+
if (recordId === void 0 || recordId.length === 0) {
|
|
2036
|
+
errors.push({
|
|
2037
|
+
code: "invalid-record",
|
|
2038
|
+
message: "agenticMemoryBundle: record.id must be a non-empty string",
|
|
2039
|
+
index,
|
|
2040
|
+
record: value,
|
|
2041
|
+
validationErrors: ["record.id must be a non-empty string"]
|
|
2042
|
+
});
|
|
2043
|
+
}
|
|
2044
|
+
if (!isAgenticMemoryKind(record.kind)) {
|
|
2045
|
+
errors.push({
|
|
2046
|
+
code: "invalid-record-kind",
|
|
2047
|
+
message: "agenticMemoryBundle: record.kind is invalid",
|
|
2048
|
+
index,
|
|
2049
|
+
recordId,
|
|
2050
|
+
record: value,
|
|
2051
|
+
validationErrors: ["kind must be one of working, episodic, semantic, procedural, profile"]
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
2054
|
+
if (!isAgenticMemoryPersistenceLevel(record.persistenceLevel)) {
|
|
2055
|
+
errors.push({
|
|
2056
|
+
code: "invalid-persistence-level",
|
|
2057
|
+
message: "agenticMemoryBundle: record.persistenceLevel is invalid",
|
|
2058
|
+
index,
|
|
2059
|
+
recordId,
|
|
2060
|
+
record: value,
|
|
2061
|
+
validationErrors: [
|
|
2062
|
+
"persistenceLevel must be one of turn, session, project, longTerm, permanent, archived"
|
|
2063
|
+
]
|
|
2064
|
+
});
|
|
2065
|
+
}
|
|
2066
|
+
if (!isAgenticMemoryArtifactKind(record.artifactKind)) {
|
|
2067
|
+
errors.push({
|
|
2068
|
+
code: "invalid-artifact-kind",
|
|
2069
|
+
message: "agenticMemoryBundle: record.artifactKind is invalid",
|
|
2070
|
+
index,
|
|
2071
|
+
recordId,
|
|
2072
|
+
record: value,
|
|
2073
|
+
validationErrors: ["artifactKind must be one of raw, insight, profile, procedure"]
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
const scopeValidation = validateScope(record.scope);
|
|
2077
|
+
if (!scopeValidation.ok) {
|
|
2078
|
+
errors.push({
|
|
2079
|
+
code: "invalid-scope",
|
|
2080
|
+
message: "agenticMemoryBundle: record.scope is invalid",
|
|
2081
|
+
index,
|
|
2082
|
+
recordId,
|
|
2083
|
+
record: value,
|
|
2084
|
+
validationErrors: Object.freeze(scopeValidation.errors)
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2087
|
+
const fragmentValidation = validateMemoryFragment(record.fragment);
|
|
2088
|
+
if (!fragmentValidation.ok) {
|
|
2089
|
+
errors.push({
|
|
2090
|
+
code: "invalid-fragment",
|
|
2091
|
+
message: "agenticMemoryBundle: record.fragment is invalid",
|
|
2092
|
+
index,
|
|
2093
|
+
recordId,
|
|
2094
|
+
fragmentId: typeof record.fragment === "object" && record.fragment !== null && typeof record.fragment.id === "string" ? record.fragment.id : void 0,
|
|
2095
|
+
record: value,
|
|
2096
|
+
validationErrors: Object.freeze([...fragmentValidation.errors])
|
|
2097
|
+
});
|
|
2098
|
+
}
|
|
2099
|
+
const forbiddenFields = [
|
|
2100
|
+
"storageTier",
|
|
2101
|
+
"storageKey",
|
|
2102
|
+
"adapter",
|
|
2103
|
+
"collection",
|
|
2104
|
+
"collections",
|
|
2105
|
+
"ttl",
|
|
2106
|
+
"ttlMs",
|
|
2107
|
+
"ttlNs",
|
|
2108
|
+
"expiresAt",
|
|
2109
|
+
"timer",
|
|
2110
|
+
"scheduler",
|
|
2111
|
+
"schedule",
|
|
2112
|
+
"retentionTimer",
|
|
2113
|
+
"consolidationSchedule",
|
|
2114
|
+
"reflectionSchedule",
|
|
2115
|
+
"llm",
|
|
2116
|
+
"llmHandle",
|
|
2117
|
+
"tool",
|
|
2118
|
+
"toolHandle",
|
|
2119
|
+
"runner",
|
|
2120
|
+
"runnerHandle",
|
|
2121
|
+
"restore",
|
|
2122
|
+
"hydrate",
|
|
2123
|
+
"hydration",
|
|
2124
|
+
"graphMutation",
|
|
2125
|
+
"protocol"
|
|
2126
|
+
];
|
|
2127
|
+
const presentForbidden = forbiddenFields.filter((field) => Object.hasOwn(record, field));
|
|
2128
|
+
if (presentForbidden.length > 0) {
|
|
2129
|
+
errors.push({
|
|
2130
|
+
code: "invalid-record",
|
|
2131
|
+
message: "agenticMemoryBundle: record contains forbidden runtime/persistence fields",
|
|
2132
|
+
index,
|
|
2133
|
+
recordId,
|
|
2134
|
+
record: value,
|
|
2135
|
+
validationErrors: Object.freeze(
|
|
2136
|
+
presentForbidden.map((field) => `${field} is not part of AgenticMemoryRecord`)
|
|
2137
|
+
)
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
if (errors.length > 0) return { errors };
|
|
2141
|
+
const scope = scopeValidation.scope;
|
|
2142
|
+
const fragment = snapshotFragment(record.fragment);
|
|
2143
|
+
return {
|
|
2144
|
+
record: Object.freeze({
|
|
2145
|
+
id: recordId,
|
|
2146
|
+
kind: record.kind,
|
|
2147
|
+
persistenceLevel: record.persistenceLevel,
|
|
2148
|
+
artifactKind: record.artifactKind,
|
|
2149
|
+
...scope === void 0 ? {} : { scope },
|
|
2150
|
+
fragment
|
|
2151
|
+
}),
|
|
2152
|
+
errors
|
|
2153
|
+
};
|
|
2154
|
+
}
|
|
2155
|
+
function snapshotFragment(fragment) {
|
|
2156
|
+
return Object.freeze({
|
|
2157
|
+
id: fragment.id,
|
|
2158
|
+
payload: fragment.payload,
|
|
2159
|
+
tNs: fragment.tNs,
|
|
2160
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: fragment.validFrom },
|
|
2161
|
+
...fragment.validTo === void 0 ? {} : { validTo: fragment.validTo },
|
|
2162
|
+
confidence: fragment.confidence,
|
|
2163
|
+
tags: Object.freeze([...fragment.tags]),
|
|
2164
|
+
sources: Object.freeze([...fragment.sources]),
|
|
2165
|
+
...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
|
|
2166
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
2167
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
2168
|
+
});
|
|
2169
|
+
}
|
|
2170
|
+
function recordMetadata(record) {
|
|
2171
|
+
return Object.freeze({
|
|
2172
|
+
recordId: record.id,
|
|
2173
|
+
kind: record.kind,
|
|
2174
|
+
persistenceLevel: record.persistenceLevel,
|
|
2175
|
+
artifactKind: record.artifactKind,
|
|
2176
|
+
...record.scope === void 0 ? {} : { scope: record.scope }
|
|
2177
|
+
});
|
|
2178
|
+
}
|
|
2179
|
+
function validateRecordMetadata(value) {
|
|
2180
|
+
if (value === void 0) return { ok: true, errors: [] };
|
|
2181
|
+
if (!isPlainRecord(value)) {
|
|
2182
|
+
return { ok: false, errors: ["record metadata must be an object when present"] };
|
|
2183
|
+
}
|
|
2184
|
+
const errors = [];
|
|
2185
|
+
for (const key of Object.keys(value)) {
|
|
2186
|
+
if (key !== "recordId" && key !== "kind" && key !== "persistenceLevel" && key !== "artifactKind" && key !== "scope") {
|
|
2187
|
+
errors.push(`record.${key} is not part of AgenticMemoryRecordMetadata`);
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
if (!isNonEmptyString(value.recordId)) {
|
|
2191
|
+
errors.push("record.recordId must be a non-empty string");
|
|
2192
|
+
}
|
|
2193
|
+
if (!isAgenticMemoryKind(value.kind)) {
|
|
2194
|
+
errors.push("record.kind is invalid");
|
|
2195
|
+
}
|
|
2196
|
+
if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
|
|
2197
|
+
errors.push("record.persistenceLevel is invalid");
|
|
2198
|
+
}
|
|
2199
|
+
if (!isAgenticMemoryArtifactKind(value.artifactKind)) {
|
|
2200
|
+
errors.push("record.artifactKind is invalid");
|
|
2201
|
+
}
|
|
2202
|
+
const scopeValidation = validateScope(value.scope);
|
|
2203
|
+
if (!scopeValidation.ok) {
|
|
2204
|
+
errors.push(...scopeValidation.errors.map((error) => `record.${error}`));
|
|
2205
|
+
}
|
|
2206
|
+
if (errors.length > 0) return { ok: false, errors };
|
|
2207
|
+
return {
|
|
2208
|
+
ok: true,
|
|
2209
|
+
errors,
|
|
2210
|
+
metadata: Object.freeze({
|
|
2211
|
+
recordId: value.recordId,
|
|
2212
|
+
kind: value.kind,
|
|
2213
|
+
persistenceLevel: value.persistenceLevel,
|
|
2214
|
+
artifactKind: value.artifactKind,
|
|
2215
|
+
...scopeValidation.scope === void 0 ? {} : { scope: scopeValidation.scope }
|
|
2216
|
+
})
|
|
2217
|
+
};
|
|
2218
|
+
}
|
|
2219
|
+
function contextState(projection, retrieval) {
|
|
2220
|
+
if (projection === "error" || retrieval === "error") return "error";
|
|
2221
|
+
if (projection === "partial" || retrieval === "partial") return "partial";
|
|
2222
|
+
return retrieval;
|
|
2223
|
+
}
|
|
2224
|
+
function agenticStatusState(errorCount, validRecords) {
|
|
2225
|
+
if (errorCount > 0 && validRecords === 0) return "error";
|
|
2226
|
+
if (errorCount > 0) return "partial";
|
|
2227
|
+
return validRecords > 0 ? "ready" : "empty";
|
|
2228
|
+
}
|
|
2229
|
+
function isAgenticMemoryKind(value) {
|
|
2230
|
+
return value === "working" || value === "episodic" || value === "semantic" || value === "procedural" || value === "profile";
|
|
2231
|
+
}
|
|
2232
|
+
function isAgenticMemoryPersistenceLevel(value) {
|
|
2233
|
+
return value === "turn" || value === "session" || value === "project" || value === "longTerm" || value === "permanent" || value === "archived";
|
|
2234
|
+
}
|
|
2235
|
+
function isAgenticMemoryArtifactKind(value) {
|
|
2236
|
+
return value === "raw" || value === "insight" || value === "profile" || value === "procedure";
|
|
2237
|
+
}
|
|
2238
|
+
function validateScope(value) {
|
|
2239
|
+
if (value === void 0) return { ok: true, errors: [] };
|
|
2240
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2241
|
+
return { ok: false, errors: ["scope must be an object when present"] };
|
|
2242
|
+
}
|
|
2243
|
+
const scope = value;
|
|
2244
|
+
const errors = [];
|
|
2245
|
+
const allowed = /* @__PURE__ */ new Set(["sessionId", "projectId", "userId", "tenantId"]);
|
|
2246
|
+
for (const key of Object.keys(scope)) {
|
|
2247
|
+
if (!allowed.has(key)) errors.push(`scope.${key} is not part of AgenticMemoryScope`);
|
|
2248
|
+
}
|
|
2249
|
+
for (const key of allowed) {
|
|
2250
|
+
if (scope[key] !== void 0 && (typeof scope[key] !== "string" || scope[key].length === 0)) {
|
|
2251
|
+
errors.push(`scope.${key} must be a non-empty string when present`);
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
if (errors.length > 0) return { ok: false, errors };
|
|
2255
|
+
return {
|
|
2256
|
+
ok: true,
|
|
2257
|
+
errors,
|
|
2258
|
+
scope: Object.freeze({
|
|
2259
|
+
...scope.sessionId === void 0 ? {} : { sessionId: scope.sessionId },
|
|
2260
|
+
...scope.projectId === void 0 ? {} : { projectId: scope.projectId },
|
|
2261
|
+
...scope.userId === void 0 ? {} : { userId: scope.userId },
|
|
2262
|
+
...scope.tenantId === void 0 ? {} : { tenantId: scope.tenantId }
|
|
2263
|
+
})
|
|
2264
|
+
};
|
|
2265
|
+
}
|
|
2266
|
+
function isPlainRecord(value) {
|
|
2267
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2268
|
+
}
|
|
2269
|
+
function ownKeys(value) {
|
|
2270
|
+
return Object.keys(value).sort();
|
|
2271
|
+
}
|
|
2272
|
+
function assertExactKeys(value, expected, label) {
|
|
2273
|
+
const actual = ownKeys(value);
|
|
2274
|
+
const want = [...expected].sort();
|
|
2275
|
+
if (actual.length !== want.length || actual.some((key, i) => key !== want[i])) {
|
|
2276
|
+
throw new TypeError(`${label}: unexpected fields ${actual.join(",")}`);
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
function assertAgenticMemoryRecordCodecShape(value) {
|
|
2280
|
+
if (!isPlainRecord(value)) {
|
|
2281
|
+
throw new TypeError("agenticMemoryRecordFrame: record must be an object");
|
|
2282
|
+
}
|
|
2283
|
+
assertNoSymbolKeys(value, "agenticMemoryRecordFrame.record");
|
|
2284
|
+
assertExactKeys(
|
|
2285
|
+
value,
|
|
2286
|
+
value.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
|
|
2287
|
+
"agenticMemoryRecordFrame.record"
|
|
2288
|
+
);
|
|
2289
|
+
const fragment = value.fragment;
|
|
2290
|
+
if (!isPlainRecord(fragment)) {
|
|
2291
|
+
throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
|
|
2292
|
+
}
|
|
2293
|
+
assertNoSymbolKeys(fragment, "agenticMemoryRecordFrame.record.fragment");
|
|
2294
|
+
assertExactKeys(
|
|
2295
|
+
fragment,
|
|
2296
|
+
[
|
|
2297
|
+
"id",
|
|
2298
|
+
"payload",
|
|
2299
|
+
"tNs",
|
|
2300
|
+
...fragment.validFrom === void 0 ? [] : ["validFrom"],
|
|
2301
|
+
...fragment.validTo === void 0 ? [] : ["validTo"],
|
|
2302
|
+
"confidence",
|
|
2303
|
+
"tags",
|
|
2304
|
+
"sources",
|
|
2305
|
+
...fragment.embedding === void 0 ? [] : ["embedding"],
|
|
2306
|
+
...fragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
|
|
2307
|
+
...fragment.provenance === void 0 ? [] : ["provenance"]
|
|
2308
|
+
],
|
|
2309
|
+
"agenticMemoryRecordFrame.record.fragment"
|
|
2310
|
+
);
|
|
2311
|
+
assertStrictJsonValue(fragment.tags, "record.fragment.tags");
|
|
2312
|
+
assertStrictJsonValue(fragment.sources, "record.fragment.sources");
|
|
2313
|
+
if (fragment.embedding !== void 0) {
|
|
2314
|
+
assertStrictJsonValue(fragment.embedding, "record.fragment.embedding");
|
|
2315
|
+
}
|
|
2316
|
+
if (value.scope !== void 0) assertScopeFrame(value.scope);
|
|
2317
|
+
}
|
|
2318
|
+
function assertNoSymbolKeys(value, label) {
|
|
2319
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
2320
|
+
throw new TypeError(`${label}: unexpected symbol fields`);
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
function decimalBigIntString(value, label) {
|
|
2324
|
+
const out = value.toString(10);
|
|
2325
|
+
if (!/^-?(0|[1-9]\d*)$/.test(out)) {
|
|
2326
|
+
throw new TypeError(`${label} must encode as a canonical decimal bigint string`);
|
|
2327
|
+
}
|
|
2328
|
+
return out;
|
|
2329
|
+
}
|
|
2330
|
+
function parseDecimalBigInt(value, label) {
|
|
2331
|
+
if (typeof value !== "string" || !/^(0|-?[1-9]\d*)$/.test(value)) {
|
|
2332
|
+
throw new TypeError(`${label} must be a canonical decimal bigint string`);
|
|
2333
|
+
}
|
|
2334
|
+
return BigInt(value);
|
|
2335
|
+
}
|
|
2336
|
+
function assertStrictJsonValue(value, label) {
|
|
2337
|
+
try {
|
|
2338
|
+
strictJsonCodec.encode(value);
|
|
2339
|
+
return value;
|
|
2340
|
+
} catch (error) {
|
|
2341
|
+
throw new TypeError(`${label} must be strict JSON: ${errorMessage(error)}`);
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
function assertScopeFrame(value) {
|
|
2345
|
+
if (!isPlainRecord(value)) {
|
|
2346
|
+
throw new TypeError("agenticMemoryRecordFrame: scope must be an object when present");
|
|
2347
|
+
}
|
|
2348
|
+
assertStrictJsonValue(value, "record.scope");
|
|
2349
|
+
const validation = validateScope(value);
|
|
2350
|
+
if (!validation.ok || validation.scope === void 0) {
|
|
2351
|
+
throw new TypeError(`agenticMemoryRecordFrame: invalid scope: ${validation.errors.join("; ")}`);
|
|
2352
|
+
}
|
|
2353
|
+
assertExactKeys(
|
|
2354
|
+
value,
|
|
2355
|
+
[
|
|
2356
|
+
...value.sessionId === void 0 ? [] : ["sessionId"],
|
|
2357
|
+
...value.projectId === void 0 ? [] : ["projectId"],
|
|
2358
|
+
...value.userId === void 0 ? [] : ["userId"],
|
|
2359
|
+
...value.tenantId === void 0 ? [] : ["tenantId"]
|
|
2360
|
+
],
|
|
2361
|
+
"agenticMemoryRecordFrame.record.scope"
|
|
2362
|
+
);
|
|
2363
|
+
return validation.scope;
|
|
2364
|
+
}
|
|
2365
|
+
function assertKindValue(value) {
|
|
2366
|
+
if (!isAgenticMemoryKind(value)) {
|
|
2367
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid memory kind");
|
|
2368
|
+
}
|
|
2369
|
+
return value;
|
|
2370
|
+
}
|
|
2371
|
+
function assertPersistenceLevelValue(value) {
|
|
2372
|
+
if (!isAgenticMemoryPersistenceLevel(value)) {
|
|
2373
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid persistence level");
|
|
2374
|
+
}
|
|
2375
|
+
return value;
|
|
2376
|
+
}
|
|
2377
|
+
function assertArtifactKindValue(value) {
|
|
2378
|
+
if (!isAgenticMemoryArtifactKind(value)) {
|
|
2379
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid artifact kind");
|
|
2380
|
+
}
|
|
2381
|
+
return value;
|
|
2382
|
+
}
|
|
2383
|
+
function assertNonEmptyString(value, label) {
|
|
2384
|
+
if (!isNonEmptyString(value)) throw new TypeError(`${label} must be a non-empty string`);
|
|
2385
|
+
return value;
|
|
2386
|
+
}
|
|
2387
|
+
function assertString(value, label) {
|
|
2388
|
+
if (typeof value !== "string") throw new TypeError(`${label} must be a string`);
|
|
2389
|
+
return value;
|
|
2390
|
+
}
|
|
2391
|
+
function assertConfidence(value, label) {
|
|
2392
|
+
if (!Number.isFinite(value) || value < 0 || value > 1) {
|
|
2393
|
+
throw new TypeError(`${label} must be a finite number in [0, 1]`);
|
|
2394
|
+
}
|
|
2395
|
+
return value;
|
|
2396
|
+
}
|
|
2397
|
+
function assertStringArray(value, label) {
|
|
2398
|
+
if (!isDenseArrayOf(value, (item) => typeof item === "string")) {
|
|
2399
|
+
throw new TypeError(`${label} must be a readonly string array`);
|
|
2400
|
+
}
|
|
2401
|
+
return Object.freeze([...value]);
|
|
2402
|
+
}
|
|
2403
|
+
function assertFiniteNumberArray(value, label) {
|
|
2404
|
+
if (!isDenseArrayOf(value, (item) => Number.isFinite(item))) {
|
|
2405
|
+
throw new TypeError(`${label} must be a finite number array`);
|
|
2406
|
+
}
|
|
2407
|
+
return Object.freeze([...value]);
|
|
2408
|
+
}
|
|
2409
|
+
function isNonEmptyString(value) {
|
|
2410
|
+
return typeof value === "string" && value.length > 0;
|
|
2411
|
+
}
|
|
2412
|
+
function isDenseArrayOf(value, predicate) {
|
|
2413
|
+
if (!Array.isArray(value)) return false;
|
|
2414
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
2415
|
+
if (!Object.hasOwn(value, i) || !predicate(value[i])) return false;
|
|
2416
|
+
}
|
|
2417
|
+
return true;
|
|
2418
|
+
}
|
|
2419
|
+
function freezeError(error) {
|
|
2420
|
+
return Object.freeze({
|
|
2421
|
+
...error,
|
|
2422
|
+
...error.validationErrors === void 0 ? {} : { validationErrors: Object.freeze([...error.validationErrors]) }
|
|
2423
|
+
});
|
|
2424
|
+
}
|
|
2425
|
+
function safeArrayLength(value) {
|
|
2426
|
+
try {
|
|
2427
|
+
return value.length;
|
|
2428
|
+
} catch {
|
|
2429
|
+
return void 0;
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
function errorMessage(error) {
|
|
2433
|
+
return error instanceof Error ? error.message : String(error);
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
export {
|
|
2437
|
+
AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
|
|
2438
|
+
AGENTIC_MEMORY_RECORD_FRAME_VERSION,
|
|
2439
|
+
agenticMemoryBundle,
|
|
2440
|
+
agenticMemoryKgProjectionBundle,
|
|
2441
|
+
agenticMemoryRecordFrame,
|
|
2442
|
+
assertAgenticMemoryRecordFrame,
|
|
2443
|
+
agenticMemoryRecordFrameCodec,
|
|
2444
|
+
agenticMemoryRecordCodec,
|
|
2445
|
+
agenticMemoryRetentionBundle,
|
|
2446
|
+
agenticMemoryConsolidationBundle,
|
|
2447
|
+
agenticMemoryContextPackingBundle
|
|
2448
|
+
};
|
|
2449
|
+
//# sourceMappingURL=chunk-COHO25CZ.js.map
|