@pyxmate/memory 1.13.0 → 1.15.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/dist/agent-contract.mjs +1 -1
- package/dist/{chunk-OUSGU272.mjs → chunk-3BTAAGMM.mjs} +12 -11
- package/dist/{chunk-HOBDPIHO.mjs → chunk-3FRA37TI.mjs} +1 -1
- package/dist/chunk-A3L46P2G.mjs +57 -0
- package/dist/{chunk-5BLT7RSY.mjs → chunk-IEBF7BQF.mjs} +48 -67
- package/dist/cli/pyx-mem.mjs +38 -6
- package/dist/dashboard.mjs +3 -2
- package/dist/data-plane-contract.d.ts +234 -0
- package/dist/data-plane-contract.mjs +1150 -0
- package/dist/index.d.ts +93 -54
- package/dist/index.mjs +4 -2
- package/dist/react.mjs +3 -2
- package/package.json +5 -1
|
@@ -0,0 +1,1150 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeGraphLabel,
|
|
3
|
+
normalizeNameKey
|
|
4
|
+
} from "./chunk-A3L46P2G.mjs";
|
|
5
|
+
|
|
6
|
+
// ../shared/src/data-plane-contract.ts
|
|
7
|
+
import { createHash } from "crypto";
|
|
8
|
+
var DATA_PLANE_CONTRACT_VERSION = "pyx-data-plane-contract-v1";
|
|
9
|
+
var DATA_PLANE_CATALOG_VERSION = "maas-request-v1";
|
|
10
|
+
var DATA_PLANE_MANIFEST_VERSION = "pyx-data-plane-manifest-v1";
|
|
11
|
+
var DATA_PLANE_STEP_INPUT_FRAME = "pyx-data-plane-step-input-v1\0";
|
|
12
|
+
var DATA_PLANE_MANIFEST_FRAME = "pyx-data-plane-manifest-v1\0";
|
|
13
|
+
var DATA_PLANE_HTTP_RESPONSE_FRAME = "pyx-data-plane-http-response-v1\0";
|
|
14
|
+
var DATA_PLANE_COMPILER_LIMITS = {
|
|
15
|
+
operationIdBytes: 64,
|
|
16
|
+
identityBytes: 256,
|
|
17
|
+
semanticTextBytes: 128e3,
|
|
18
|
+
canonicalInputBytes: 1048576,
|
|
19
|
+
profileContentBytes: 8192
|
|
20
|
+
};
|
|
21
|
+
var MEMORY_TYPES = ["short-term", "long-term", "working", "episodic", "summary"];
|
|
22
|
+
var SENSITIVITY_LEVELS = ["public", "internal", "secret"];
|
|
23
|
+
var PRINCIPAL_KINDS = ["api_key", "user"];
|
|
24
|
+
var TENANT_MODES = ["single", "multi"];
|
|
25
|
+
var ENTITY_TYPES = ["PERSON", "ORGANIZATION", "CONCEPT", "TOOL", "LOCATION", "EVENT"];
|
|
26
|
+
var DATA_PLANE_OPERATION_COVERAGE = {
|
|
27
|
+
"rest:store": {
|
|
28
|
+
support: "journal_multi_step"
|
|
29
|
+
},
|
|
30
|
+
"rest:search": {
|
|
31
|
+
support: "journal_multi_step"
|
|
32
|
+
},
|
|
33
|
+
"rest:query_as_of": { support: "sqlite_atomic_one_step" },
|
|
34
|
+
"rest:query_by_event_time": { support: "sqlite_atomic_one_step" },
|
|
35
|
+
"rest:log": { support: "sqlite_atomic_one_step" },
|
|
36
|
+
"rest:lineage": {
|
|
37
|
+
support: "journal_multi_step"
|
|
38
|
+
},
|
|
39
|
+
"rest:reinforce": {
|
|
40
|
+
support: "journal_multi_step"
|
|
41
|
+
},
|
|
42
|
+
"rest:record_correction": { support: "sqlite_atomic_one_step" },
|
|
43
|
+
"rest:fetch_corrections": { support: "sqlite_atomic_one_step" },
|
|
44
|
+
"rest:synthesis_entity_refresh": {
|
|
45
|
+
support: "not_execution_ready",
|
|
46
|
+
reasonCode: "external_io_execution_not_ready",
|
|
47
|
+
reason: "entity synthesis refresh invokes an external LLM with data-dependent output and is not execution-ready in data-plane contract v1"
|
|
48
|
+
},
|
|
49
|
+
"rest:get_synthesis_entity": { support: "sqlite_atomic_one_step" },
|
|
50
|
+
"rest:list": { support: "sqlite_atomic_one_step" },
|
|
51
|
+
"rest:batch_store": {
|
|
52
|
+
support: "journal_multi_step"
|
|
53
|
+
},
|
|
54
|
+
"rest:get": { support: "sqlite_atomic_one_step" },
|
|
55
|
+
"rest:delete": {
|
|
56
|
+
support: "journal_multi_step"
|
|
57
|
+
},
|
|
58
|
+
"rest:graph_nodes": {
|
|
59
|
+
support: "journal_multi_step"
|
|
60
|
+
},
|
|
61
|
+
"rest:graph_relationships": {
|
|
62
|
+
support: "journal_multi_step"
|
|
63
|
+
},
|
|
64
|
+
"rest:graph_subgraph": {
|
|
65
|
+
support: "journal_multi_step"
|
|
66
|
+
},
|
|
67
|
+
"rest:embedding_map": {
|
|
68
|
+
support: "not_execution_ready",
|
|
69
|
+
reasonCode: "corpus_dependent_execution_not_ready",
|
|
70
|
+
reason: "embedding map reads cache state and may compute PCA over a data-dependent corpus, so it is not execution-ready in data-plane contract v1"
|
|
71
|
+
},
|
|
72
|
+
"mcp:search_memories": {
|
|
73
|
+
support: "journal_multi_step"
|
|
74
|
+
},
|
|
75
|
+
"mcp:store_memory": {
|
|
76
|
+
support: "journal_multi_step"
|
|
77
|
+
},
|
|
78
|
+
"mcp:get_memory": { support: "sqlite_atomic_one_step" },
|
|
79
|
+
"mcp:lineage": {
|
|
80
|
+
support: "journal_multi_step"
|
|
81
|
+
},
|
|
82
|
+
"mcp:reinforce": {
|
|
83
|
+
support: "journal_multi_step"
|
|
84
|
+
},
|
|
85
|
+
"mcp:list_memories": { support: "sqlite_atomic_one_step" },
|
|
86
|
+
"mcp:delete_memory": {
|
|
87
|
+
support: "journal_multi_step"
|
|
88
|
+
},
|
|
89
|
+
"mcp:ingest_memory_file": {
|
|
90
|
+
support: "not_execution_ready",
|
|
91
|
+
reasonCode: "external_io_execution_not_ready",
|
|
92
|
+
reason: "ingest_memory_file reads caller-local files and is not execution-ready in data-plane contract v1"
|
|
93
|
+
},
|
|
94
|
+
"mcp:summarize_memory_entity": { support: "sqlite_atomic_one_step" },
|
|
95
|
+
"mcp:get_taxonomy_state": {
|
|
96
|
+
support: "journal_multi_step"
|
|
97
|
+
},
|
|
98
|
+
"mcp:name_cluster": {
|
|
99
|
+
support: "journal_multi_step"
|
|
100
|
+
},
|
|
101
|
+
"mcp:status": {
|
|
102
|
+
support: "not_execution_ready",
|
|
103
|
+
reasonCode: "nonchargeable_operation",
|
|
104
|
+
reason: "status is nonchargeable and must bypass data-plane reservation"
|
|
105
|
+
},
|
|
106
|
+
"mcp:get_user_profile": { support: "sqlite_atomic_one_step" },
|
|
107
|
+
"mcp:upsert_user_profile": { support: "sqlite_atomic_one_step" },
|
|
108
|
+
"mcp:record_correction": { support: "sqlite_atomic_one_step" },
|
|
109
|
+
"mcp:fetch_applicable_corrections": { support: "sqlite_atomic_one_step" },
|
|
110
|
+
"mcp:fetch_due_facts": { support: "sqlite_atomic_one_step" }
|
|
111
|
+
};
|
|
112
|
+
function isPlainObject(value) {
|
|
113
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
114
|
+
}
|
|
115
|
+
function requireObject(value, field) {
|
|
116
|
+
if (!isPlainObject(value)) throw new Error(`${field} must be a plain object`);
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
function requireExactKeys(value, allowed, field) {
|
|
120
|
+
const allowedKeys = new Set(allowed);
|
|
121
|
+
for (const key of Object.keys(value)) {
|
|
122
|
+
requireWellFormedUnicode(key, `${field} key`);
|
|
123
|
+
if (!allowedKeys.has(key)) throw new Error(`${field} contains unknown field: ${key}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function requireWellFormedUnicode(value, field) {
|
|
127
|
+
if (!value.isWellFormed()) throw new Error(`${field} contains an unpaired UTF-16 surrogate`);
|
|
128
|
+
}
|
|
129
|
+
function requireString(value, field, options = {}) {
|
|
130
|
+
if (typeof value !== "string") throw new Error(`${field} must be a string`);
|
|
131
|
+
requireWellFormedUnicode(value, field);
|
|
132
|
+
if (options.nonempty !== false && value.length === 0)
|
|
133
|
+
throw new Error(`${field} must not be empty`);
|
|
134
|
+
const maxBytes = options.maxBytes ?? DATA_PLANE_COMPILER_LIMITS.semanticTextBytes;
|
|
135
|
+
if (Buffer.byteLength(value, "utf8") > maxBytes)
|
|
136
|
+
throw new Error(`${field} exceeds ${maxBytes} UTF-8 bytes`);
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
function optionalString(value, field) {
|
|
140
|
+
return value === void 0 ? void 0 : requireString(value, field);
|
|
141
|
+
}
|
|
142
|
+
function optionalNonemptyString(value, field) {
|
|
143
|
+
if (value === void 0) return void 0;
|
|
144
|
+
const text = requireString(value, field, { nonempty: false });
|
|
145
|
+
return text.length === 0 ? void 0 : text;
|
|
146
|
+
}
|
|
147
|
+
function requireEnum(value, values, field) {
|
|
148
|
+
if (typeof value !== "string" || !values.includes(value)) throw new Error(`${field} is invalid`);
|
|
149
|
+
return value;
|
|
150
|
+
}
|
|
151
|
+
function optionalEnum(value, values, field) {
|
|
152
|
+
return value === void 0 ? void 0 : requireEnum(value, values, field);
|
|
153
|
+
}
|
|
154
|
+
function optionalEnumOrEmpty(value, values, field) {
|
|
155
|
+
return value === "" ? void 0 : optionalEnum(value, values, field);
|
|
156
|
+
}
|
|
157
|
+
function normalizeAgentId(value, field, defaultAgentId, emptyMeansNoFilter) {
|
|
158
|
+
if (value === void 0) return defaultAgentId ?? void 0;
|
|
159
|
+
const agentId = requireString(value, field, { nonempty: false });
|
|
160
|
+
if (agentId.length > 0) return agentId;
|
|
161
|
+
return emptyMeansNoFilter ? null : defaultAgentId ?? void 0;
|
|
162
|
+
}
|
|
163
|
+
function requireInteger(value, field, minimum, maximum) {
|
|
164
|
+
if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
|
|
165
|
+
throw new Error(`${field} must be a safe integer between ${minimum} and ${maximum}`);
|
|
166
|
+
}
|
|
167
|
+
return Object.is(value, -0) ? 0 : value;
|
|
168
|
+
}
|
|
169
|
+
function optionalInteger(value, field, minimum, maximum) {
|
|
170
|
+
return value === void 0 ? void 0 : requireInteger(value, field, minimum, maximum);
|
|
171
|
+
}
|
|
172
|
+
function optionalClampedPositiveInteger(value, field, maximum) {
|
|
173
|
+
if (value === void 0) return void 0;
|
|
174
|
+
return Math.min(requireInteger(value, field, 1, Number.MAX_SAFE_INTEGER), maximum);
|
|
175
|
+
}
|
|
176
|
+
function requireFiniteNumber(value, field) {
|
|
177
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
178
|
+
throw new Error(`${field} must be a finite number`);
|
|
179
|
+
}
|
|
180
|
+
return Object.is(value, -0) ? 0 : value;
|
|
181
|
+
}
|
|
182
|
+
function normalizeRestLimit(value, field, originMaximum) {
|
|
183
|
+
const requested = value === void 0 ? 50 : requireFiniteNumber(value, field);
|
|
184
|
+
const gatewayLimit = Math.min(Math.max(requested || 50, 1), 200);
|
|
185
|
+
const originLimit = Number.parseInt(String(gatewayLimit), 10);
|
|
186
|
+
return Math.min(originMaximum, Math.max(1, originLimit));
|
|
187
|
+
}
|
|
188
|
+
function normalizeRestPagination(limitValue, offsetValue) {
|
|
189
|
+
const requestedLimit = limitValue === void 0 ? 50 : requireFiniteNumber(limitValue, "input.limit");
|
|
190
|
+
const requestedOffset = offsetValue === void 0 ? 0 : requireFiniteNumber(offsetValue, "input.offset");
|
|
191
|
+
const gatewayLimit = Math.min(requestedLimit || 50, 200);
|
|
192
|
+
const gatewayOffset = Math.max(requestedOffset || 0, 0);
|
|
193
|
+
const mappedPage = Math.floor(gatewayOffset / gatewayLimit) + 1;
|
|
194
|
+
const originPage = Number.parseInt(String(mappedPage), 10);
|
|
195
|
+
const originLimit = Number.parseInt(String(gatewayLimit), 10);
|
|
196
|
+
if (!Number.isSafeInteger(originPage) || !Number.isSafeInteger(originLimit)) {
|
|
197
|
+
throw new Error("REST pagination cannot be represented as safe origin integers");
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
page: Math.max(1, originPage),
|
|
201
|
+
limit: Math.min(100, Math.max(1, originLimit))
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function requireBoolean(value, field) {
|
|
205
|
+
if (typeof value !== "boolean") throw new Error(`${field} must be a boolean`);
|
|
206
|
+
return value;
|
|
207
|
+
}
|
|
208
|
+
function requireCanonicalIso(value, field) {
|
|
209
|
+
const text = requireString(value, field, { maxBytes: 32 });
|
|
210
|
+
const parsed = Date.parse(text);
|
|
211
|
+
if (!Number.isFinite(parsed) || new Date(parsed).toISOString() !== text) {
|
|
212
|
+
throw new Error(`${field} must be a canonical absolute ISO-8601 timestamp`);
|
|
213
|
+
}
|
|
214
|
+
return text;
|
|
215
|
+
}
|
|
216
|
+
function normalizeIso(value, field) {
|
|
217
|
+
const text = requireString(value, field, { maxBytes: 64 });
|
|
218
|
+
const parsed = Date.parse(text);
|
|
219
|
+
if (!Number.isFinite(parsed)) throw new Error(`${field} must be a valid ISO-8601 timestamp`);
|
|
220
|
+
return new Date(parsed).toISOString();
|
|
221
|
+
}
|
|
222
|
+
function withOptional(target, key, value) {
|
|
223
|
+
if (value !== void 0) target[key] = value;
|
|
224
|
+
}
|
|
225
|
+
function normalizeTemporalFilters(value, prefix, defaultAgentId) {
|
|
226
|
+
const normalized = {
|
|
227
|
+
limit: normalizeRestLimit(value.limit, `${prefix}.limit`, 100)
|
|
228
|
+
};
|
|
229
|
+
withOptional(
|
|
230
|
+
normalized,
|
|
231
|
+
"agentId",
|
|
232
|
+
normalizeAgentId(value.agentId, `${prefix}.agentId`, defaultAgentId, false)
|
|
233
|
+
);
|
|
234
|
+
withOptional(normalized, "type", optionalEnumOrEmpty(value.type, MEMORY_TYPES, `${prefix}.type`));
|
|
235
|
+
return normalized;
|
|
236
|
+
}
|
|
237
|
+
function normalizeQueryAsOf(input, defaultAgentId) {
|
|
238
|
+
const value = requireObject(input, "input");
|
|
239
|
+
requireExactKeys(value, ["asOf", "limit", "type", "agentId"], "input");
|
|
240
|
+
return {
|
|
241
|
+
asOf: normalizeIso(value.asOf, "input.asOf"),
|
|
242
|
+
...normalizeTemporalFilters(value, "input", defaultAgentId)
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function normalizeQueryByEventTime(input, defaultAgentId) {
|
|
246
|
+
const value = requireObject(input, "input");
|
|
247
|
+
requireExactKeys(value, ["startTime", "endTime", "limit", "type", "agentId"], "input");
|
|
248
|
+
const startTime = normalizeIso(value.startTime, "input.startTime");
|
|
249
|
+
const endTime = normalizeIso(value.endTime, "input.endTime");
|
|
250
|
+
if (endTime < startTime) throw new Error("input.endTime must not be before input.startTime");
|
|
251
|
+
return { startTime, endTime, ...normalizeTemporalFilters(value, "input", defaultAgentId) };
|
|
252
|
+
}
|
|
253
|
+
function normalizeLog(input, defaultAgentId) {
|
|
254
|
+
const value = requireObject(input, "input");
|
|
255
|
+
requireExactKeys(value, ["since", "limit", "type", "agentId"], "input");
|
|
256
|
+
const normalized = {
|
|
257
|
+
...normalizeTemporalFilters(value, "input", defaultAgentId)
|
|
258
|
+
};
|
|
259
|
+
withOptional(
|
|
260
|
+
normalized,
|
|
261
|
+
"since",
|
|
262
|
+
value.since === void 0 ? void 0 : normalizeIso(value.since, "input.since")
|
|
263
|
+
);
|
|
264
|
+
return normalized;
|
|
265
|
+
}
|
|
266
|
+
function normalizeCorrectionRecord(input, defaultAgentId) {
|
|
267
|
+
const value = requireObject(input, "input");
|
|
268
|
+
const keys = ["whatWasWrong", "whatToDoInstead", "appliesWhen", "project", "taskShape"];
|
|
269
|
+
requireExactKeys(value, keys, "input");
|
|
270
|
+
const normalized = {
|
|
271
|
+
whatWasWrong: requireString(value.whatWasWrong, "input.whatWasWrong"),
|
|
272
|
+
whatToDoInstead: requireString(value.whatToDoInstead, "input.whatToDoInstead"),
|
|
273
|
+
appliesWhen: requireString(value.appliesWhen, "input.appliesWhen")
|
|
274
|
+
};
|
|
275
|
+
withOptional(normalized, "agentId", defaultAgentId ?? void 0);
|
|
276
|
+
withOptional(normalized, "project", optionalNonemptyString(value.project, "input.project"));
|
|
277
|
+
withOptional(normalized, "taskShape", optionalNonemptyString(value.taskShape, "input.taskShape"));
|
|
278
|
+
return normalized;
|
|
279
|
+
}
|
|
280
|
+
function normalizeCorrectionFetch(input, rest) {
|
|
281
|
+
const value = requireObject(input, "input");
|
|
282
|
+
requireExactKeys(value, ["taskShape", "project", "limit"], "input");
|
|
283
|
+
const normalized = {
|
|
284
|
+
taskShape: requireString(value.taskShape, "input.taskShape"),
|
|
285
|
+
limit: rest ? normalizeRestLimit(value.limit, "input.limit", 5) : optionalClampedPositiveInteger(value.limit, "input.limit", 5) ?? 5
|
|
286
|
+
};
|
|
287
|
+
withOptional(normalized, "project", optionalNonemptyString(value.project, "input.project"));
|
|
288
|
+
return normalized;
|
|
289
|
+
}
|
|
290
|
+
function normalizeEntitySynthesisGet(input, mcp) {
|
|
291
|
+
const value = requireObject(input, "input");
|
|
292
|
+
requireExactKeys(value, mcp ? ["entityName", "entityType", "refresh"] : ["name"], "input");
|
|
293
|
+
const nameField = mcp ? "input.entityName" : "input.name";
|
|
294
|
+
const name = requireString(mcp ? value.entityName : value.name, nameField).trim().toLowerCase();
|
|
295
|
+
if (name.length === 0) throw new Error(`${nameField} must not be blank`);
|
|
296
|
+
if (!mcp) return { name };
|
|
297
|
+
const refresh = value.refresh === void 0 ? false : requireBoolean(value.refresh, "input.refresh");
|
|
298
|
+
if (refresh) throw new Error("mcp:summarize_memory_entity refresh=true is not execution-ready");
|
|
299
|
+
if (value.entityType !== void 0)
|
|
300
|
+
requireEnum(value.entityType, ENTITY_TYPES, "input.entityType");
|
|
301
|
+
return { name };
|
|
302
|
+
}
|
|
303
|
+
function normalizeRestList(input) {
|
|
304
|
+
const value = requireObject(input, "input");
|
|
305
|
+
requireExactKeys(value, ["limit", "offset", "type"], "input");
|
|
306
|
+
const normalized = normalizeRestPagination(
|
|
307
|
+
value.limit,
|
|
308
|
+
value.offset
|
|
309
|
+
);
|
|
310
|
+
withOptional(normalized, "type", optionalEnumOrEmpty(value.type, MEMORY_TYPES, "input.type"));
|
|
311
|
+
return normalized;
|
|
312
|
+
}
|
|
313
|
+
function normalizeGet(input) {
|
|
314
|
+
const value = requireObject(input, "input");
|
|
315
|
+
requireExactKeys(value, ["id"], "input");
|
|
316
|
+
return {
|
|
317
|
+
id: requireString(value.id, "input.id", { maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes })
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function normalizeRestGet(input) {
|
|
321
|
+
const normalized = normalizeGet(input);
|
|
322
|
+
const id = normalized.id;
|
|
323
|
+
if (typeof id !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)) {
|
|
324
|
+
throw new Error("input.id must be a valid UUID");
|
|
325
|
+
}
|
|
326
|
+
return normalized;
|
|
327
|
+
}
|
|
328
|
+
function normalizeMcpList(input, defaultAgentId) {
|
|
329
|
+
const value = requireObject(input, "input");
|
|
330
|
+
requireExactKeys(value, ["mode", "page", "limit", "type", "agentId", "since"], "input");
|
|
331
|
+
const mode = value.mode === void 0 ? "entries" : requireEnum(value.mode, ["entries", "log"], "input.mode");
|
|
332
|
+
const normalized = { mode };
|
|
333
|
+
withOptional(normalized, "type", optionalEnum(value.type, MEMORY_TYPES, "input.type"));
|
|
334
|
+
if (mode === "entries") {
|
|
335
|
+
if (value.since !== void 0) requireString(value.since, "input.since", { nonempty: false });
|
|
336
|
+
normalized.page = optionalInteger(value.page, "input.page", 1, Number.MAX_SAFE_INTEGER) ?? 1;
|
|
337
|
+
normalized.limit = optionalClampedPositiveInteger(value.limit, "input.limit", 100) ?? 20;
|
|
338
|
+
withOptional(
|
|
339
|
+
normalized,
|
|
340
|
+
"agentId",
|
|
341
|
+
normalizeAgentId(value.agentId, "input.agentId", null, false)
|
|
342
|
+
);
|
|
343
|
+
} else {
|
|
344
|
+
if (value.page !== void 0)
|
|
345
|
+
requireInteger(value.page, "input.page", 1, Number.MAX_SAFE_INTEGER);
|
|
346
|
+
withOptional(
|
|
347
|
+
normalized,
|
|
348
|
+
"agentId",
|
|
349
|
+
normalizeAgentId(value.agentId, "input.agentId", defaultAgentId, true)
|
|
350
|
+
);
|
|
351
|
+
withOptional(
|
|
352
|
+
normalized,
|
|
353
|
+
"limit",
|
|
354
|
+
optionalClampedPositiveInteger(value.limit, "input.limit", 100)
|
|
355
|
+
);
|
|
356
|
+
withOptional(
|
|
357
|
+
normalized,
|
|
358
|
+
"since",
|
|
359
|
+
value.since === void 0 ? void 0 : normalizeIso(value.since, "input.since")
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
return normalized;
|
|
363
|
+
}
|
|
364
|
+
function normalizeProfile(input, write, defaultAgentId) {
|
|
365
|
+
const value = requireObject(input, "input");
|
|
366
|
+
requireExactKeys(value, write ? ["content"] : [], "input");
|
|
367
|
+
const normalized = {};
|
|
368
|
+
if (write) {
|
|
369
|
+
normalized.content = requireString(value.content, "input.content", {
|
|
370
|
+
maxBytes: DATA_PLANE_COMPILER_LIMITS.profileContentBytes
|
|
371
|
+
});
|
|
372
|
+
withOptional(normalized, "agentId", defaultAgentId ?? void 0);
|
|
373
|
+
}
|
|
374
|
+
return normalized;
|
|
375
|
+
}
|
|
376
|
+
function normalizeDue(input) {
|
|
377
|
+
const value = requireObject(input, "input");
|
|
378
|
+
requireExactKeys(value, ["from", "to", "limit"], "input");
|
|
379
|
+
const from = requireCanonicalIso(value.from, "input.from");
|
|
380
|
+
const to = requireCanonicalIso(value.to, "input.to");
|
|
381
|
+
const duration = Date.parse(to) - Date.parse(from);
|
|
382
|
+
if (duration < 864e5 || duration > 370 * 864e5 || duration % 864e5 !== 0) {
|
|
383
|
+
throw new Error("input.to must be 1-370 fixed 24-hour periods after input.from");
|
|
384
|
+
}
|
|
385
|
+
const normalized = {
|
|
386
|
+
from,
|
|
387
|
+
to,
|
|
388
|
+
limit: optionalClampedPositiveInteger(value.limit, "input.limit", 100) ?? 20
|
|
389
|
+
};
|
|
390
|
+
return normalized;
|
|
391
|
+
}
|
|
392
|
+
function canonicalValue(value, field) {
|
|
393
|
+
try {
|
|
394
|
+
return JSON.parse(canonicalDataPlaneJson(value));
|
|
395
|
+
} catch (error) {
|
|
396
|
+
throw new Error(`${field} is not canonical JSON data`, { cause: error });
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function normalizeStoreTargets(value) {
|
|
400
|
+
const order = ["sqlite", "vector", "graph"];
|
|
401
|
+
if (value === void 0) return [...order];
|
|
402
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > 3) {
|
|
403
|
+
throw new Error("input.targets must contain 1-3 storage targets");
|
|
404
|
+
}
|
|
405
|
+
const targets = value.map((target) => requireEnum(target, order, "input.targets item"));
|
|
406
|
+
if (new Set(targets).size !== targets.length) throw new Error("input.targets must be unique");
|
|
407
|
+
return order.filter((target) => targets.includes(target));
|
|
408
|
+
}
|
|
409
|
+
function normalizeGraphEntities(value) {
|
|
410
|
+
if (value === void 0) return void 0;
|
|
411
|
+
if (!Array.isArray(value) || value.length > 256) {
|
|
412
|
+
throw new Error("input.entities must be an array of at most 256 items");
|
|
413
|
+
}
|
|
414
|
+
return value.map((item, index) => {
|
|
415
|
+
const entity = requireObject(item, `input.entities[${index}]`);
|
|
416
|
+
requireExactKeys(entity, ["name", "type", "properties"], `input.entities[${index}]`);
|
|
417
|
+
const normalized = {
|
|
418
|
+
name: requireString(entity.name, `input.entities[${index}].name`),
|
|
419
|
+
type: requireEnum(entity.type, ENTITY_TYPES, `input.entities[${index}].type`)
|
|
420
|
+
};
|
|
421
|
+
if (entity.properties !== void 0) {
|
|
422
|
+
normalized.properties = canonicalValue(
|
|
423
|
+
requireObject(entity.properties, `input.entities[${index}].properties`),
|
|
424
|
+
`input.entities[${index}].properties`
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
return normalized;
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
function normalizeGraphRelationships(value) {
|
|
431
|
+
if (value === void 0) return void 0;
|
|
432
|
+
if (!Array.isArray(value) || value.length > 512) {
|
|
433
|
+
throw new Error("input.relationships must be an array of at most 512 items");
|
|
434
|
+
}
|
|
435
|
+
return value.map((item, index) => {
|
|
436
|
+
const relationship = requireObject(item, `input.relationships[${index}]`);
|
|
437
|
+
requireExactKeys(
|
|
438
|
+
relationship,
|
|
439
|
+
["source", "target", "type", "properties"],
|
|
440
|
+
`input.relationships[${index}]`
|
|
441
|
+
);
|
|
442
|
+
const normalized = {
|
|
443
|
+
source: requireString(relationship.source, `input.relationships[${index}].source`),
|
|
444
|
+
target: requireString(relationship.target, `input.relationships[${index}].target`),
|
|
445
|
+
type: requireString(relationship.type, `input.relationships[${index}].type`)
|
|
446
|
+
};
|
|
447
|
+
if (relationship.properties !== void 0) {
|
|
448
|
+
normalized.properties = canonicalValue(
|
|
449
|
+
requireObject(relationship.properties, `input.relationships[${index}].properties`),
|
|
450
|
+
`input.relationships[${index}].properties`
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
return normalized;
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
function normalizeStore(input, context, mcp) {
|
|
457
|
+
const value = requireObject(input, "input");
|
|
458
|
+
const common = [
|
|
459
|
+
"content",
|
|
460
|
+
"type",
|
|
461
|
+
"targets",
|
|
462
|
+
"source",
|
|
463
|
+
"importance",
|
|
464
|
+
"eventTime",
|
|
465
|
+
"agentId",
|
|
466
|
+
"namespaceId",
|
|
467
|
+
"sessionId",
|
|
468
|
+
"parentId",
|
|
469
|
+
"entities",
|
|
470
|
+
"relationships",
|
|
471
|
+
"extractEntities"
|
|
472
|
+
];
|
|
473
|
+
requireExactKeys(
|
|
474
|
+
value,
|
|
475
|
+
mcp ? [...common, "topic", "project", "triples", "entitiesOnly"] : [...common, "metadata", "id"],
|
|
476
|
+
"input"
|
|
477
|
+
);
|
|
478
|
+
if (value.namespaceId !== void 0 && value.namespaceId !== context.scope.namespaceId) {
|
|
479
|
+
throw new Error("input.namespaceId does not match trusted context.scope.namespaceId");
|
|
480
|
+
}
|
|
481
|
+
if (value.extractEntities === true) {
|
|
482
|
+
throw new Error("input.extractEntities=true requires external I/O and is not execution-ready");
|
|
483
|
+
}
|
|
484
|
+
const normalized = {
|
|
485
|
+
content: requireString(value.content, "input.content"),
|
|
486
|
+
type: optionalEnum(value.type, MEMORY_TYPES, "input.type") ?? "long-term",
|
|
487
|
+
targets: normalizeStoreTargets(value.targets),
|
|
488
|
+
metadata: mcp ? {
|
|
489
|
+
source: "agent",
|
|
490
|
+
topic: requireString(value.topic, "input.topic"),
|
|
491
|
+
project: requireString(value.project, "input.project")
|
|
492
|
+
} : canonicalValue(value.metadata ?? {}, "input.metadata"),
|
|
493
|
+
createdAt: context.resolvedAt,
|
|
494
|
+
ingestTime: context.resolvedAt,
|
|
495
|
+
extractEntities: false
|
|
496
|
+
};
|
|
497
|
+
if (!mcp && value.id !== void 0) normalized.id = requireString(value.id, "input.id");
|
|
498
|
+
withOptional(normalized, "source", optionalNonemptyString(value.source, "input.source"));
|
|
499
|
+
withOptional(normalized, "agentId", optionalNonemptyString(value.agentId, "input.agentId"));
|
|
500
|
+
withOptional(normalized, "sessionId", optionalNonemptyString(value.sessionId, "input.sessionId"));
|
|
501
|
+
withOptional(normalized, "parentId", optionalNonemptyString(value.parentId, "input.parentId"));
|
|
502
|
+
withOptional(
|
|
503
|
+
normalized,
|
|
504
|
+
"eventTime",
|
|
505
|
+
value.eventTime === void 0 ? void 0 : normalizeIso(value.eventTime, "input.eventTime")
|
|
506
|
+
);
|
|
507
|
+
if (value.importance !== void 0) {
|
|
508
|
+
const importance = requireFiniteNumber(value.importance, "input.importance");
|
|
509
|
+
if (importance < 0 || importance > 10) throw new Error("input.importance must be 0-10");
|
|
510
|
+
normalized.importance = importance;
|
|
511
|
+
}
|
|
512
|
+
const entities = normalizeGraphEntities(value.entities) ?? [];
|
|
513
|
+
const relationships = normalizeGraphRelationships(value.relationships) ?? [];
|
|
514
|
+
if (mcp && value.triples !== void 0) {
|
|
515
|
+
if (!Array.isArray(value.triples) || value.triples.length > 256) {
|
|
516
|
+
throw new Error("input.triples must be an array of at most 256 items");
|
|
517
|
+
}
|
|
518
|
+
for (const [index, item] of value.triples.entries()) {
|
|
519
|
+
const triple = requireObject(item, `input.triples[${index}]`);
|
|
520
|
+
requireExactKeys(triple, ["subject", "relation", "object"], `input.triples[${index}]`);
|
|
521
|
+
const tripleEntities = normalizeGraphEntities([triple.subject, triple.object]);
|
|
522
|
+
const subject = tripleEntities?.[0];
|
|
523
|
+
const object = tripleEntities?.[1];
|
|
524
|
+
if (!subject || !object) throw new Error(`input.triples[${index}] has invalid endpoints`);
|
|
525
|
+
entities.push(subject, object);
|
|
526
|
+
relationships.push({
|
|
527
|
+
source: subject.name,
|
|
528
|
+
target: object.name,
|
|
529
|
+
type: normalizeGraphLabel(
|
|
530
|
+
requireString(triple.relation, `input.triples[${index}].relation`),
|
|
531
|
+
"RELATED_TO"
|
|
532
|
+
)
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
const uniqueEntities = /* @__PURE__ */ new Map();
|
|
537
|
+
for (const entity of entities) {
|
|
538
|
+
const key = normalizeNameKey(entity.name);
|
|
539
|
+
if (!uniqueEntities.has(key)) uniqueEntities.set(key, entity);
|
|
540
|
+
}
|
|
541
|
+
const uniqueRelationships = /* @__PURE__ */ new Map();
|
|
542
|
+
for (const relationship of relationships) {
|
|
543
|
+
const key = [
|
|
544
|
+
normalizeNameKey(relationship.source),
|
|
545
|
+
normalizeNameKey(relationship.target),
|
|
546
|
+
normalizeGraphLabel(relationship.type, "RELATED_TO")
|
|
547
|
+
].join("\0");
|
|
548
|
+
if (!uniqueRelationships.has(key)) uniqueRelationships.set(key, relationship);
|
|
549
|
+
}
|
|
550
|
+
if (uniqueEntities.size > 0) normalized.entities = [...uniqueEntities.values()];
|
|
551
|
+
if (uniqueRelationships.size > 0) {
|
|
552
|
+
normalized.relationships = [...uniqueRelationships.values()];
|
|
553
|
+
}
|
|
554
|
+
return normalized;
|
|
555
|
+
}
|
|
556
|
+
function normalizeBatchStore(input, context) {
|
|
557
|
+
const value = requireObject(input, "input");
|
|
558
|
+
requireExactKeys(value, ["entries"], "input");
|
|
559
|
+
if (!Array.isArray(value.entries) || value.entries.length < 1 || value.entries.length > 32) {
|
|
560
|
+
throw new Error("input.entries must contain 1-32 entries");
|
|
561
|
+
}
|
|
562
|
+
return {
|
|
563
|
+
entries: value.entries.map((entry, index) => {
|
|
564
|
+
const normalized = normalizeStore(entry, context, false);
|
|
565
|
+
return { ...normalized, batchIndex: index };
|
|
566
|
+
})
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
function normalizeSearch(input, mcp) {
|
|
570
|
+
const value = requireObject(input, "input");
|
|
571
|
+
const keys = [
|
|
572
|
+
"query",
|
|
573
|
+
"limit",
|
|
574
|
+
"strategy",
|
|
575
|
+
"effort",
|
|
576
|
+
"type",
|
|
577
|
+
"agentId",
|
|
578
|
+
"abstentionThreshold",
|
|
579
|
+
"eventTimeStart",
|
|
580
|
+
"eventTimeEnd",
|
|
581
|
+
"asOf",
|
|
582
|
+
"anchorTime",
|
|
583
|
+
"enumerationConcept",
|
|
584
|
+
"enableRerank"
|
|
585
|
+
];
|
|
586
|
+
requireExactKeys(value, keys, "input");
|
|
587
|
+
if (value.enumerationConcept !== void 0) {
|
|
588
|
+
throw new Error(
|
|
589
|
+
"input.enumerationConcept requires additional embeddings and is not execution-ready"
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
const normalized = {
|
|
593
|
+
query: requireString(value.query, "input.query"),
|
|
594
|
+
limit: mcp ? optionalClampedPositiveInteger(value.limit, "input.limit", 100) ?? 10 : normalizeRestLimit(value.limit, "input.limit", 100),
|
|
595
|
+
strategy: optionalEnum(value.strategy, ["naive", "graph", "hybrid"], "input.strategy") ?? "hybrid"
|
|
596
|
+
};
|
|
597
|
+
withOptional(
|
|
598
|
+
normalized,
|
|
599
|
+
"effort",
|
|
600
|
+
optionalEnum(value.effort, ["quick", "medium", "deep"], "input.effort")
|
|
601
|
+
);
|
|
602
|
+
withOptional(normalized, "type", optionalEnum(value.type, MEMORY_TYPES, "input.type"));
|
|
603
|
+
withOptional(normalized, "agentId", optionalNonemptyString(value.agentId, "input.agentId"));
|
|
604
|
+
for (const field of ["asOf", "anchorTime"]) {
|
|
605
|
+
if (value[field] !== void 0)
|
|
606
|
+
normalized[field] = normalizeIso(value[field], `input.${field}`);
|
|
607
|
+
}
|
|
608
|
+
if (value.eventTimeStart === void 0 !== (value.eventTimeEnd === void 0)) {
|
|
609
|
+
throw new Error("input.eventTimeStart and input.eventTimeEnd must be paired");
|
|
610
|
+
}
|
|
611
|
+
if (value.eventTimeStart !== void 0 && value.eventTimeEnd !== void 0) {
|
|
612
|
+
normalized.eventTimeRange = [
|
|
613
|
+
normalizeIso(value.eventTimeStart, "input.eventTimeStart"),
|
|
614
|
+
normalizeIso(value.eventTimeEnd, "input.eventTimeEnd")
|
|
615
|
+
];
|
|
616
|
+
}
|
|
617
|
+
if (value.abstentionThreshold !== void 0) {
|
|
618
|
+
const threshold = requireFiniteNumber(value.abstentionThreshold, "input.abstentionThreshold");
|
|
619
|
+
if (threshold < 0 || threshold > 1) throw new Error("input.abstentionThreshold must be 0-1");
|
|
620
|
+
normalized.abstentionThreshold = threshold;
|
|
621
|
+
}
|
|
622
|
+
if (value.enableRerank !== void 0) {
|
|
623
|
+
normalized.enableRerank = requireBoolean(value.enableRerank, "input.enableRerank");
|
|
624
|
+
}
|
|
625
|
+
return normalized;
|
|
626
|
+
}
|
|
627
|
+
function normalizeLineage(input) {
|
|
628
|
+
const value = requireObject(input, "input");
|
|
629
|
+
requireExactKeys(
|
|
630
|
+
value,
|
|
631
|
+
[
|
|
632
|
+
"subject",
|
|
633
|
+
"relation",
|
|
634
|
+
"entryId",
|
|
635
|
+
"asOf",
|
|
636
|
+
"beforeValue",
|
|
637
|
+
"eventTimeStart",
|
|
638
|
+
"eventTimeEnd",
|
|
639
|
+
"limit"
|
|
640
|
+
],
|
|
641
|
+
"input"
|
|
642
|
+
);
|
|
643
|
+
if (value.subject === void 0 && value.entryId === void 0) {
|
|
644
|
+
throw new Error("input.subject or input.entryId is required");
|
|
645
|
+
}
|
|
646
|
+
const normalized = {};
|
|
647
|
+
for (const field of ["subject", "relation", "entryId", "beforeValue"]) {
|
|
648
|
+
withOptional(normalized, field, optionalNonemptyString(value[field], `input.${field}`));
|
|
649
|
+
}
|
|
650
|
+
if (value.asOf !== void 0) normalized.asOf = normalizeIso(value.asOf, "input.asOf");
|
|
651
|
+
if (value.eventTimeStart === void 0 !== (value.eventTimeEnd === void 0)) {
|
|
652
|
+
throw new Error("input.eventTimeStart and input.eventTimeEnd must be paired");
|
|
653
|
+
}
|
|
654
|
+
if (value.eventTimeStart !== void 0 && value.eventTimeEnd !== void 0) {
|
|
655
|
+
normalized.eventTimeRange = [
|
|
656
|
+
normalizeIso(value.eventTimeStart, "input.eventTimeStart"),
|
|
657
|
+
normalizeIso(value.eventTimeEnd, "input.eventTimeEnd")
|
|
658
|
+
];
|
|
659
|
+
}
|
|
660
|
+
withOptional(
|
|
661
|
+
normalized,
|
|
662
|
+
"limit",
|
|
663
|
+
optionalClampedPositiveInteger(value.limit, "input.limit", 100)
|
|
664
|
+
);
|
|
665
|
+
return normalized;
|
|
666
|
+
}
|
|
667
|
+
function normalizeReinforce(input) {
|
|
668
|
+
const value = requireObject(input, "input");
|
|
669
|
+
requireExactKeys(value, ["entryIds", "signal", "at"], "input");
|
|
670
|
+
if (!Array.isArray(value.entryIds) || value.entryIds.length < 1 || value.entryIds.length > 100) {
|
|
671
|
+
throw new Error("input.entryIds must contain 1-100 ids");
|
|
672
|
+
}
|
|
673
|
+
const normalized = {
|
|
674
|
+
entryIds: value.entryIds.map(
|
|
675
|
+
(id, index) => requireString(id, `input.entryIds[${index}]`, {
|
|
676
|
+
maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes
|
|
677
|
+
})
|
|
678
|
+
),
|
|
679
|
+
signal: requireEnum(
|
|
680
|
+
value.signal,
|
|
681
|
+
["context_included", "cited", "explicit_positive"],
|
|
682
|
+
"input.signal"
|
|
683
|
+
)
|
|
684
|
+
};
|
|
685
|
+
if (value.at !== void 0) {
|
|
686
|
+
normalized.at = typeof value.at === "number" ? requireInteger(value.at, "input.at", 0, Number.MAX_SAFE_INTEGER) : normalizeIso(value.at, "input.at");
|
|
687
|
+
}
|
|
688
|
+
return normalized;
|
|
689
|
+
}
|
|
690
|
+
function normalizeGraphRead(input, operation) {
|
|
691
|
+
const value = requireObject(input, "input");
|
|
692
|
+
if (operation === "rest:graph_nodes") {
|
|
693
|
+
requireExactKeys(value, ["name", "type", "limit"], "input");
|
|
694
|
+
const normalized = {
|
|
695
|
+
limit: optionalClampedPositiveInteger(value.limit, "input.limit", 1e5) ?? 50
|
|
696
|
+
};
|
|
697
|
+
withOptional(normalized, "name", optionalNonemptyString(value.name, "input.name"));
|
|
698
|
+
withOptional(normalized, "type", optionalNonemptyString(value.type, "input.type"));
|
|
699
|
+
return normalized;
|
|
700
|
+
}
|
|
701
|
+
const field = operation === "rest:graph_subgraph" ? "edges" : "limit";
|
|
702
|
+
requireExactKeys(value, [field], "input");
|
|
703
|
+
return {
|
|
704
|
+
[field]: optionalClampedPositiveInteger(
|
|
705
|
+
value[field],
|
|
706
|
+
`input.${field}`,
|
|
707
|
+
operation === "rest:graph_subgraph" ? 1e4 : 5e5
|
|
708
|
+
) ?? (operation === "rest:graph_subgraph" ? 2e3 : 200)
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
function normalizeNameCluster(input) {
|
|
712
|
+
const value = requireObject(input, "input");
|
|
713
|
+
requireExactKeys(value, ["name", "memberNames", "previousName"], "input");
|
|
714
|
+
const name = requireString(value.name, "input.name").trim();
|
|
715
|
+
if (name.length < 1 || name.length > 40) {
|
|
716
|
+
throw new Error("input.name must contain 1-40 characters after trimming");
|
|
717
|
+
}
|
|
718
|
+
if (!Array.isArray(value.memberNames) || value.memberNames.length > 30) {
|
|
719
|
+
throw new Error("input.memberNames must be an array of at most 30 names");
|
|
720
|
+
}
|
|
721
|
+
const normalized = {
|
|
722
|
+
name,
|
|
723
|
+
memberNames: value.memberNames.map(
|
|
724
|
+
(memberName, index) => requireString(memberName, `input.memberNames[${index}]`)
|
|
725
|
+
)
|
|
726
|
+
};
|
|
727
|
+
withOptional(
|
|
728
|
+
normalized,
|
|
729
|
+
"previousName",
|
|
730
|
+
optionalString(value.previousName, "input.previousName")
|
|
731
|
+
);
|
|
732
|
+
return normalized;
|
|
733
|
+
}
|
|
734
|
+
function normalizeSupportedInput(operation, input, context) {
|
|
735
|
+
const defaultAgentId = context.runtimeAttestation.defaultAgentId;
|
|
736
|
+
switch (operation) {
|
|
737
|
+
case "rest:store":
|
|
738
|
+
return normalizeStore(input, context, false);
|
|
739
|
+
case "mcp:store_memory":
|
|
740
|
+
return normalizeStore(input, context, true);
|
|
741
|
+
case "rest:batch_store":
|
|
742
|
+
return normalizeBatchStore(input, context);
|
|
743
|
+
case "rest:search":
|
|
744
|
+
return normalizeSearch(input, false);
|
|
745
|
+
case "mcp:search_memories":
|
|
746
|
+
return normalizeSearch(input, true);
|
|
747
|
+
case "rest:lineage":
|
|
748
|
+
case "mcp:lineage":
|
|
749
|
+
return normalizeLineage(input);
|
|
750
|
+
case "rest:reinforce":
|
|
751
|
+
case "mcp:reinforce":
|
|
752
|
+
return normalizeReinforce(input);
|
|
753
|
+
case "rest:delete":
|
|
754
|
+
case "mcp:delete_memory":
|
|
755
|
+
return normalizeGet(input);
|
|
756
|
+
case "rest:graph_nodes":
|
|
757
|
+
case "rest:graph_relationships":
|
|
758
|
+
case "rest:graph_subgraph":
|
|
759
|
+
return normalizeGraphRead(input, operation);
|
|
760
|
+
case "mcp:get_taxonomy_state": {
|
|
761
|
+
const value = requireObject(input, "input");
|
|
762
|
+
requireExactKeys(value, [], "input");
|
|
763
|
+
return {};
|
|
764
|
+
}
|
|
765
|
+
case "mcp:name_cluster":
|
|
766
|
+
return normalizeNameCluster(input);
|
|
767
|
+
case "rest:query_as_of":
|
|
768
|
+
return normalizeQueryAsOf(input, defaultAgentId);
|
|
769
|
+
case "rest:query_by_event_time":
|
|
770
|
+
return normalizeQueryByEventTime(input, defaultAgentId);
|
|
771
|
+
case "rest:log":
|
|
772
|
+
return normalizeLog(input, defaultAgentId);
|
|
773
|
+
case "rest:record_correction":
|
|
774
|
+
return normalizeCorrectionRecord(input, defaultAgentId);
|
|
775
|
+
case "rest:fetch_corrections":
|
|
776
|
+
return normalizeCorrectionFetch(input, true);
|
|
777
|
+
case "rest:get_synthesis_entity":
|
|
778
|
+
return normalizeEntitySynthesisGet(input, false);
|
|
779
|
+
case "rest:list":
|
|
780
|
+
return normalizeRestList(input);
|
|
781
|
+
case "rest:get":
|
|
782
|
+
return normalizeRestGet(input);
|
|
783
|
+
case "mcp:get_memory":
|
|
784
|
+
return normalizeGet(input);
|
|
785
|
+
case "mcp:list_memories":
|
|
786
|
+
return normalizeMcpList(input, defaultAgentId);
|
|
787
|
+
case "mcp:get_user_profile":
|
|
788
|
+
return normalizeProfile(input, false, defaultAgentId);
|
|
789
|
+
case "mcp:upsert_user_profile":
|
|
790
|
+
return normalizeProfile(input, true, defaultAgentId);
|
|
791
|
+
case "mcp:record_correction":
|
|
792
|
+
return normalizeCorrectionRecord(input, defaultAgentId);
|
|
793
|
+
case "mcp:fetch_applicable_corrections":
|
|
794
|
+
return normalizeCorrectionFetch(input, false);
|
|
795
|
+
case "mcp:fetch_due_facts":
|
|
796
|
+
return normalizeDue(input);
|
|
797
|
+
case "mcp:summarize_memory_entity":
|
|
798
|
+
return normalizeEntitySynthesisGet(input, true);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
function requireExecutionScope(operation, context) {
|
|
802
|
+
const sharedFallbackSafe = /* @__PURE__ */ new Set([
|
|
803
|
+
"rest:query_as_of",
|
|
804
|
+
"rest:query_by_event_time",
|
|
805
|
+
"rest:log",
|
|
806
|
+
"rest:get"
|
|
807
|
+
]);
|
|
808
|
+
if (context.runtimeAttestation.sharedFallback && !sharedFallbackSafe.has(operation)) {
|
|
809
|
+
throw new Error(`${operation} is not execution-ready on the shared fallback runtime`);
|
|
810
|
+
}
|
|
811
|
+
const namespaceRequiredInMulti = /* @__PURE__ */ new Set([
|
|
812
|
+
"rest:record_correction",
|
|
813
|
+
"rest:fetch_corrections",
|
|
814
|
+
"mcp:record_correction",
|
|
815
|
+
"mcp:fetch_applicable_corrections",
|
|
816
|
+
"mcp:fetch_due_facts"
|
|
817
|
+
]);
|
|
818
|
+
if (context.runtimeAttestation.tenantMode === "multi" && namespaceRequiredInMulti.has(operation) && context.scope.namespaceId === void 0) {
|
|
819
|
+
throw new Error(`${operation} requires trusted context.scope.namespaceId in multi-tenant mode`);
|
|
820
|
+
}
|
|
821
|
+
if (operation === "mcp:get_user_profile" || operation === "mcp:upsert_user_profile") {
|
|
822
|
+
if (context.scope.namespaceId === void 0) {
|
|
823
|
+
throw new Error(`${operation} requires trusted context.scope.namespaceId`);
|
|
824
|
+
}
|
|
825
|
+
if (context.scope.userId === void 0) {
|
|
826
|
+
throw new Error(`${operation} requires trusted context.scope.userId`);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
function stripAndVerifyRawScope(input, context) {
|
|
831
|
+
if (!isPlainObject(input)) return input;
|
|
832
|
+
const value = { ...input };
|
|
833
|
+
const bindings = {
|
|
834
|
+
tenantId: context.scope.tenantId,
|
|
835
|
+
namespaceId: context.scope.namespaceId,
|
|
836
|
+
userId: context.scope.userId,
|
|
837
|
+
teamId: context.scope.teamId,
|
|
838
|
+
callerAccessLevel: context.scope.callerAccessLevel
|
|
839
|
+
};
|
|
840
|
+
for (const [field, trusted] of Object.entries(bindings)) {
|
|
841
|
+
if (value[field] !== void 0 && value[field] !== trusted) {
|
|
842
|
+
throw new Error(`input.${field} does not match trusted context.scope.${field}`);
|
|
843
|
+
}
|
|
844
|
+
delete value[field];
|
|
845
|
+
}
|
|
846
|
+
return value;
|
|
847
|
+
}
|
|
848
|
+
function normalizeContext(input) {
|
|
849
|
+
const value = requireObject(input, "context");
|
|
850
|
+
requireExactKeys(
|
|
851
|
+
value,
|
|
852
|
+
[
|
|
853
|
+
"organizationId",
|
|
854
|
+
"projectId",
|
|
855
|
+
"instanceId",
|
|
856
|
+
"operationId",
|
|
857
|
+
"principal",
|
|
858
|
+
"scope",
|
|
859
|
+
"resolvedAt",
|
|
860
|
+
"runtimeAttestation"
|
|
861
|
+
],
|
|
862
|
+
"context"
|
|
863
|
+
);
|
|
864
|
+
const principal = requireObject(value.principal, "context.principal");
|
|
865
|
+
requireExactKeys(principal, ["kind", "id"], "context.principal");
|
|
866
|
+
const scope = requireObject(value.scope, "context.scope");
|
|
867
|
+
requireExactKeys(
|
|
868
|
+
scope,
|
|
869
|
+
["tenantId", "namespaceId", "userId", "teamId", "callerAccessLevel"],
|
|
870
|
+
"context.scope"
|
|
871
|
+
);
|
|
872
|
+
const runtime = requireObject(value.runtimeAttestation, "context.runtimeAttestation");
|
|
873
|
+
requireExactKeys(
|
|
874
|
+
runtime,
|
|
875
|
+
[
|
|
876
|
+
"contractVersion",
|
|
877
|
+
"tenantMode",
|
|
878
|
+
"defaultAgentId",
|
|
879
|
+
"effectiveSource",
|
|
880
|
+
"sharedFallback",
|
|
881
|
+
"sqliteAtomicOneStep"
|
|
882
|
+
],
|
|
883
|
+
"context.runtimeAttestation"
|
|
884
|
+
);
|
|
885
|
+
if (runtime.contractVersion !== DATA_PLANE_CONTRACT_VERSION)
|
|
886
|
+
throw new Error("context.runtimeAttestation.contractVersion is invalid");
|
|
887
|
+
if (runtime.sqliteAtomicOneStep !== true)
|
|
888
|
+
throw new Error("context.runtimeAttestation.sqliteAtomicOneStep must be true");
|
|
889
|
+
const normalizedScope = {
|
|
890
|
+
tenantId: requireString(scope.tenantId, "context.scope.tenantId", {
|
|
891
|
+
maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes
|
|
892
|
+
})
|
|
893
|
+
};
|
|
894
|
+
const namespaceId = optionalString(scope.namespaceId, "context.scope.namespaceId");
|
|
895
|
+
const userId = optionalString(scope.userId, "context.scope.userId");
|
|
896
|
+
const teamId = optionalString(scope.teamId, "context.scope.teamId");
|
|
897
|
+
const callerAccessLevel = optionalEnum(
|
|
898
|
+
scope.callerAccessLevel,
|
|
899
|
+
SENSITIVITY_LEVELS,
|
|
900
|
+
"context.scope.callerAccessLevel"
|
|
901
|
+
);
|
|
902
|
+
if (namespaceId !== void 0) normalizedScope.namespaceId = namespaceId;
|
|
903
|
+
if (userId !== void 0) normalizedScope.userId = userId;
|
|
904
|
+
if (teamId !== void 0) normalizedScope.teamId = teamId;
|
|
905
|
+
if (callerAccessLevel !== void 0) normalizedScope.callerAccessLevel = callerAccessLevel;
|
|
906
|
+
const organizationId = requireString(value.organizationId, "context.organizationId", {
|
|
907
|
+
maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes
|
|
908
|
+
});
|
|
909
|
+
const projectId = requireString(value.projectId, "context.projectId", {
|
|
910
|
+
maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes
|
|
911
|
+
});
|
|
912
|
+
const effectiveSource = requireString(
|
|
913
|
+
runtime.effectiveSource,
|
|
914
|
+
"context.runtimeAttestation.effectiveSource"
|
|
915
|
+
);
|
|
916
|
+
if (effectiveSource !== `tenant:${organizationId}:${projectId}`) {
|
|
917
|
+
throw new Error(
|
|
918
|
+
"context.runtimeAttestation.effectiveSource must match the trusted organization/project source"
|
|
919
|
+
);
|
|
920
|
+
}
|
|
921
|
+
return {
|
|
922
|
+
organizationId,
|
|
923
|
+
projectId,
|
|
924
|
+
instanceId: requireString(value.instanceId, "context.instanceId", {
|
|
925
|
+
maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes
|
|
926
|
+
}),
|
|
927
|
+
operationId: requireString(value.operationId, "context.operationId", {
|
|
928
|
+
maxBytes: DATA_PLANE_COMPILER_LIMITS.operationIdBytes
|
|
929
|
+
}),
|
|
930
|
+
principal: {
|
|
931
|
+
kind: requireEnum(principal.kind, PRINCIPAL_KINDS, "context.principal.kind"),
|
|
932
|
+
id: requireString(principal.id, "context.principal.id", {
|
|
933
|
+
maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes
|
|
934
|
+
})
|
|
935
|
+
},
|
|
936
|
+
scope: normalizedScope,
|
|
937
|
+
resolvedAt: requireCanonicalIso(value.resolvedAt, "context.resolvedAt"),
|
|
938
|
+
runtimeAttestation: {
|
|
939
|
+
contractVersion: DATA_PLANE_CONTRACT_VERSION,
|
|
940
|
+
tenantMode: requireEnum(
|
|
941
|
+
runtime.tenantMode,
|
|
942
|
+
TENANT_MODES,
|
|
943
|
+
"context.runtimeAttestation.tenantMode"
|
|
944
|
+
),
|
|
945
|
+
defaultAgentId: runtime.defaultAgentId === null ? null : requireString(runtime.defaultAgentId, "context.runtimeAttestation.defaultAgentId", {
|
|
946
|
+
maxBytes: DATA_PLANE_COMPILER_LIMITS.identityBytes
|
|
947
|
+
}),
|
|
948
|
+
effectiveSource,
|
|
949
|
+
sharedFallback: requireBoolean(
|
|
950
|
+
runtime.sharedFallback,
|
|
951
|
+
"context.runtimeAttestation.sharedFallback"
|
|
952
|
+
),
|
|
953
|
+
sqliteAtomicOneStep: true
|
|
954
|
+
}
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
function normalizeCanonicalValue(value, path) {
|
|
958
|
+
if (value === null || typeof value === "boolean") return value;
|
|
959
|
+
if (typeof value === "string") {
|
|
960
|
+
requireWellFormedUnicode(value, path);
|
|
961
|
+
return value;
|
|
962
|
+
}
|
|
963
|
+
if (typeof value === "bigint") return value.toString(10);
|
|
964
|
+
if (typeof value === "number") {
|
|
965
|
+
if (!Number.isSafeInteger(value)) throw new Error(`${path} must be a safe integer`);
|
|
966
|
+
return Object.is(value, -0) ? 0 : value;
|
|
967
|
+
}
|
|
968
|
+
if (Array.isArray(value)) {
|
|
969
|
+
return Array.from({ length: value.length }, (_, index) => {
|
|
970
|
+
if (!Object.hasOwn(value, index))
|
|
971
|
+
throw new Error(`${path}[${index}] must not be a sparse hole`);
|
|
972
|
+
return normalizeCanonicalValue(value[index], `${path}[${index}]`);
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
const record = requireObject(value, path);
|
|
976
|
+
const normalized = /* @__PURE__ */ Object.create(null);
|
|
977
|
+
for (const key of Object.keys(record).sort()) {
|
|
978
|
+
requireWellFormedUnicode(key, `${path} key`);
|
|
979
|
+
if (record[key] === void 0) throw new Error(`${path}.${key} must not be undefined`);
|
|
980
|
+
normalized[key] = normalizeCanonicalValue(record[key], `${path}.${key}`);
|
|
981
|
+
}
|
|
982
|
+
return normalized;
|
|
983
|
+
}
|
|
984
|
+
function canonicalDataPlaneJson(value) {
|
|
985
|
+
return JSON.stringify(normalizeCanonicalValue(value, "$"));
|
|
986
|
+
}
|
|
987
|
+
function framedSha256(frame, canonicalJson, maxBytes) {
|
|
988
|
+
const payload = Buffer.from(canonicalJson, "utf8");
|
|
989
|
+
if (payload.byteLength > maxBytes)
|
|
990
|
+
throw new Error(`canonical payload exceeds ${maxBytes} UTF-8 bytes`);
|
|
991
|
+
if (payload.byteLength > 4294967295)
|
|
992
|
+
throw new Error("canonical payload exceeds U32 framing capacity");
|
|
993
|
+
const length = Buffer.allocUnsafe(4);
|
|
994
|
+
length.writeUInt32BE(payload.byteLength, 0);
|
|
995
|
+
return createHash("sha256").update(frame, "utf8").update(length).update(payload).digest("hex");
|
|
996
|
+
}
|
|
997
|
+
function hashDataPlaneStepInputV1(value) {
|
|
998
|
+
const canonicalJson = canonicalDataPlaneJson(value);
|
|
999
|
+
return {
|
|
1000
|
+
canonicalJson,
|
|
1001
|
+
sha256: framedSha256(
|
|
1002
|
+
DATA_PLANE_STEP_INPUT_FRAME,
|
|
1003
|
+
canonicalJson,
|
|
1004
|
+
DATA_PLANE_COMPILER_LIMITS.canonicalInputBytes
|
|
1005
|
+
)
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
function hashDataPlaneManifestV1(value) {
|
|
1009
|
+
const canonicalJson = canonicalDataPlaneJson(value);
|
|
1010
|
+
return { canonicalJson, sha256: framedSha256(DATA_PLANE_MANIFEST_FRAME, canonicalJson, 32768) };
|
|
1011
|
+
}
|
|
1012
|
+
function hashDataPlaneHttpResponseV1(statusCode, contentType, body) {
|
|
1013
|
+
if (!Number.isSafeInteger(statusCode) || statusCode < 100 || statusCode > 599) {
|
|
1014
|
+
throw new Error("statusCode must be an integer from 100 through 599");
|
|
1015
|
+
}
|
|
1016
|
+
if (typeof contentType !== "string" || contentType.length === 0 || Buffer.byteLength(contentType, "utf8") > 256 || !/^[\x20-\x7e]+$/.test(contentType) || /[\r\n]/.test(contentType)) {
|
|
1017
|
+
throw new Error("contentType must be 1-256 visible ASCII bytes without CR or LF");
|
|
1018
|
+
}
|
|
1019
|
+
if (!(body instanceof Uint8Array)) throw new Error("body must be a Uint8Array");
|
|
1020
|
+
const status = Buffer.from(String(statusCode), "ascii");
|
|
1021
|
+
const contentTypeBytes = Buffer.from(contentType, "ascii");
|
|
1022
|
+
const statusLength = Buffer.allocUnsafe(4);
|
|
1023
|
+
statusLength.writeUInt32BE(status.byteLength);
|
|
1024
|
+
const contentTypeLength = Buffer.allocUnsafe(4);
|
|
1025
|
+
contentTypeLength.writeUInt32BE(contentTypeBytes.byteLength);
|
|
1026
|
+
const bodyLength = Buffer.allocUnsafe(8);
|
|
1027
|
+
bodyLength.writeBigUInt64BE(BigInt(body.byteLength));
|
|
1028
|
+
return createHash("sha256").update(DATA_PLANE_HTTP_RESPONSE_FRAME, "utf8").update(statusLength).update(status).update(contentTypeLength).update(contentTypeBytes).update(bodyLength).update(body).digest("hex");
|
|
1029
|
+
}
|
|
1030
|
+
function compileDataPlaneRequest(request) {
|
|
1031
|
+
const outer = requireObject(request, "request");
|
|
1032
|
+
requireExactKeys(outer, ["catalogVersion", "operation", "context", "input"], "request");
|
|
1033
|
+
if (outer.catalogVersion !== DATA_PLANE_CATALOG_VERSION)
|
|
1034
|
+
throw new Error(`unknown data-plane catalog version: ${String(outer.catalogVersion)}`);
|
|
1035
|
+
if (typeof outer.operation !== "string" || !Object.hasOwn(DATA_PLANE_OPERATION_COVERAGE, outer.operation)) {
|
|
1036
|
+
throw new Error(`unknown data-plane catalog operation: ${String(outer.operation)}`);
|
|
1037
|
+
}
|
|
1038
|
+
const operation = outer.operation;
|
|
1039
|
+
const entry = DATA_PLANE_OPERATION_COVERAGE[operation];
|
|
1040
|
+
if (entry.support === "not_execution_ready") {
|
|
1041
|
+
return {
|
|
1042
|
+
kind: "unsupported",
|
|
1043
|
+
catalogVersion: DATA_PLANE_CATALOG_VERSION,
|
|
1044
|
+
operation,
|
|
1045
|
+
reasonCode: entry.reasonCode,
|
|
1046
|
+
reason: entry.reason
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
const supportedOperation = operation;
|
|
1050
|
+
const context = normalizeContext(outer.context);
|
|
1051
|
+
requireExecutionScope(supportedOperation, context);
|
|
1052
|
+
const normalizedInput = normalizeSupportedInput(
|
|
1053
|
+
supportedOperation,
|
|
1054
|
+
stripAndVerifyRawScope(outer.input, context),
|
|
1055
|
+
context
|
|
1056
|
+
);
|
|
1057
|
+
const stepInput = {
|
|
1058
|
+
contractVersion: DATA_PLANE_CONTRACT_VERSION,
|
|
1059
|
+
catalogVersion: DATA_PLANE_CATALOG_VERSION,
|
|
1060
|
+
operation: supportedOperation,
|
|
1061
|
+
context,
|
|
1062
|
+
input: normalizedInput
|
|
1063
|
+
};
|
|
1064
|
+
const step = hashDataPlaneStepInputV1(stepInput);
|
|
1065
|
+
const storeEntries = supportedOperation === "rest:batch_store" ? normalizedInput.entries : supportedOperation === "rest:store" || supportedOperation === "mcp:store_memory" ? [normalizedInput] : [];
|
|
1066
|
+
const storeHasTarget = (target) => storeEntries.some(
|
|
1067
|
+
(entry2) => entry2.targets.includes(target)
|
|
1068
|
+
);
|
|
1069
|
+
const multiStepKinds = (() => {
|
|
1070
|
+
switch (supportedOperation) {
|
|
1071
|
+
case "rest:store":
|
|
1072
|
+
case "mcp:store_memory":
|
|
1073
|
+
case "rest:batch_store": {
|
|
1074
|
+
const kinds = [];
|
|
1075
|
+
if (storeHasTarget("vector")) kinds.push("embedding", "vector");
|
|
1076
|
+
if (storeHasTarget("graph")) kinds.push("graph");
|
|
1077
|
+
kinds.push("sqlite");
|
|
1078
|
+
return kinds;
|
|
1079
|
+
}
|
|
1080
|
+
case "rest:search":
|
|
1081
|
+
case "mcp:search_memories":
|
|
1082
|
+
return ["embedding", "sqlite"];
|
|
1083
|
+
case "rest:delete":
|
|
1084
|
+
case "mcp:delete_memory":
|
|
1085
|
+
return ["vector", "graph", "sqlite"];
|
|
1086
|
+
case "rest:lineage":
|
|
1087
|
+
case "mcp:lineage":
|
|
1088
|
+
case "rest:graph_nodes":
|
|
1089
|
+
case "rest:graph_relationships":
|
|
1090
|
+
case "rest:graph_subgraph":
|
|
1091
|
+
case "mcp:get_taxonomy_state":
|
|
1092
|
+
case "mcp:name_cluster":
|
|
1093
|
+
return ["graph", "sqlite"];
|
|
1094
|
+
case "rest:reinforce":
|
|
1095
|
+
case "mcp:reinforce":
|
|
1096
|
+
return ["vector", "sqlite"];
|
|
1097
|
+
default:
|
|
1098
|
+
return ["sqlite"];
|
|
1099
|
+
}
|
|
1100
|
+
})();
|
|
1101
|
+
const executionPlan = {
|
|
1102
|
+
mode: "journal",
|
|
1103
|
+
version: DATA_PLANE_MANIFEST_VERSION,
|
|
1104
|
+
steps: multiStepKinds.map((kind, sequence) => ({
|
|
1105
|
+
sequence,
|
|
1106
|
+
stepKey: multiStepKinds.length === 1 ? supportedOperation : `${supportedOperation}:${kind}`,
|
|
1107
|
+
kind,
|
|
1108
|
+
execution: kind === "sqlite" ? "sqlite_atomic" : "idempotent_adapter",
|
|
1109
|
+
inputSha256: multiStepKinds.length === 1 ? step.sha256 : hashDataPlaneStepInputV1({ ...stepInput, step: { kind, sequence } }).sha256
|
|
1110
|
+
}))
|
|
1111
|
+
};
|
|
1112
|
+
const manifest = hashDataPlaneManifestV1(executionPlan);
|
|
1113
|
+
const embeddingUnicodeScalars = supportedOperation === "rest:store" || supportedOperation === "mcp:store_memory" ? storeHasTarget("vector") ? Array.from(normalizedInput.content).length : 0 : supportedOperation === "rest:batch_store" ? storeEntries.reduce(
|
|
1114
|
+
(total, entry2) => total + (entry2.targets.includes("vector") ? Array.from(entry2.content).length : 0),
|
|
1115
|
+
0
|
|
1116
|
+
) : supportedOperation === "rest:search" || supportedOperation === "mcp:search_memories" ? Array.from(normalizedInput.query).length : 0;
|
|
1117
|
+
return {
|
|
1118
|
+
kind: "compiled",
|
|
1119
|
+
contractVersion: DATA_PLANE_CONTRACT_VERSION,
|
|
1120
|
+
catalogVersion: DATA_PLANE_CATALOG_VERSION,
|
|
1121
|
+
operation: supportedOperation,
|
|
1122
|
+
context,
|
|
1123
|
+
normalizedInput,
|
|
1124
|
+
stepInputCanonicalJson: step.canonicalJson,
|
|
1125
|
+
stepInputSha256: step.sha256,
|
|
1126
|
+
executionPlan,
|
|
1127
|
+
manifestCanonicalJson: manifest.canonicalJson,
|
|
1128
|
+
manifestSha256: manifest.sha256,
|
|
1129
|
+
quoteDimensions: {
|
|
1130
|
+
databaseOperations: supportedOperation === "rest:batch_store" ? normalizedInput.entries.length : 1,
|
|
1131
|
+
embeddingUnicodeScalars,
|
|
1132
|
+
embeddingEvents: embeddingUnicodeScalars > 0 ? 1 : 0
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
export {
|
|
1137
|
+
DATA_PLANE_CATALOG_VERSION,
|
|
1138
|
+
DATA_PLANE_COMPILER_LIMITS,
|
|
1139
|
+
DATA_PLANE_CONTRACT_VERSION,
|
|
1140
|
+
DATA_PLANE_HTTP_RESPONSE_FRAME,
|
|
1141
|
+
DATA_PLANE_MANIFEST_FRAME,
|
|
1142
|
+
DATA_PLANE_MANIFEST_VERSION,
|
|
1143
|
+
DATA_PLANE_OPERATION_COVERAGE,
|
|
1144
|
+
DATA_PLANE_STEP_INPUT_FRAME,
|
|
1145
|
+
canonicalDataPlaneJson,
|
|
1146
|
+
compileDataPlaneRequest,
|
|
1147
|
+
hashDataPlaneHttpResponseV1,
|
|
1148
|
+
hashDataPlaneManifestV1,
|
|
1149
|
+
hashDataPlaneStepInputV1
|
|
1150
|
+
};
|