@opengeni/contracts 0.9.0 → 0.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/index.d.ts +6929 -1520
- package/dist/index.js +3332 -196
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
- package/src/event-preview.ts +911 -0
- package/src/index.ts +3953 -318
package/dist/index.js
CHANGED
|
@@ -1,10 +1,664 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
// src/event-preview.ts
|
|
5
|
+
var SESSION_EVENT_PAYLOAD_MAX_BYTES = 64 * 1024;
|
|
6
|
+
var TARGET_PAYLOAD_BYTES = 60 * 1024;
|
|
7
|
+
var DEFAULT_STRING_BYTES = 8 * 1024;
|
|
8
|
+
var RETRY_STRING_BYTES = 1024;
|
|
9
|
+
var DEFAULT_ARRAY_ENTRIES = 40;
|
|
10
|
+
var RETRY_ARRAY_ENTRIES = 12;
|
|
11
|
+
var DEFAULT_OBJECT_FIELDS = 80;
|
|
12
|
+
var RETRY_OBJECT_FIELDS = 32;
|
|
13
|
+
var MAX_PREVIEW_DEPTH = 12;
|
|
14
|
+
var MAX_PREVIEW_NODES = 512;
|
|
15
|
+
var MAX_MEASUREMENT_NODES = 2048;
|
|
16
|
+
var MAX_MEASUREMENT_DEPTH = 64;
|
|
17
|
+
var MAX_DETAIL_RECORDS = 24;
|
|
18
|
+
var APPROX_BYTES_PER_TOKEN = 4;
|
|
19
|
+
var encoder = new TextEncoder();
|
|
20
|
+
var IDENTITY_FIELDS = /* @__PURE__ */ new Set([
|
|
21
|
+
"id",
|
|
22
|
+
"callId",
|
|
23
|
+
"call_id",
|
|
24
|
+
"name",
|
|
25
|
+
"toolName",
|
|
26
|
+
"type",
|
|
27
|
+
"status",
|
|
28
|
+
"code",
|
|
29
|
+
"isError",
|
|
30
|
+
"stream",
|
|
31
|
+
"commandId",
|
|
32
|
+
"sequence"
|
|
33
|
+
]);
|
|
34
|
+
function sessionEventJsonBytes(value) {
|
|
35
|
+
return encoder.encode(stringifyForBoundary(value)).byteLength;
|
|
36
|
+
}
|
|
37
|
+
function measureSessionEventJson(value) {
|
|
38
|
+
return measureJsonBytes(value);
|
|
39
|
+
}
|
|
40
|
+
function approximateSessionEventTokens(bytes) {
|
|
41
|
+
return Math.ceil(Math.max(0, bytes) / APPROX_BYTES_PER_TOKEN);
|
|
42
|
+
}
|
|
43
|
+
function sessionEventMediaPreview(mediaType, inlineBytes) {
|
|
44
|
+
return {
|
|
45
|
+
type: "media_preview",
|
|
46
|
+
mediaType: mediaType || "application/octet-stream",
|
|
47
|
+
inlineBytes: inlineBytes === null ? null : Math.max(0, Math.floor(Number.isFinite(inlineBytes) ? inlineBytes : 0)),
|
|
48
|
+
fullOutputAvailable: false,
|
|
49
|
+
preview: "Inline media omitted from the audit timeline; source bytes were not retained."
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function sessionEventMediaPreviewFromDataUrl(value) {
|
|
53
|
+
const match = /^data:([^;,]+)(?:;[^,]*)?;base64,/i.exec(value);
|
|
54
|
+
if (!match) return null;
|
|
55
|
+
const encodedLength = Math.max(0, value.length - match[0].length);
|
|
56
|
+
const padding = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
|
|
57
|
+
return sessionEventMediaPreview(
|
|
58
|
+
match[1] ?? "application/octet-stream",
|
|
59
|
+
Math.max(0, Math.floor(encodedLength * 3 / 4) - padding)
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
function sessionEventPayloadTruncation(payload) {
|
|
63
|
+
if (!isPlainRecord(payload)) return null;
|
|
64
|
+
const value = payload.truncation;
|
|
65
|
+
if (!isPlainRecord(value) || value.truncated !== true) return null;
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
function boundSessionEventPayload(payload, options = {}) {
|
|
69
|
+
const maxBytes = Math.max(1024, Math.floor(options.maxBytes ?? SESSION_EVENT_PAYLOAD_MAX_BYTES));
|
|
70
|
+
const surface = options.surface ?? "durable_audit";
|
|
71
|
+
const originalMeasurement = measureJsonBytes(payload);
|
|
72
|
+
const originalBytes = originalMeasurement.bytes;
|
|
73
|
+
let state = previewState(DEFAULT_STRING_BYTES, DEFAULT_ARRAY_ENTRIES, DEFAULT_OBJECT_FIELDS);
|
|
74
|
+
let preview = previewValue(payload, state, "$", 0);
|
|
75
|
+
if (!state.changed && originalBytes !== null && originalBytes <= maxBytes) {
|
|
76
|
+
return payload;
|
|
77
|
+
}
|
|
78
|
+
let reason = payloadTruncationReason(originalMeasurement, state);
|
|
79
|
+
let bounded = attachTruncation(preview, boundaryMetadata(surface, reason, originalBytes, state));
|
|
80
|
+
if (sessionEventJsonBytes(bounded) > Math.min(maxBytes, TARGET_PAYLOAD_BYTES)) {
|
|
81
|
+
state = previewState(RETRY_STRING_BYTES, RETRY_ARRAY_ENTRIES, RETRY_OBJECT_FIELDS);
|
|
82
|
+
preview = previewValue(payload, state, "$", 0);
|
|
83
|
+
reason = payloadTruncationReason(originalMeasurement, state);
|
|
84
|
+
bounded = attachTruncation(preview, boundaryMetadata(surface, reason, originalBytes, state));
|
|
85
|
+
}
|
|
86
|
+
if (sessionEventJsonBytes(bounded) > maxBytes) {
|
|
87
|
+
const identity = identityPreview(payload);
|
|
88
|
+
state.changed = true;
|
|
89
|
+
recordDetail(state, {
|
|
90
|
+
path: "$",
|
|
91
|
+
kind: "object",
|
|
92
|
+
...originalBytes === null ? {} : { originalBytes }
|
|
93
|
+
});
|
|
94
|
+
bounded = attachTruncation(
|
|
95
|
+
{
|
|
96
|
+
...identity,
|
|
97
|
+
preview: "[event payload omitted: bounded audit preview exceeded the storage envelope]"
|
|
98
|
+
},
|
|
99
|
+
boundaryMetadata(surface, reason, originalBytes, state)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
settleDeliveredSizes(bounded, maxBytes);
|
|
103
|
+
return bounded;
|
|
104
|
+
}
|
|
105
|
+
function previewState(stringBytes, arrayEntries, objectFields) {
|
|
106
|
+
return {
|
|
107
|
+
changed: false,
|
|
108
|
+
sawMedia: false,
|
|
109
|
+
details: [],
|
|
110
|
+
stringBytes,
|
|
111
|
+
arrayEntries,
|
|
112
|
+
objectFields,
|
|
113
|
+
remainingNodes: MAX_PREVIEW_NODES
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function payloadTruncationReason(measurement, state) {
|
|
117
|
+
if (state.sawMedia) return "inline_media_not_retained";
|
|
118
|
+
return measurement.bytes === null ? measurement.reason : "payload_bytes_exceeded";
|
|
119
|
+
}
|
|
120
|
+
function previewValue(value, state, path, depth) {
|
|
121
|
+
if (state.remainingNodes <= 0) {
|
|
122
|
+
state.changed = true;
|
|
123
|
+
recordDetail(state, { path, kind: "budget" });
|
|
124
|
+
return "[nested value omitted at audit preview traversal boundary]";
|
|
125
|
+
}
|
|
126
|
+
state.remainingNodes -= 1;
|
|
127
|
+
if (typeof value === "string") {
|
|
128
|
+
const media = inlineMediaFact(value);
|
|
129
|
+
if (media) {
|
|
130
|
+
state.changed = true;
|
|
131
|
+
state.sawMedia = true;
|
|
132
|
+
recordDetail(state, {
|
|
133
|
+
path,
|
|
134
|
+
kind: "media",
|
|
135
|
+
originalBytes: utf8Bytes(value),
|
|
136
|
+
deliveredBytes: sessionEventJsonBytes(media),
|
|
137
|
+
mediaType: media.mediaType
|
|
138
|
+
});
|
|
139
|
+
return media;
|
|
140
|
+
}
|
|
141
|
+
const originalBytes = utf8Bytes(value);
|
|
142
|
+
if (originalBytes <= state.stringBytes) return value;
|
|
143
|
+
state.changed = true;
|
|
144
|
+
const delivered = truncateUtf8Middle(value, state.stringBytes, originalBytes);
|
|
145
|
+
recordDetail(state, {
|
|
146
|
+
path,
|
|
147
|
+
kind: "string",
|
|
148
|
+
originalBytes,
|
|
149
|
+
deliveredBytes: utf8Bytes(delivered)
|
|
150
|
+
});
|
|
151
|
+
return delivered;
|
|
152
|
+
}
|
|
153
|
+
if (typeof value === "bigint" || typeof value === "function" || typeof value === "symbol") {
|
|
154
|
+
state.changed = true;
|
|
155
|
+
recordDetail(state, { path, kind: "unserializable" });
|
|
156
|
+
return `[${typeof value} value omitted at audit serialization boundary]`;
|
|
157
|
+
}
|
|
158
|
+
if (value === null || typeof value !== "object") return value;
|
|
159
|
+
const binary = binaryFact(value);
|
|
160
|
+
if (binary) {
|
|
161
|
+
state.changed = true;
|
|
162
|
+
recordDetail(state, {
|
|
163
|
+
path,
|
|
164
|
+
kind: "binary",
|
|
165
|
+
originalBytes: binary.originalBytes,
|
|
166
|
+
deliveredBytes: sessionEventJsonBytes(binary.preview)
|
|
167
|
+
});
|
|
168
|
+
return binary.preview;
|
|
169
|
+
}
|
|
170
|
+
if (depth >= MAX_PREVIEW_DEPTH) {
|
|
171
|
+
state.changed = true;
|
|
172
|
+
recordDetail(state, { path, kind: "depth" });
|
|
173
|
+
return "[nested value omitted at audit preview depth boundary]";
|
|
174
|
+
}
|
|
175
|
+
if (Array.isArray(value)) {
|
|
176
|
+
const keep = Math.max(2, state.arrayEntries);
|
|
177
|
+
if (value.length <= keep) {
|
|
178
|
+
return Array.from(
|
|
179
|
+
{ length: value.length },
|
|
180
|
+
(_, index) => previewArrayEntry(value, index, state, path, depth)
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
state.changed = true;
|
|
184
|
+
const head = Math.ceil(keep / 2);
|
|
185
|
+
const tail = Math.floor(keep / 2);
|
|
186
|
+
const omitted2 = value.length - head - tail;
|
|
187
|
+
recordDetail(state, { path, kind: "array", omittedEntries: omitted2 });
|
|
188
|
+
return [
|
|
189
|
+
...Array.from(
|
|
190
|
+
{ length: head },
|
|
191
|
+
(_, index) => previewArrayEntry(value, index, state, path, depth)
|
|
192
|
+
),
|
|
193
|
+
{ omittedEntries: omitted2, preview: "[middle array entries omitted]" },
|
|
194
|
+
...Array.from(
|
|
195
|
+
{ length: tail },
|
|
196
|
+
(_, index) => previewArrayEntry(value, value.length - tail + index, state, path, depth)
|
|
197
|
+
)
|
|
198
|
+
];
|
|
199
|
+
}
|
|
200
|
+
if (value instanceof Date) {
|
|
201
|
+
if (!hasCanonicalDateSerialization(value)) {
|
|
202
|
+
state.changed = true;
|
|
203
|
+
recordDetail(state, { path, kind: "unserializable" });
|
|
204
|
+
return "[Date value with custom serialization omitted at audit boundary]";
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
const epoch = Date.prototype.getTime.call(value);
|
|
208
|
+
return Number.isFinite(epoch) ? Date.prototype.toISOString.call(value) : null;
|
|
209
|
+
} catch {
|
|
210
|
+
state.changed = true;
|
|
211
|
+
recordDetail(state, { path, kind: "unserializable" });
|
|
212
|
+
return "[Date value omitted at audit serialization boundary]";
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const record = value;
|
|
216
|
+
const { entries, omitted, accessorKeys } = selectObjectEntries(record, state.objectFields);
|
|
217
|
+
for (const key of accessorKeys) {
|
|
218
|
+
state.changed = true;
|
|
219
|
+
recordDetail(state, {
|
|
220
|
+
path: `${path}.${key}`,
|
|
221
|
+
kind: "unserializable"
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
if (omitted) {
|
|
225
|
+
state.changed = true;
|
|
226
|
+
recordDetail(state, {
|
|
227
|
+
path,
|
|
228
|
+
kind: "object",
|
|
229
|
+
// Counting every remaining field would defeat the traversal bound. `null`
|
|
230
|
+
// is deliberate: at least one field was omitted, but its exact count is
|
|
231
|
+
// unknown because the source was not fully enumerated.
|
|
232
|
+
omittedEntries: null
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
const out = {};
|
|
236
|
+
for (const [key, entry] of entries) {
|
|
237
|
+
out[key] = previewValue(entry, state, `${path}.${key}`, depth + 1);
|
|
238
|
+
}
|
|
239
|
+
if (omitted) {
|
|
240
|
+
out.omittedFields = "additional fields omitted; exact count not measured";
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
function previewArrayEntry(value, index, state, path, depth) {
|
|
245
|
+
let descriptor;
|
|
246
|
+
try {
|
|
247
|
+
descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
248
|
+
} catch {
|
|
249
|
+
state.changed = true;
|
|
250
|
+
recordDetail(state, { path: `${path}[${index}]`, kind: "unserializable" });
|
|
251
|
+
return "[array element omitted at audit serialization boundary]";
|
|
252
|
+
}
|
|
253
|
+
if (descriptor && !("value" in descriptor)) {
|
|
254
|
+
state.changed = true;
|
|
255
|
+
recordDetail(state, { path: `${path}[${index}]`, kind: "unserializable" });
|
|
256
|
+
return "[array accessor value omitted at audit serialization boundary]";
|
|
257
|
+
}
|
|
258
|
+
return previewValue(
|
|
259
|
+
descriptor && "value" in descriptor ? descriptor.value : void 0,
|
|
260
|
+
state,
|
|
261
|
+
`${path}[${index}]`,
|
|
262
|
+
depth + 1
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
function selectObjectEntries(record, maxFields) {
|
|
266
|
+
const entries = [];
|
|
267
|
+
const selected = /* @__PURE__ */ new Set();
|
|
268
|
+
const accessorKeys = [];
|
|
269
|
+
const select = (key) => {
|
|
270
|
+
const descriptor = Object.getOwnPropertyDescriptor(record, key);
|
|
271
|
+
if (!descriptor?.enumerable) return false;
|
|
272
|
+
selected.add(key);
|
|
273
|
+
if ("value" in descriptor) {
|
|
274
|
+
entries.push([key, descriptor.value]);
|
|
275
|
+
} else {
|
|
276
|
+
entries.push([key, "[accessor value omitted at audit serialization boundary]"]);
|
|
277
|
+
accessorKeys.push(key);
|
|
278
|
+
}
|
|
279
|
+
return true;
|
|
280
|
+
};
|
|
281
|
+
try {
|
|
282
|
+
for (const key of IDENTITY_FIELDS) {
|
|
283
|
+
if (entries.length >= maxFields) break;
|
|
284
|
+
select(key);
|
|
285
|
+
}
|
|
286
|
+
for (const key in record) {
|
|
287
|
+
if (!Object.prototype.hasOwnProperty.call(record, key) || selected.has(key)) continue;
|
|
288
|
+
if (entries.length >= maxFields) {
|
|
289
|
+
return { entries, omitted: true, accessorKeys };
|
|
290
|
+
}
|
|
291
|
+
select(key);
|
|
292
|
+
}
|
|
293
|
+
} catch {
|
|
294
|
+
return { entries, omitted: true, accessorKeys };
|
|
295
|
+
}
|
|
296
|
+
return { entries, omitted: false, accessorKeys };
|
|
297
|
+
}
|
|
298
|
+
function attachTruncation(preview, truncation) {
|
|
299
|
+
if (isPlainRecord(preview)) {
|
|
300
|
+
return { ...preview, truncation };
|
|
301
|
+
}
|
|
302
|
+
return { value: preview, truncation };
|
|
303
|
+
}
|
|
304
|
+
function boundaryMetadata(surface, reason, originalBytes, state) {
|
|
305
|
+
return {
|
|
306
|
+
truncated: true,
|
|
307
|
+
surface,
|
|
308
|
+
reason,
|
|
309
|
+
originalBytes,
|
|
310
|
+
deliveredBytes: 0,
|
|
311
|
+
omittedBytes: originalBytes,
|
|
312
|
+
estimatedOriginalTokens: originalBytes === null ? null : approximateSessionEventTokens(originalBytes),
|
|
313
|
+
estimatedDeliveredTokens: 0,
|
|
314
|
+
fullEvidence: { available: false, reason: "not_retained" },
|
|
315
|
+
details: state.details
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function settleDeliveredSizes(payload, maxBytes) {
|
|
319
|
+
const truncation = payload.truncation;
|
|
320
|
+
convergeDeliveredSizes(payload, truncation);
|
|
321
|
+
if (sessionEventJsonBytes(payload) > maxBytes) {
|
|
322
|
+
payload.preview = "[event payload omitted at audit byte boundary]";
|
|
323
|
+
for (const key of Object.keys(payload)) {
|
|
324
|
+
if (key !== "preview" && key !== "truncation" && IDENTITY_FIELDS.has(key) === false) {
|
|
325
|
+
delete payload[key];
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
truncation.details = truncation.details.slice(0, 4);
|
|
329
|
+
convergeDeliveredSizes(payload, truncation);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function convergeDeliveredSizes(payload, truncation) {
|
|
333
|
+
for (let attempt = 0; attempt < 16; attempt += 1) {
|
|
334
|
+
const deliveredBytes = sessionEventJsonBytes(payload);
|
|
335
|
+
const omittedBytes = truncation.originalBytes === null ? null : Math.max(0, truncation.originalBytes - deliveredBytes);
|
|
336
|
+
const estimatedDeliveredTokens = approximateSessionEventTokens(deliveredBytes);
|
|
337
|
+
if (truncation.deliveredBytes === deliveredBytes && truncation.omittedBytes === omittedBytes && truncation.estimatedDeliveredTokens === estimatedDeliveredTokens) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
truncation.deliveredBytes = deliveredBytes;
|
|
341
|
+
truncation.omittedBytes = omittedBytes;
|
|
342
|
+
truncation.estimatedDeliveredTokens = estimatedDeliveredTokens;
|
|
343
|
+
}
|
|
344
|
+
throw new RangeError("Session event byte accounting did not converge");
|
|
345
|
+
}
|
|
346
|
+
function recordDetail(state, detail) {
|
|
347
|
+
if (state.details.length < MAX_DETAIL_RECORDS) state.details.push(detail);
|
|
348
|
+
}
|
|
349
|
+
function identityPreview(value) {
|
|
350
|
+
if (!isPlainRecord(value)) return {};
|
|
351
|
+
const out = {};
|
|
352
|
+
for (const key of IDENTITY_FIELDS) {
|
|
353
|
+
let field;
|
|
354
|
+
try {
|
|
355
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
356
|
+
if (!descriptor?.enumerable || !("value" in descriptor)) continue;
|
|
357
|
+
field = descriptor.value;
|
|
358
|
+
} catch {
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (typeof field === "string") {
|
|
362
|
+
out[key] = truncateUtf8Middle(field, 256, utf8Bytes(field));
|
|
363
|
+
} else if (typeof field === "number" || typeof field === "boolean" || field === null) {
|
|
364
|
+
out[key] = field;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return out;
|
|
368
|
+
}
|
|
369
|
+
function inlineMediaFact(value) {
|
|
370
|
+
return sessionEventMediaPreviewFromDataUrl(value);
|
|
371
|
+
}
|
|
372
|
+
function binaryFact(value) {
|
|
373
|
+
if (ArrayBuffer.isView(value)) {
|
|
374
|
+
return {
|
|
375
|
+
originalBytes: value.byteLength,
|
|
376
|
+
preview: {
|
|
377
|
+
type: "binary_preview",
|
|
378
|
+
byteLength: value.byteLength,
|
|
379
|
+
fullOutputAvailable: false,
|
|
380
|
+
preview: "Inline binary value omitted from the audit timeline; bytes were not retained."
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
if (value instanceof ArrayBuffer) {
|
|
385
|
+
return {
|
|
386
|
+
originalBytes: value.byteLength,
|
|
387
|
+
preview: {
|
|
388
|
+
type: "binary_preview",
|
|
389
|
+
byteLength: value.byteLength,
|
|
390
|
+
fullOutputAvailable: false,
|
|
391
|
+
preview: "Inline binary value omitted from the audit timeline; bytes were not retained."
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
function truncateUtf8Middle(value, maxBytes, knownBytes = utf8Bytes(value)) {
|
|
398
|
+
if (knownBytes <= maxBytes) return value;
|
|
399
|
+
let omittedBytes = Math.max(0, knownBytes - maxBytes);
|
|
400
|
+
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
401
|
+
const marker2 = `\u2026[${omittedBytes} bytes omitted]\u2026`;
|
|
402
|
+
const contentBudget2 = Math.max(0, maxBytes - utf8Bytes(marker2));
|
|
403
|
+
if (contentBudget2 === 0) return marker2;
|
|
404
|
+
const left2 = utf8Prefix(value, Math.floor(contentBudget2 / 2));
|
|
405
|
+
const right2 = utf8Suffix(value, contentBudget2 - left2.bytes);
|
|
406
|
+
const exactOmittedBytes = Math.max(0, knownBytes - left2.bytes - right2.bytes);
|
|
407
|
+
if (exactOmittedBytes === omittedBytes) {
|
|
408
|
+
return `${value.slice(0, left2.end)}${marker2}${value.slice(right2.start)}`;
|
|
409
|
+
}
|
|
410
|
+
omittedBytes = exactOmittedBytes;
|
|
411
|
+
}
|
|
412
|
+
const marker = `\u2026[${omittedBytes} bytes omitted]\u2026`;
|
|
413
|
+
const contentBudget = Math.max(0, maxBytes - utf8Bytes(marker));
|
|
414
|
+
const left = utf8Prefix(value, Math.floor(contentBudget / 2));
|
|
415
|
+
const right = utf8Suffix(value, contentBudget - left.bytes);
|
|
416
|
+
return `${value.slice(0, left.end)}${marker}${value.slice(right.start)}`;
|
|
417
|
+
}
|
|
418
|
+
function utf8Prefix(value, maxBytes) {
|
|
419
|
+
let end = 0;
|
|
420
|
+
let bytes = 0;
|
|
421
|
+
while (end < value.length) {
|
|
422
|
+
const unit = utf8UnitAt(value, end);
|
|
423
|
+
if (bytes + unit.bytes > maxBytes) break;
|
|
424
|
+
bytes += unit.bytes;
|
|
425
|
+
end += unit.codeUnits;
|
|
426
|
+
}
|
|
427
|
+
return { end, bytes };
|
|
428
|
+
}
|
|
429
|
+
function utf8Suffix(value, maxBytes) {
|
|
430
|
+
let start = value.length;
|
|
431
|
+
let bytes = 0;
|
|
432
|
+
while (start > 0) {
|
|
433
|
+
const unit = utf8UnitBefore(value, start);
|
|
434
|
+
if (bytes + unit.bytes > maxBytes) break;
|
|
435
|
+
bytes += unit.bytes;
|
|
436
|
+
start -= unit.codeUnits;
|
|
437
|
+
}
|
|
438
|
+
return { start, bytes };
|
|
439
|
+
}
|
|
440
|
+
function utf8UnitAt(value, index) {
|
|
441
|
+
const code = value.charCodeAt(index);
|
|
442
|
+
if (code <= 127) return { codeUnits: 1, bytes: 1 };
|
|
443
|
+
if (code <= 2047) return { codeUnits: 1, bytes: 2 };
|
|
444
|
+
if (code >= 55296 && code <= 56319) {
|
|
445
|
+
const next = index + 1 < value.length ? value.charCodeAt(index + 1) : 0;
|
|
446
|
+
if (next >= 56320 && next <= 57343) {
|
|
447
|
+
return { codeUnits: 2, bytes: 4 };
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return { codeUnits: 1, bytes: 3 };
|
|
451
|
+
}
|
|
452
|
+
function utf8UnitBefore(value, end) {
|
|
453
|
+
const code = value.charCodeAt(end - 1);
|
|
454
|
+
if (code >= 56320 && code <= 57343 && end >= 2) {
|
|
455
|
+
const previous = value.charCodeAt(end - 2);
|
|
456
|
+
if (previous >= 55296 && previous <= 56319) {
|
|
457
|
+
return { codeUnits: 2, bytes: 4 };
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (code <= 127) return { codeUnits: 1, bytes: 1 };
|
|
461
|
+
if (code <= 2047) return { codeUnits: 1, bytes: 2 };
|
|
462
|
+
return { codeUnits: 1, bytes: 3 };
|
|
463
|
+
}
|
|
464
|
+
function utf8Bytes(value) {
|
|
465
|
+
let bytes = 0;
|
|
466
|
+
for (let index = 0; index < value.length; ) {
|
|
467
|
+
const unit = utf8UnitAt(value, index);
|
|
468
|
+
bytes += unit.bytes;
|
|
469
|
+
index += unit.codeUnits;
|
|
470
|
+
}
|
|
471
|
+
return bytes;
|
|
472
|
+
}
|
|
473
|
+
function measureJsonBytes(value) {
|
|
474
|
+
const state = {
|
|
475
|
+
remainingNodes: MAX_MEASUREMENT_NODES,
|
|
476
|
+
seen: /* @__PURE__ */ new WeakSet(),
|
|
477
|
+
failureReason: null
|
|
478
|
+
};
|
|
479
|
+
try {
|
|
480
|
+
const bytes = measureJsonValue(value, state, "top", 0);
|
|
481
|
+
return bytes === null ? {
|
|
482
|
+
bytes: null,
|
|
483
|
+
reason: state.failureReason ?? "payload_measurement_bounded"
|
|
484
|
+
} : { bytes, reason: null };
|
|
485
|
+
} catch {
|
|
486
|
+
return { bytes: null, reason: "payload_measurement_bounded" };
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
function measureJsonValue(value, state, position, depth) {
|
|
490
|
+
if (state.remainingNodes <= 0 || depth > MAX_MEASUREMENT_DEPTH) {
|
|
491
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
492
|
+
}
|
|
493
|
+
state.remainingNodes -= 1;
|
|
494
|
+
if (value === null) return 4;
|
|
495
|
+
if (typeof value === "string") return jsonStringBytes(value);
|
|
496
|
+
if (typeof value === "boolean") return value ? 4 : 5;
|
|
497
|
+
if (typeof value === "number") {
|
|
498
|
+
const serialized = JSON.stringify(value);
|
|
499
|
+
return serialized === void 0 ? null : serialized.length;
|
|
500
|
+
}
|
|
501
|
+
if (typeof value === "undefined" || typeof value === "function" || typeof value === "symbol") {
|
|
502
|
+
return position === "array" ? 4 : failJsonMeasurement(state, "payload_not_serializable");
|
|
503
|
+
}
|
|
504
|
+
if (typeof value === "bigint") {
|
|
505
|
+
return failJsonMeasurement(state, "payload_not_serializable");
|
|
506
|
+
}
|
|
507
|
+
if (typeof value !== "object") {
|
|
508
|
+
return failJsonMeasurement(state, "payload_not_serializable");
|
|
509
|
+
}
|
|
510
|
+
if (value instanceof Date) {
|
|
511
|
+
if (!hasCanonicalDateSerialization(value)) {
|
|
512
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
513
|
+
}
|
|
514
|
+
try {
|
|
515
|
+
const epoch = Date.prototype.getTime.call(value);
|
|
516
|
+
return Number.isFinite(epoch) ? jsonStringBytes(Date.prototype.toISOString.call(value)) : 4;
|
|
517
|
+
} catch {
|
|
518
|
+
return failJsonMeasurement(state, "payload_not_serializable");
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
|
|
522
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
523
|
+
}
|
|
524
|
+
if (state.seen.has(value)) {
|
|
525
|
+
return failJsonMeasurement(state, "payload_not_serializable");
|
|
526
|
+
}
|
|
527
|
+
state.seen.add(value);
|
|
528
|
+
try {
|
|
529
|
+
if (Array.isArray(value)) {
|
|
530
|
+
if (Object.getPrototypeOf(value) !== Array.prototype) {
|
|
531
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
532
|
+
}
|
|
533
|
+
const toJson2 = Object.getOwnPropertyDescriptor(value, "toJSON");
|
|
534
|
+
if (toJson2 && ("get" in toJson2 || typeof toJson2.value === "function")) {
|
|
535
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
536
|
+
}
|
|
537
|
+
if (value.length > state.remainingNodes) {
|
|
538
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
539
|
+
}
|
|
540
|
+
let bytes2 = 2;
|
|
541
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
542
|
+
if (index > 0) bytes2 += 1;
|
|
543
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
544
|
+
if (descriptor && !("value" in descriptor)) {
|
|
545
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
546
|
+
}
|
|
547
|
+
const entry = descriptor && "value" in descriptor ? descriptor.value : void 0;
|
|
548
|
+
const measured = measureJsonValue(entry, state, "array", depth + 1);
|
|
549
|
+
if (measured === null) return null;
|
|
550
|
+
bytes2 += measured;
|
|
551
|
+
}
|
|
552
|
+
return bytes2;
|
|
553
|
+
}
|
|
554
|
+
const prototype = Object.getPrototypeOf(value);
|
|
555
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
556
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
557
|
+
}
|
|
558
|
+
const toJson = Object.getOwnPropertyDescriptor(value, "toJSON");
|
|
559
|
+
if (toJson && ("get" in toJson || typeof toJson.value === "function")) {
|
|
560
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
561
|
+
}
|
|
562
|
+
let bytes = 2;
|
|
563
|
+
let fields = 0;
|
|
564
|
+
try {
|
|
565
|
+
for (const key in value) {
|
|
566
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
567
|
+
if (state.remainingNodes <= 0) {
|
|
568
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
569
|
+
}
|
|
570
|
+
state.remainingNodes -= 1;
|
|
571
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
572
|
+
if (!descriptor || !("value" in descriptor)) {
|
|
573
|
+
return failJsonMeasurement(state, "payload_measurement_bounded");
|
|
574
|
+
}
|
|
575
|
+
const entry = descriptor.value;
|
|
576
|
+
if (typeof entry === "undefined" || typeof entry === "function" || typeof entry === "symbol") {
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
const measured = measureJsonValue(entry, state, "object", depth + 1);
|
|
580
|
+
if (measured === null) return null;
|
|
581
|
+
if (fields > 0) bytes += 1;
|
|
582
|
+
bytes += jsonStringBytes(key) + 1 + measured;
|
|
583
|
+
fields += 1;
|
|
584
|
+
}
|
|
585
|
+
} catch {
|
|
586
|
+
return null;
|
|
587
|
+
}
|
|
588
|
+
return bytes;
|
|
589
|
+
} finally {
|
|
590
|
+
state.seen.delete(value);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
function hasCanonicalDateSerialization(value) {
|
|
594
|
+
try {
|
|
595
|
+
if (Object.getPrototypeOf(value) !== Date.prototype) return false;
|
|
596
|
+
return Object.getOwnPropertyDescriptor(value, "toJSON") === void 0;
|
|
597
|
+
} catch {
|
|
598
|
+
return false;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
function failJsonMeasurement(state, reason) {
|
|
602
|
+
state.failureReason ??= reason;
|
|
603
|
+
return null;
|
|
604
|
+
}
|
|
605
|
+
function jsonStringBytes(value) {
|
|
606
|
+
let bytes = 2;
|
|
607
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
608
|
+
const code = value.charCodeAt(index);
|
|
609
|
+
if (code === 34 || code === 92 || code === 8 || code === 9 || code === 10 || code === 12 || code === 13) {
|
|
610
|
+
bytes += 2;
|
|
611
|
+
} else if (code <= 31) {
|
|
612
|
+
bytes += 6;
|
|
613
|
+
} else if (code <= 127) {
|
|
614
|
+
bytes += 1;
|
|
615
|
+
} else if (code <= 2047) {
|
|
616
|
+
bytes += 2;
|
|
617
|
+
} else if (code >= 55296 && code <= 56319) {
|
|
618
|
+
const next = index + 1 < value.length ? value.charCodeAt(index + 1) : 0;
|
|
619
|
+
if (next >= 56320 && next <= 57343) {
|
|
620
|
+
bytes += 4;
|
|
621
|
+
index += 1;
|
|
622
|
+
} else {
|
|
623
|
+
bytes += 6;
|
|
624
|
+
}
|
|
625
|
+
} else if (code >= 56320 && code <= 57343) {
|
|
626
|
+
bytes += 6;
|
|
627
|
+
} else {
|
|
628
|
+
bytes += 3;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
return bytes;
|
|
632
|
+
}
|
|
633
|
+
function serializeForBoundary(value) {
|
|
634
|
+
try {
|
|
635
|
+
const serialized = JSON.stringify(value);
|
|
636
|
+
return {
|
|
637
|
+
value: serialized === void 0 ? "null" : serialized,
|
|
638
|
+
serializable: serialized !== void 0
|
|
639
|
+
};
|
|
640
|
+
} catch {
|
|
641
|
+
return {
|
|
642
|
+
value: JSON.stringify("[unserializable event payload omitted]"),
|
|
643
|
+
serializable: false
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
function stringifyForBoundary(value) {
|
|
648
|
+
return serializeForBoundary(value).value;
|
|
649
|
+
}
|
|
650
|
+
function isPlainRecord(value) {
|
|
651
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// src/index.ts
|
|
3
655
|
var SessionStatus = z.enum([
|
|
4
656
|
"queued",
|
|
5
657
|
"running",
|
|
6
658
|
"idle",
|
|
7
659
|
"requires_action",
|
|
660
|
+
"recovering",
|
|
661
|
+
"waiting_capacity",
|
|
8
662
|
"failed",
|
|
9
663
|
"cancelled"
|
|
10
664
|
]);
|
|
@@ -383,7 +1037,7 @@ var Permission = z.enum([
|
|
|
383
1037
|
"sessions:create",
|
|
384
1038
|
"sessions:read",
|
|
385
1039
|
"sessions:control",
|
|
386
|
-
//
|
|
1040
|
+
// sandbox workspace (sandbox contract §C.3 / crosscut PART 1.2). stream:view is a
|
|
387
1041
|
// REAL, distinct permission — strictly BROADER than sessions:read — because the
|
|
388
1042
|
// pixel plane (Channel B) is UN-REDACTED: a viewer of raw pixels can see cloud
|
|
389
1043
|
// creds the agent cat's into a terminal, which the redacted Channel-A event log
|
|
@@ -414,8 +1068,12 @@ var Permission = z.enum([
|
|
|
414
1068
|
"api_keys:manage",
|
|
415
1069
|
"connections:read",
|
|
416
1070
|
"connections:write",
|
|
1071
|
+
/** @deprecated alias of variable-sets:manage */
|
|
417
1072
|
"environments:manage",
|
|
1073
|
+
/** @deprecated alias of variable-sets:use */
|
|
418
1074
|
"environments:use",
|
|
1075
|
+
"variable-sets:manage",
|
|
1076
|
+
"variable-sets:use",
|
|
419
1077
|
// Attach or rotate per-session third-party MCP server credentials. Deliberately
|
|
420
1078
|
// not part of the worker's default first-party MCP permission set: a sandboxed
|
|
421
1079
|
// agent must not be able to hand itself new bearer credentials.
|
|
@@ -431,7 +1089,14 @@ var Permission = z.enum([
|
|
|
431
1089
|
// enrollment grants WHOLE-MACHINE access to a user's own hardware — a high-trust,
|
|
432
1090
|
// admin-shaped action. workspace:admin is the super-wildcard over both.
|
|
433
1091
|
"enrollments:read",
|
|
434
|
-
"enrollments:manage"
|
|
1092
|
+
"enrollments:manage",
|
|
1093
|
+
// Rigs (workspace-scoped, versioned sandbox machine definitions). rigs:use is
|
|
1094
|
+
// read + propose-change (the agent-native, additive path a sandboxed session
|
|
1095
|
+
// is trusted with); rigs:manage is create/edit/activate/promote/delete (the
|
|
1096
|
+
// admin-shaped path that mints or rolls versions). workspace:admin is the
|
|
1097
|
+
// super-wildcard over both.
|
|
1098
|
+
"rigs:use",
|
|
1099
|
+
"rigs:manage"
|
|
435
1100
|
]);
|
|
436
1101
|
function prefixedMcpToolName(registryId2, toolName) {
|
|
437
1102
|
return `${registryId2}__${toolName}`;
|
|
@@ -459,12 +1124,316 @@ var Workspace = z.object({
|
|
|
459
1124
|
// Per-workspace agent persona template (white-label override). null means
|
|
460
1125
|
// the deployment default (OPENGENI_AGENT_INSTRUCTIONS_TEMPLATE /
|
|
461
1126
|
// DEFAULT_AGENT_INSTRUCTIONS) is used. The runtime always injects the
|
|
462
|
-
// non-bypassable CORE (goal-loop ownership +
|
|
1127
|
+
// non-bypassable CORE (goal-loop ownership + variableSet block), so an
|
|
463
1128
|
// override restyles the persona without dropping that contract.
|
|
464
1129
|
agentInstructions: z.string().nullable(),
|
|
1130
|
+
// Growth-ready per-workspace settings bag (migration 0045). Known keys are
|
|
1131
|
+
// validated by WorkspaceSettingsSchema; unknown keys are preserved across
|
|
1132
|
+
// PATCH merges so newer settings survive an older server.
|
|
1133
|
+
settings: z.record(z.string(), z.unknown()),
|
|
1134
|
+
inferenceControl: z.object({
|
|
1135
|
+
state: z.enum(["active", "paused"]),
|
|
1136
|
+
revision: z.number().int().nonnegative(),
|
|
1137
|
+
reason: z.string().nullable(),
|
|
1138
|
+
changedBy: z.string().nullable(),
|
|
1139
|
+
changedAt: z.string().nullable()
|
|
1140
|
+
}),
|
|
1141
|
+
// Workspace default rig used by session/scheduled-task create fallback.
|
|
1142
|
+
defaultRigId: z.string().uuid().nullable(),
|
|
465
1143
|
createdAt: z.string(),
|
|
466
1144
|
updatedAt: z.string()
|
|
467
1145
|
});
|
|
1146
|
+
var WorkspaceTranscriptionTarget = z.object({
|
|
1147
|
+
provider: z.string().trim().min(1).max(128),
|
|
1148
|
+
model: z.string().trim().min(1).max(256).nullable(),
|
|
1149
|
+
credentialMode: z.enum(["managed", "byok"]),
|
|
1150
|
+
// A workspace-scoped connection reference, never credential material.
|
|
1151
|
+
credentialConnectionId: z.string().uuid().nullable(),
|
|
1152
|
+
region: z.string().trim().min(1).max(128).nullable()
|
|
1153
|
+
}).strict().superRefine((target, context) => {
|
|
1154
|
+
if (target.provider === "azure-speech" && target.credentialMode !== "byok") {
|
|
1155
|
+
context.addIssue({
|
|
1156
|
+
code: "custom",
|
|
1157
|
+
path: ["credentialMode"],
|
|
1158
|
+
message: "Azure Speech is supported only through workspace BYOK"
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
if (target.credentialMode === "byok" && target.credentialConnectionId === null) {
|
|
1162
|
+
context.addIssue({
|
|
1163
|
+
code: "custom",
|
|
1164
|
+
path: ["credentialConnectionId"],
|
|
1165
|
+
message: "BYOK transcription targets require a workspace connection reference"
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
if (target.credentialMode === "managed" && target.credentialConnectionId !== null) {
|
|
1169
|
+
context.addIssue({
|
|
1170
|
+
code: "custom",
|
|
1171
|
+
path: ["credentialConnectionId"],
|
|
1172
|
+
message: "managed transcription targets cannot name a BYOK connection"
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
var TranscriptionErrorCode = z.enum([
|
|
1177
|
+
"permission_denied",
|
|
1178
|
+
"not_supported",
|
|
1179
|
+
"network",
|
|
1180
|
+
"provider",
|
|
1181
|
+
"policy_blocked",
|
|
1182
|
+
"timeout",
|
|
1183
|
+
"cancelled",
|
|
1184
|
+
"unknown"
|
|
1185
|
+
]);
|
|
1186
|
+
var TranscriptionTimeSpan = z.object({
|
|
1187
|
+
startMilliseconds: z.number().finite().nonnegative(),
|
|
1188
|
+
endMilliseconds: z.number().finite().nonnegative()
|
|
1189
|
+
}).strict().superRefine((span, context) => {
|
|
1190
|
+
if (span.endMilliseconds < span.startMilliseconds) {
|
|
1191
|
+
context.addIssue({
|
|
1192
|
+
code: "custom",
|
|
1193
|
+
path: ["endMilliseconds"],
|
|
1194
|
+
message: "transcription spans must not end before they start"
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
var TranscriptionSpeaker = z.object({
|
|
1199
|
+
id: z.string().trim().min(1).max(128),
|
|
1200
|
+
label: z.string().trim().min(1).max(128).optional()
|
|
1201
|
+
}).strict();
|
|
1202
|
+
var TranscriptionWord = z.object({
|
|
1203
|
+
text: z.string().min(1).max(4096),
|
|
1204
|
+
span: TranscriptionTimeSpan,
|
|
1205
|
+
confidence: z.number().finite().min(0).max(1).optional(),
|
|
1206
|
+
speaker: TranscriptionSpeaker.optional()
|
|
1207
|
+
}).strict();
|
|
1208
|
+
var TranscriptionResultMetadata = z.object({
|
|
1209
|
+
detectedLanguage: z.string().trim().min(1).max(64).optional(),
|
|
1210
|
+
span: TranscriptionTimeSpan.optional(),
|
|
1211
|
+
confidence: z.number().finite().min(0).max(1).optional(),
|
|
1212
|
+
speaker: TranscriptionSpeaker.optional(),
|
|
1213
|
+
words: z.array(TranscriptionWord).max(1e4).optional()
|
|
1214
|
+
}).strict().superRefine((metadata, context) => {
|
|
1215
|
+
let previousStart = -1;
|
|
1216
|
+
for (const [index, word] of (metadata.words ?? []).entries()) {
|
|
1217
|
+
if (word.span.startMilliseconds < previousStart) {
|
|
1218
|
+
context.addIssue({
|
|
1219
|
+
code: "custom",
|
|
1220
|
+
path: ["words", index, "span", "startMilliseconds"],
|
|
1221
|
+
message: "transcription words must be ordered by start time"
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
previousStart = word.span.startMilliseconds;
|
|
1225
|
+
if (metadata.span && (word.span.startMilliseconds < metadata.span.startMilliseconds || word.span.endMilliseconds > metadata.span.endMilliseconds)) {
|
|
1226
|
+
context.addIssue({
|
|
1227
|
+
code: "custom",
|
|
1228
|
+
path: ["words", index, "span"],
|
|
1229
|
+
message: "transcription word spans must fall within the result span"
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
});
|
|
1234
|
+
var TranscriptionEventBase = z.object({
|
|
1235
|
+
localSessionId: z.string().min(1).max(256),
|
|
1236
|
+
sequence: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
1237
|
+
occurredAt: z.string().datetime({ offset: true })
|
|
1238
|
+
}).strict();
|
|
1239
|
+
var TranscriptionEvent = z.discriminatedUnion("type", [
|
|
1240
|
+
TranscriptionEventBase.extend({ type: z.literal("permission.requested") }),
|
|
1241
|
+
TranscriptionEventBase.extend({
|
|
1242
|
+
type: z.literal("session.opened"),
|
|
1243
|
+
providerSessionId: z.string().min(1).max(512)
|
|
1244
|
+
}),
|
|
1245
|
+
TranscriptionEventBase.extend({
|
|
1246
|
+
type: z.literal("transcript.partial"),
|
|
1247
|
+
segmentId: z.string().min(1).max(512),
|
|
1248
|
+
text: z.string().max(1e6),
|
|
1249
|
+
metadata: TranscriptionResultMetadata.optional()
|
|
1250
|
+
}),
|
|
1251
|
+
TranscriptionEventBase.extend({
|
|
1252
|
+
type: z.literal("transcript.final"),
|
|
1253
|
+
segmentId: z.string().min(1).max(512),
|
|
1254
|
+
text: z.string().max(1e6),
|
|
1255
|
+
providerAcceptanceId: z.string().min(1).max(512),
|
|
1256
|
+
metadata: TranscriptionResultMetadata.optional()
|
|
1257
|
+
}),
|
|
1258
|
+
TranscriptionEventBase.extend({
|
|
1259
|
+
type: z.literal("usage"),
|
|
1260
|
+
audioMilliseconds: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
|
|
1261
|
+
costUsd: z.number().finite().nonnegative().max(1e9).nullable()
|
|
1262
|
+
}),
|
|
1263
|
+
TranscriptionEventBase.extend({
|
|
1264
|
+
type: z.literal("session.reconnecting"),
|
|
1265
|
+
attempt: z.number().int().nonnegative().max(1e4),
|
|
1266
|
+
reason: z.string().min(1).max(256)
|
|
1267
|
+
}),
|
|
1268
|
+
TranscriptionEventBase.extend({
|
|
1269
|
+
type: z.literal("session.error"),
|
|
1270
|
+
code: TranscriptionErrorCode,
|
|
1271
|
+
recoverable: z.boolean()
|
|
1272
|
+
}),
|
|
1273
|
+
TranscriptionEventBase.extend({
|
|
1274
|
+
type: z.literal("session.closed"),
|
|
1275
|
+
reason: z.enum(["completed", "cancelled", "error", "replaced"])
|
|
1276
|
+
})
|
|
1277
|
+
]);
|
|
1278
|
+
var WorkspaceTranscriptionPolicy = z.object({
|
|
1279
|
+
enabled: z.boolean(),
|
|
1280
|
+
acceptanceId: z.string().uuid().nullable(),
|
|
1281
|
+
primary: WorkspaceTranscriptionTarget.nullable(),
|
|
1282
|
+
language: z.string().trim().min(1).max(64).nullable(),
|
|
1283
|
+
autoDetectLanguage: z.boolean(),
|
|
1284
|
+
diarization: z.object({
|
|
1285
|
+
enabled: z.boolean(),
|
|
1286
|
+
maxSpeakers: z.number().int().min(2).max(100).nullable()
|
|
1287
|
+
}).strict(),
|
|
1288
|
+
retention: z.object({
|
|
1289
|
+
mode: z.enum(["none", "provider-policy"]),
|
|
1290
|
+
maxDays: z.number().int().nonnegative().max(3650).nullable()
|
|
1291
|
+
}).strict(),
|
|
1292
|
+
privacy: z.object({
|
|
1293
|
+
allowProviderLogging: z.boolean(),
|
|
1294
|
+
allowProviderTraining: z.boolean()
|
|
1295
|
+
}).strict(),
|
|
1296
|
+
fallback: z.object({
|
|
1297
|
+
mode: z.enum(["disabled", "explicit"]),
|
|
1298
|
+
targets: z.array(WorkspaceTranscriptionTarget).max(8)
|
|
1299
|
+
}).strict(),
|
|
1300
|
+
cost: z.object({
|
|
1301
|
+
currency: z.literal("USD"),
|
|
1302
|
+
maxPerHour: z.number().finite().nonnegative().max(1e4).nullable(),
|
|
1303
|
+
maxPerMonth: z.number().finite().nonnegative().max(1e6).nullable()
|
|
1304
|
+
}).strict()
|
|
1305
|
+
}).strict().superRefine((policy, context) => {
|
|
1306
|
+
if (policy.enabled && policy.acceptanceId === null) {
|
|
1307
|
+
context.addIssue({
|
|
1308
|
+
code: "custom",
|
|
1309
|
+
path: ["acceptanceId"],
|
|
1310
|
+
message: "enabled transcription requires an accepted policy identity"
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
if (policy.enabled && policy.primary === null) {
|
|
1314
|
+
context.addIssue({
|
|
1315
|
+
code: "custom",
|
|
1316
|
+
path: ["primary"],
|
|
1317
|
+
message: "enabled transcription requires a primary target"
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
if (policy.enabled && !policy.autoDetectLanguage && policy.language === null) {
|
|
1321
|
+
context.addIssue({
|
|
1322
|
+
code: "custom",
|
|
1323
|
+
path: ["language"],
|
|
1324
|
+
message: "enabled transcription requires a language or accepted automatic detection"
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
if (policy.autoDetectLanguage && policy.language !== null) {
|
|
1328
|
+
context.addIssue({
|
|
1329
|
+
code: "custom",
|
|
1330
|
+
path: ["language"],
|
|
1331
|
+
message: "automatic language detection and a fixed language are mutually exclusive"
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
if (!policy.diarization.enabled && policy.diarization.maxSpeakers !== null) {
|
|
1335
|
+
context.addIssue({
|
|
1336
|
+
code: "custom",
|
|
1337
|
+
path: ["diarization", "maxSpeakers"],
|
|
1338
|
+
message: "disabled diarization cannot retain a speaker limit"
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
if (policy.fallback.mode === "disabled" && policy.fallback.targets.length > 0) {
|
|
1342
|
+
context.addIssue({
|
|
1343
|
+
code: "custom",
|
|
1344
|
+
path: ["fallback", "targets"],
|
|
1345
|
+
message: "disabled fallback cannot retain accepted targets"
|
|
1346
|
+
});
|
|
1347
|
+
}
|
|
1348
|
+
if (policy.fallback.mode === "explicit" && policy.fallback.targets.length === 0) {
|
|
1349
|
+
context.addIssue({
|
|
1350
|
+
code: "custom",
|
|
1351
|
+
path: ["fallback", "targets"],
|
|
1352
|
+
message: "explicit fallback requires at least one accepted target"
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
const targetKeys = [policy.primary, ...policy.fallback.targets].filter((target) => target !== null).map(
|
|
1356
|
+
(target) => [
|
|
1357
|
+
target.provider,
|
|
1358
|
+
target.model ?? "",
|
|
1359
|
+
target.credentialMode,
|
|
1360
|
+
target.credentialConnectionId ?? "",
|
|
1361
|
+
target.region ?? ""
|
|
1362
|
+
].join("\0")
|
|
1363
|
+
);
|
|
1364
|
+
if (new Set(targetKeys).size !== targetKeys.length) {
|
|
1365
|
+
context.addIssue({
|
|
1366
|
+
code: "custom",
|
|
1367
|
+
path: ["fallback", "targets"],
|
|
1368
|
+
message: "transcription targets must be unique"
|
|
1369
|
+
});
|
|
1370
|
+
}
|
|
1371
|
+
});
|
|
1372
|
+
var WorkspaceSettingsSchema = z.object({
|
|
1373
|
+
memoryEnabled: z.boolean().optional(),
|
|
1374
|
+
transcription: WorkspaceTranscriptionPolicy.optional()
|
|
1375
|
+
}).passthrough();
|
|
1376
|
+
function resolveWorkspaceMemoryEnabled(settings) {
|
|
1377
|
+
const parsed = WorkspaceSettingsSchema.safeParse(settings ?? {});
|
|
1378
|
+
return parsed.success ? parsed.data.memoryEnabled === true : false;
|
|
1379
|
+
}
|
|
1380
|
+
var UpdateWorkspaceSettingsRequest = z.object({
|
|
1381
|
+
memoryEnabled: z.boolean().optional(),
|
|
1382
|
+
transcription: WorkspaceTranscriptionPolicy.optional()
|
|
1383
|
+
}).passthrough();
|
|
1384
|
+
var SetWorkspaceDefaultRigRequest = z.object({
|
|
1385
|
+
rigId: z.string().uuid().nullable()
|
|
1386
|
+
});
|
|
1387
|
+
var UpdateWorkspaceModelPolicyRequest = z.object({
|
|
1388
|
+
allowedProviders: z.array(z.string().min(1).max(128)).max(64).nullable().optional(),
|
|
1389
|
+
allowedModels: z.array(z.string().min(1).max(256)).max(256).nullable().optional()
|
|
1390
|
+
});
|
|
1391
|
+
var turnInitiatorIdentityFields = {
|
|
1392
|
+
subjectId: z.string().min(1),
|
|
1393
|
+
/** Immutable display snapshot; never an authorization input. */
|
|
1394
|
+
label: z.string().min(1).optional()
|
|
1395
|
+
};
|
|
1396
|
+
var UNATTRIBUTED_LEGACY_INITIATOR_SUBJECT_ID = "unattributed-legacy";
|
|
1397
|
+
var ServiceTurnInitiator = z.object({
|
|
1398
|
+
kind: z.literal("service"),
|
|
1399
|
+
subjectId: z.string().min(1).max(1024).refine((value) => value !== UNATTRIBUTED_LEGACY_INITIATOR_SUBJECT_ID, {
|
|
1400
|
+
message: "unattributed-legacy is reserved for migrated rows"
|
|
1401
|
+
}),
|
|
1402
|
+
/** Immutable display snapshot; never an authorization input. */
|
|
1403
|
+
label: z.string().min(1).max(256).optional()
|
|
1404
|
+
});
|
|
1405
|
+
var TurnInitiatorContext = z.record(z.string(), z.unknown());
|
|
1406
|
+
var reservedServiceTurnInitiatorContextKeys = /* @__PURE__ */ new Set([
|
|
1407
|
+
"backfill",
|
|
1408
|
+
"label",
|
|
1409
|
+
"provenanceError",
|
|
1410
|
+
"via",
|
|
1411
|
+
"viaTruncated"
|
|
1412
|
+
]);
|
|
1413
|
+
var ServiceTurnInitiatorContext = TurnInitiatorContext.superRefine((value, ctx) => {
|
|
1414
|
+
for (const key of reservedServiceTurnInitiatorContextKeys) {
|
|
1415
|
+
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
1416
|
+
ctx.addIssue({
|
|
1417
|
+
code: z.ZodIssueCode.custom,
|
|
1418
|
+
path: [key],
|
|
1419
|
+
message: `${key} is reserved OpenGeni initiator context`
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
try {
|
|
1424
|
+
if (new TextEncoder().encode(JSON.stringify(value)).byteLength > 4096) {
|
|
1425
|
+
ctx.addIssue({
|
|
1426
|
+
code: z.ZodIssueCode.custom,
|
|
1427
|
+
message: "service initiator context exceeds 4096 UTF-8 bytes"
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1430
|
+
} catch {
|
|
1431
|
+
ctx.addIssue({
|
|
1432
|
+
code: z.ZodIssueCode.custom,
|
|
1433
|
+
message: "service initiator context must be JSON-serializable"
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
});
|
|
468
1437
|
var AccountGrant = z.object({
|
|
469
1438
|
accountId: z.string().uuid(),
|
|
470
1439
|
subjectId: z.string().min(1),
|
|
@@ -479,7 +1448,11 @@ var AccessGrant = z.object({
|
|
|
479
1448
|
subjectId: z.string().min(1),
|
|
480
1449
|
subjectLabel: z.string().optional(),
|
|
481
1450
|
permissions: z.array(Permission),
|
|
482
|
-
metadata: z.record(z.string(), z.unknown()).optional()
|
|
1451
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
1452
|
+
// Optional trusted causal principal for a command submitted by an embedding
|
|
1453
|
+
// host. Authorization still uses subjectId + permissions above.
|
|
1454
|
+
serviceInitiator: ServiceTurnInitiator.optional(),
|
|
1455
|
+
serviceInitiatorContext: ServiceTurnInitiatorContext.optional()
|
|
483
1456
|
});
|
|
484
1457
|
var AccessContext = z.object({
|
|
485
1458
|
mode: ProductAccessMode,
|
|
@@ -496,35 +1469,85 @@ var DelegatedAccessTokenPayload = z.object({
|
|
|
496
1469
|
subjectId: z.string().min(1),
|
|
497
1470
|
subjectLabel: z.string().optional(),
|
|
498
1471
|
permissions: z.array(Permission).min(1),
|
|
1472
|
+
// Trusted embedding hosts can sign a causal service principal separately
|
|
1473
|
+
// from the grant subject that authorizes the request. The claim is consumed
|
|
1474
|
+
// only when a command creates a new session/turn.
|
|
1475
|
+
serviceInitiator: ServiceTurnInitiator.optional(),
|
|
1476
|
+
serviceInitiatorContext: ServiceTurnInitiatorContext.optional(),
|
|
499
1477
|
// Worker-asserted session scope for first-party MCP calls (HMAC-signed, not
|
|
500
1478
|
// agent-controlled); enables session-scoped tools such as goal management.
|
|
501
1479
|
sessionId: z.string().uuid().optional(),
|
|
1480
|
+
// The turn making the call (the caller's identity), HMAC-signed by the worker
|
|
1481
|
+
// at turn setup. Lets a tool classify WHO is calling from the token itself,
|
|
1482
|
+
// instead of racily re-reading the session's live active_turn_id — e.g. the
|
|
1483
|
+
// sacred-pause guard must know if the CALLER is a machine child-notification
|
|
1484
|
+
// turn, and the active pointer can flip to another turn mid-check.
|
|
1485
|
+
turnId: z.string().uuid().optional(),
|
|
1486
|
+
// Exact execution owner. Agent control commands are accepted only while this
|
|
1487
|
+
// attempt still owns the signed turn.
|
|
1488
|
+
attemptId: z.string().uuid().optional(),
|
|
1489
|
+
executionGeneration: z.number().int().positive().optional(),
|
|
502
1490
|
exp: z.number().int().positive()
|
|
1491
|
+
}).superRefine((payload, ctx) => {
|
|
1492
|
+
if (payload.serviceInitiatorContext && !payload.serviceInitiator) {
|
|
1493
|
+
ctx.addIssue({
|
|
1494
|
+
code: z.ZodIssueCode.custom,
|
|
1495
|
+
path: ["serviceInitiatorContext"],
|
|
1496
|
+
message: "serviceInitiatorContext requires serviceInitiator"
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
if (payload.serviceInitiator && (payload.turnId !== void 0 || payload.attemptId !== void 0 || payload.executionGeneration !== void 0)) {
|
|
1500
|
+
ctx.addIssue({
|
|
1501
|
+
code: z.ZodIssueCode.custom,
|
|
1502
|
+
path: ["serviceInitiator"],
|
|
1503
|
+
message: "serviceInitiator cannot replace an exact agent-attempt initiator"
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
503
1506
|
});
|
|
1507
|
+
var delegatedAccessTokenPrefix = "ogd_";
|
|
1508
|
+
var delegatedServiceAccessTokenPrefix = "ogd2_";
|
|
504
1509
|
async function signDelegatedAccessToken(secret, payload) {
|
|
505
|
-
const
|
|
506
|
-
const
|
|
507
|
-
|
|
1510
|
+
const parsed = DelegatedAccessTokenPayload.parse(payload);
|
|
1511
|
+
const prefix = parsed.serviceInitiator ? delegatedServiceAccessTokenPrefix : delegatedAccessTokenPrefix;
|
|
1512
|
+
const encodedPayload = base64UrlEncode(JSON.stringify(parsed));
|
|
1513
|
+
const signature = await hmacSha256Base64Url(
|
|
1514
|
+
secret,
|
|
1515
|
+
prefix === delegatedServiceAccessTokenPrefix ? `${prefix}${encodedPayload}` : encodedPayload
|
|
1516
|
+
);
|
|
1517
|
+
return `${prefix}${encodedPayload}.${signature}`;
|
|
508
1518
|
}
|
|
509
1519
|
async function verifyDelegatedAccessToken(secret, token, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
510
|
-
|
|
1520
|
+
const prefix = token.startsWith(delegatedServiceAccessTokenPrefix) ? delegatedServiceAccessTokenPrefix : token.startsWith(delegatedAccessTokenPrefix) ? delegatedAccessTokenPrefix : null;
|
|
1521
|
+
if (!prefix) {
|
|
511
1522
|
return null;
|
|
512
1523
|
}
|
|
513
|
-
const withoutPrefix = token.slice(
|
|
1524
|
+
const withoutPrefix = token.slice(prefix.length);
|
|
514
1525
|
const dot = withoutPrefix.lastIndexOf(".");
|
|
515
1526
|
if (dot <= 0) {
|
|
516
1527
|
return null;
|
|
517
1528
|
}
|
|
518
1529
|
const encodedPayload = withoutPrefix.slice(0, dot);
|
|
519
1530
|
const signature = withoutPrefix.slice(dot + 1);
|
|
520
|
-
const expected = await hmacSha256Base64Url(
|
|
1531
|
+
const expected = await hmacSha256Base64Url(
|
|
1532
|
+
secret,
|
|
1533
|
+
prefix === delegatedServiceAccessTokenPrefix ? `${prefix}${encodedPayload}` : encodedPayload
|
|
1534
|
+
);
|
|
521
1535
|
if (!constantTimeEqual(signature, expected)) {
|
|
522
1536
|
return null;
|
|
523
1537
|
}
|
|
524
|
-
|
|
1538
|
+
let decoded;
|
|
1539
|
+
try {
|
|
1540
|
+
decoded = JSON.parse(base64UrlDecode(encodedPayload));
|
|
1541
|
+
} catch {
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1544
|
+
const payload = DelegatedAccessTokenPayload.safeParse(decoded);
|
|
525
1545
|
if (!payload.success || payload.data.exp < nowSeconds) {
|
|
526
1546
|
return null;
|
|
527
1547
|
}
|
|
1548
|
+
if (prefix === delegatedServiceAccessTokenPrefix !== (payload.data.serviceInitiator !== void 0)) {
|
|
1549
|
+
return null;
|
|
1550
|
+
}
|
|
528
1551
|
return payload.data;
|
|
529
1552
|
}
|
|
530
1553
|
var EnrollmentBearerPayload = z.object({
|
|
@@ -813,12 +1836,86 @@ var EntitlementValue = z.union([z.boolean(), z.string(), z.number(), z.array(z.s
|
|
|
813
1836
|
var Entitlements = z.record(z.string().min(1), EntitlementValue);
|
|
814
1837
|
var LimitDecision = z.discriminatedUnion("allowed", [
|
|
815
1838
|
z.object({ allowed: z.literal(true) }),
|
|
816
|
-
z.object({
|
|
1839
|
+
z.object({
|
|
1840
|
+
allowed: z.literal(false),
|
|
1841
|
+
code: z.string(),
|
|
1842
|
+
message: z.string()
|
|
1843
|
+
})
|
|
817
1844
|
]);
|
|
818
1845
|
var EntitlementDecision = z.discriminatedUnion("allowed", [
|
|
819
1846
|
z.object({ allowed: z.literal(true), quantity: z.number().optional() }),
|
|
820
|
-
z.object({
|
|
1847
|
+
z.object({
|
|
1848
|
+
allowed: z.literal(false),
|
|
1849
|
+
reason: z.string(),
|
|
1850
|
+
code: z.string().optional(),
|
|
1851
|
+
quantity: z.number().optional()
|
|
1852
|
+
})
|
|
821
1853
|
]);
|
|
1854
|
+
var GitCredentialProvider = z.enum(["github", "gitlab", "azure_devops"]);
|
|
1855
|
+
var GitCredentialBindingId = z.string().min(1).max(256);
|
|
1856
|
+
var GitRepositoryAccess = z.enum(["read", "write"]);
|
|
1857
|
+
var GitProviderRepositoryId = z.union([z.number().int().positive(), z.string().min(1)]);
|
|
1858
|
+
var GitCredentialRepositoryRef = z.object({
|
|
1859
|
+
provider: GitCredentialProvider.optional(),
|
|
1860
|
+
credentialBindingId: GitCredentialBindingId.optional(),
|
|
1861
|
+
access: GitRepositoryAccess.optional(),
|
|
1862
|
+
uri: z.string().min(1),
|
|
1863
|
+
ref: z.string().min(1),
|
|
1864
|
+
repositoryId: GitProviderRepositoryId.optional(),
|
|
1865
|
+
installationId: GitProviderRepositoryId.optional(),
|
|
1866
|
+
projectId: GitProviderRepositoryId.optional(),
|
|
1867
|
+
connectionId: z.string().min(1).optional()
|
|
1868
|
+
});
|
|
1869
|
+
var McpConnectionResourceScope = z.object({
|
|
1870
|
+
/** Provider-stable repository identity, serialized as a string on the wire. */
|
|
1871
|
+
id: z.string().min(1).max(512),
|
|
1872
|
+
kind: z.literal("repository")
|
|
1873
|
+
}).strict();
|
|
1874
|
+
var McpConnectionResourceScopes = z.array(McpConnectionResourceScope).min(1).max(256).superRefine((resources, context) => {
|
|
1875
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1876
|
+
for (const [index, resource] of resources.entries()) {
|
|
1877
|
+
const key = `${resource.kind}\0${resource.id}`;
|
|
1878
|
+
if (seen.has(key)) {
|
|
1879
|
+
context.addIssue({
|
|
1880
|
+
code: "custom",
|
|
1881
|
+
message: "selectedResources must not contain duplicates",
|
|
1882
|
+
path: [index]
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
seen.add(key);
|
|
1886
|
+
}
|
|
1887
|
+
});
|
|
1888
|
+
var McpServerConnectionRef = z.object({
|
|
1889
|
+
/** Opaque host or standalone connection identifier. */
|
|
1890
|
+
connectionId: z.string().min(1).optional(),
|
|
1891
|
+
/** Stable provider family (for example github, gitlab, or azure_devops). */
|
|
1892
|
+
provider: z.string().min(1).max(128).optional(),
|
|
1893
|
+
/** Provider host or tenant domain. */
|
|
1894
|
+
providerDomain: z.string().min(1),
|
|
1895
|
+
kind: z.enum(["oauth2", "api_key", "app_install", "delegated"]).optional(),
|
|
1896
|
+
scopes: z.array(z.string().min(1)).optional(),
|
|
1897
|
+
/** OAuth resource indicator. This is distinct from selectedResources. */
|
|
1898
|
+
resource: z.string().min(1).optional(),
|
|
1899
|
+
/** Exact provider resources this MCP binding is allowed to operate on. */
|
|
1900
|
+
selectedResources: McpConnectionResourceScopes.optional(),
|
|
1901
|
+
subjectScope: z.enum(["workspace", "subject"]).optional()
|
|
1902
|
+
}).strict().superRefine((reference, context) => {
|
|
1903
|
+
if (!reference.selectedResources) return;
|
|
1904
|
+
if (!reference.connectionId) {
|
|
1905
|
+
context.addIssue({
|
|
1906
|
+
code: "custom",
|
|
1907
|
+
message: "selectedResources requires connectionId",
|
|
1908
|
+
path: ["connectionId"]
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
if (!reference.provider) {
|
|
1912
|
+
context.addIssue({
|
|
1913
|
+
code: "custom",
|
|
1914
|
+
message: "selectedResources requires provider",
|
|
1915
|
+
path: ["provider"]
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
});
|
|
822
1919
|
var BillingBalance = z.object({
|
|
823
1920
|
accountId: z.string().uuid(),
|
|
824
1921
|
balanceMicros: z.number().int(),
|
|
@@ -844,17 +1941,109 @@ var RepositoryResourceRef = z.object({
|
|
|
844
1941
|
ref: z.string().min(1),
|
|
845
1942
|
mountPath: z.string().min(1).optional(),
|
|
846
1943
|
subpath: z.string().min(1).optional(),
|
|
1944
|
+
provider: GitCredentialProvider.optional(),
|
|
1945
|
+
credentialBindingId: GitCredentialBindingId.optional(),
|
|
1946
|
+
access: GitRepositoryAccess.optional(),
|
|
1947
|
+
repositoryId: GitProviderRepositoryId.optional(),
|
|
1948
|
+
installationId: GitProviderRepositoryId.optional(),
|
|
1949
|
+
projectId: GitProviderRepositoryId.optional(),
|
|
1950
|
+
connectionId: z.string().min(1).optional(),
|
|
847
1951
|
githubInstallationId: z.number().int().positive().optional(),
|
|
848
1952
|
githubRepositoryId: z.number().int().positive().optional()
|
|
849
1953
|
});
|
|
1954
|
+
function positiveGitProviderInteger(value) {
|
|
1955
|
+
if (typeof value === "number" && Number.isInteger(value) && value > 0) return value;
|
|
1956
|
+
if (typeof value === "string" && /^\d+$/.test(value) && Number(value) > 0) {
|
|
1957
|
+
return Number(value);
|
|
1958
|
+
}
|
|
1959
|
+
return null;
|
|
1960
|
+
}
|
|
1961
|
+
function gitCredentialProviderForRepository(resource) {
|
|
1962
|
+
if (resource.provider) return resource.provider;
|
|
1963
|
+
if (positiveGitProviderInteger(resource.githubInstallationId) && positiveGitProviderInteger(resource.githubRepositoryId)) {
|
|
1964
|
+
return "github";
|
|
1965
|
+
}
|
|
1966
|
+
return null;
|
|
1967
|
+
}
|
|
1968
|
+
function gitCredentialBindingIdForRepository(resource, provider = gitCredentialProviderForRepository(resource)) {
|
|
1969
|
+
if (!provider) return null;
|
|
1970
|
+
const installationId = provider === "github" ? positiveGitProviderInteger(resource.githubInstallationId ?? resource.installationId) : null;
|
|
1971
|
+
return resource.credentialBindingId ?? resource.connectionId ?? (installationId ? `github-installation:${installationId}` : provider);
|
|
1972
|
+
}
|
|
850
1973
|
var FileResourceRef = z.object({
|
|
851
1974
|
kind: z.literal("file"),
|
|
852
1975
|
fileId: z.string().uuid(),
|
|
853
1976
|
mountPath: z.string().min(1).optional()
|
|
854
1977
|
});
|
|
855
1978
|
var ResourceRef = z.discriminatedUnion("kind", [RepositoryResourceRef, FileResourceRef]);
|
|
1979
|
+
var ResourceMountPathError = class extends Error {
|
|
1980
|
+
constructor(message) {
|
|
1981
|
+
super(message);
|
|
1982
|
+
this.name = "ResourceMountPathError";
|
|
1983
|
+
}
|
|
1984
|
+
};
|
|
1985
|
+
function normalizeResourceMountPath(path) {
|
|
1986
|
+
const normalizedSeparators = path.trim().replace(/\\/g, "/");
|
|
1987
|
+
if (!normalizedSeparators || normalizedSeparators.startsWith("/") || /^[A-Za-z]:\//.test(normalizedSeparators) || normalizedSeparators.includes("\0")) {
|
|
1988
|
+
throw new ResourceMountPathError(`invalid resource mount path: ${path}`);
|
|
1989
|
+
}
|
|
1990
|
+
const segments = normalizedSeparators.split("/");
|
|
1991
|
+
if (segments.some(
|
|
1992
|
+
(segment) => !segment || segment === "." || segment === ".." || /[<>:"|?*\u0000-\u001f]/.test(segment) || /[ .]$/.test(segment) || /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(segment)
|
|
1993
|
+
)) {
|
|
1994
|
+
throw new ResourceMountPathError(`invalid resource mount path: ${path}`);
|
|
1995
|
+
}
|
|
1996
|
+
return segments.join("/");
|
|
1997
|
+
}
|
|
1998
|
+
function normalizeRepositorySubpath(path) {
|
|
1999
|
+
const relative = path.trim().replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
|
|
2000
|
+
return normalizeResourceMountPath(relative);
|
|
2001
|
+
}
|
|
2002
|
+
function resourceMountPathCollisionKey(path) {
|
|
2003
|
+
return normalizeResourceMountPath(path).normalize("NFKC").toLowerCase();
|
|
2004
|
+
}
|
|
2005
|
+
function defaultRepositoryMountPath(uri) {
|
|
2006
|
+
let url;
|
|
2007
|
+
try {
|
|
2008
|
+
url = new URL(uri);
|
|
2009
|
+
} catch {
|
|
2010
|
+
throw new ResourceMountPathError(`invalid repository URI for mount path: ${uri}`);
|
|
2011
|
+
}
|
|
2012
|
+
if (url.protocol !== "https:" || !url.host) {
|
|
2013
|
+
throw new ResourceMountPathError(`invalid repository URI for mount path: ${uri}`);
|
|
2014
|
+
}
|
|
2015
|
+
const repositoryPath = url.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
|
|
2016
|
+
const segments = repositoryPath.split("/").filter(Boolean);
|
|
2017
|
+
if (segments.length < 2) {
|
|
2018
|
+
throw new ResourceMountPathError(`repository URI must include owner and repo: ${uri}`);
|
|
2019
|
+
}
|
|
2020
|
+
return normalizeResourceMountPath(
|
|
2021
|
+
`repos/${encodeURIComponent(url.host.toLowerCase())}/${segments.join("/")}`
|
|
2022
|
+
);
|
|
2023
|
+
}
|
|
2024
|
+
function resourceMountPath(resource) {
|
|
2025
|
+
if (resource.mountPath) return normalizeResourceMountPath(resource.mountPath);
|
|
2026
|
+
return resource.kind === "file" ? normalizeResourceMountPath(`files/${resource.fileId}`) : defaultRepositoryMountPath(resource.uri);
|
|
2027
|
+
}
|
|
2028
|
+
function assertUniqueResourceMountPaths(resources) {
|
|
2029
|
+
const mounted = /* @__PURE__ */ new Set();
|
|
2030
|
+
for (const resource of resources) {
|
|
2031
|
+
const path = resourceMountPath(resource);
|
|
2032
|
+
const key = resourceMountPathCollisionKey(path);
|
|
2033
|
+
if (mounted.has(key)) {
|
|
2034
|
+
throw new ResourceRefConflictError(`resource mount path is already attached: ${path}`);
|
|
2035
|
+
}
|
|
2036
|
+
mounted.add(key);
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
856
2039
|
var FileStatus = z.enum(["pending_upload", "ready", "failed", "expired", "deleted"]);
|
|
857
|
-
var FileUploadStatus = z.enum([
|
|
2040
|
+
var FileUploadStatus = z.enum([
|
|
2041
|
+
"pending",
|
|
2042
|
+
"cleanup_pending",
|
|
2043
|
+
"completed",
|
|
2044
|
+
"expired",
|
|
2045
|
+
"failed"
|
|
2046
|
+
]);
|
|
858
2047
|
var FileAsset = z.object({
|
|
859
2048
|
id: z.string().uuid(),
|
|
860
2049
|
workspaceId: z.string().uuid(),
|
|
@@ -891,7 +2080,16 @@ var FileDownloadUrlResponse = z.object({
|
|
|
891
2080
|
expiresAt: z.string()
|
|
892
2081
|
});
|
|
893
2082
|
var DocumentStatus = z.enum(["queued", "indexing", "ready", "failed"]);
|
|
894
|
-
var KnowledgeSourceKind = z.enum([
|
|
2083
|
+
var KnowledgeSourceKind = z.enum([
|
|
2084
|
+
"manual_upload",
|
|
2085
|
+
"meeting_transcript",
|
|
2086
|
+
"repository",
|
|
2087
|
+
"email",
|
|
2088
|
+
"chat",
|
|
2089
|
+
"document",
|
|
2090
|
+
"web",
|
|
2091
|
+
"other"
|
|
2092
|
+
]);
|
|
895
2093
|
var DocumentSearchMode = z.enum(["hybrid", "vector", "keyword"]);
|
|
896
2094
|
var DocumentBase = z.object({
|
|
897
2095
|
id: z.string().uuid(),
|
|
@@ -972,8 +2170,21 @@ var DocumentSearchRequest = z.object({
|
|
|
972
2170
|
aclTags: z.array(z.string().min(1)).optional(),
|
|
973
2171
|
limit: z.number().int().positive().max(50).default(5)
|
|
974
2172
|
});
|
|
975
|
-
var KnowledgeMemoryStatus = z.enum([
|
|
976
|
-
|
|
2173
|
+
var KnowledgeMemoryStatus = z.enum([
|
|
2174
|
+
"proposed",
|
|
2175
|
+
"approved",
|
|
2176
|
+
"rejected",
|
|
2177
|
+
"active",
|
|
2178
|
+
"superseded",
|
|
2179
|
+
"archived"
|
|
2180
|
+
]);
|
|
2181
|
+
var KnowledgeMemoryKind = z.enum([
|
|
2182
|
+
"semantic",
|
|
2183
|
+
"episodic",
|
|
2184
|
+
"procedural",
|
|
2185
|
+
"decision",
|
|
2186
|
+
"preference"
|
|
2187
|
+
]);
|
|
977
2188
|
var KnowledgeSourceRef = z.object({
|
|
978
2189
|
kind: z.enum(["document_chunk", "document", "session_event", "memory", "external"]),
|
|
979
2190
|
id: z.string().min(1),
|
|
@@ -994,18 +2205,31 @@ var KnowledgeMemory = z.object({
|
|
|
994
2205
|
createdBySessionId: z.string().uuid().nullable(),
|
|
995
2206
|
reviewedBy: z.string().nullable(),
|
|
996
2207
|
reviewedAt: z.string().nullable(),
|
|
2208
|
+
// Workspace Memory V1 fields. usageCount/lastUsedAt feed end-state ranking and
|
|
2209
|
+
// decay; supersedesId/supersededById link correction chains; validFrom/validUntil
|
|
2210
|
+
// are the point-in-time window. embedding/embeddingModel/textHash are internal
|
|
2211
|
+
// and never exposed on the wire.
|
|
2212
|
+
pinned: z.boolean(),
|
|
2213
|
+
usageCount: z.number().int(),
|
|
2214
|
+
lastUsedAt: z.string().nullable(),
|
|
2215
|
+
supersedesId: z.string().uuid().nullable(),
|
|
2216
|
+
supersededById: z.string().uuid().nullable(),
|
|
2217
|
+
validFrom: z.string(),
|
|
2218
|
+
validUntil: z.string().nullable(),
|
|
997
2219
|
createdAt: z.string(),
|
|
998
2220
|
updatedAt: z.string()
|
|
999
2221
|
});
|
|
1000
2222
|
var CreateKnowledgeMemoryRequest = z.object({
|
|
1001
|
-
status: KnowledgeMemoryStatus.default("
|
|
2223
|
+
status: KnowledgeMemoryStatus.default("active"),
|
|
1002
2224
|
kind: KnowledgeMemoryKind.default("semantic"),
|
|
1003
2225
|
scope: z.string().min(1).default("workspace"),
|
|
1004
2226
|
text: z.string().min(1),
|
|
1005
2227
|
sourceRefs: z.array(KnowledgeSourceRef).default([]),
|
|
1006
2228
|
confidence: z.number().min(0).max(1).default(0.5),
|
|
1007
2229
|
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
1008
|
-
createdBySessionId: z.string().uuid().optional()
|
|
2230
|
+
createdBySessionId: z.string().uuid().optional(),
|
|
2231
|
+
pinned: z.boolean().optional(),
|
|
2232
|
+
replacesId: z.string().min(1).optional()
|
|
1009
2233
|
});
|
|
1010
2234
|
var UpdateKnowledgeMemoryRequest = z.object({
|
|
1011
2235
|
status: KnowledgeMemoryStatus.optional(),
|
|
@@ -1015,7 +2239,9 @@ var UpdateKnowledgeMemoryRequest = z.object({
|
|
|
1015
2239
|
sourceRefs: z.array(KnowledgeSourceRef).optional(),
|
|
1016
2240
|
confidence: z.number().min(0).max(1).optional(),
|
|
1017
2241
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
1018
|
-
reviewedBy: z.string().min(1).optional()
|
|
2242
|
+
reviewedBy: z.string().min(1).optional(),
|
|
2243
|
+
// Human audit action: pin (never decays) / unpin.
|
|
2244
|
+
pinned: z.boolean().optional()
|
|
1019
2245
|
});
|
|
1020
2246
|
var KnowledgeMemorySearchRequest = z.object({
|
|
1021
2247
|
query: z.string().min(1).optional(),
|
|
@@ -1024,6 +2250,23 @@ var KnowledgeMemorySearchRequest = z.object({
|
|
|
1024
2250
|
scope: z.string().min(1).optional(),
|
|
1025
2251
|
limit: z.number().int().positive().max(100).default(20)
|
|
1026
2252
|
});
|
|
2253
|
+
var WorkspaceMemorySearchMode = z.enum(["hybrid", "vector", "keyword"]);
|
|
2254
|
+
var WorkspaceMemorySearchRequest = z.object({
|
|
2255
|
+
query: z.string().min(1),
|
|
2256
|
+
kind: KnowledgeMemoryKind.optional(),
|
|
2257
|
+
limit: z.number().int().positive().max(20).optional(),
|
|
2258
|
+
mode: WorkspaceMemorySearchMode.optional()
|
|
2259
|
+
});
|
|
2260
|
+
var WorkspaceMemorySearchResult = z.object({
|
|
2261
|
+
memory: KnowledgeMemory,
|
|
2262
|
+
score: z.number(),
|
|
2263
|
+
matchType: WorkspaceMemorySearchMode,
|
|
2264
|
+
vectorScore: z.number().nullable(),
|
|
2265
|
+
keywordScore: z.number().nullable()
|
|
2266
|
+
});
|
|
2267
|
+
var WorkspaceMemorySearchResponse = z.object({
|
|
2268
|
+
results: z.array(WorkspaceMemorySearchResult)
|
|
2269
|
+
});
|
|
1027
2270
|
var ToolRef = z.object({
|
|
1028
2271
|
kind: z.literal("mcp"),
|
|
1029
2272
|
id: z.string().min(1),
|
|
@@ -1036,13 +2279,16 @@ var ToolRef = z.object({
|
|
|
1036
2279
|
optional: z.boolean().optional()
|
|
1037
2280
|
});
|
|
1038
2281
|
var registryId = /^[A-Za-z0-9_-]+$/;
|
|
1039
|
-
var httpsUrl = z.string().url().refine(
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
}
|
|
2282
|
+
var httpsUrl = z.string().url().refine(
|
|
2283
|
+
(value) => {
|
|
2284
|
+
try {
|
|
2285
|
+
return new URL(value).protocol === "https:";
|
|
2286
|
+
} catch {
|
|
2287
|
+
return false;
|
|
2288
|
+
}
|
|
2289
|
+
},
|
|
2290
|
+
{ message: "URL must use https" }
|
|
2291
|
+
);
|
|
1046
2292
|
var SessionMcpServerInput = z.object({
|
|
1047
2293
|
id: z.string().min(1).regex(registryId),
|
|
1048
2294
|
name: z.string().min(1).optional(),
|
|
@@ -1058,7 +2304,10 @@ var SessionMcpServerInput = z.object({
|
|
|
1058
2304
|
requireApproval: z.union([z.boolean(), z.array(z.string().min(1))]).optional(),
|
|
1059
2305
|
// Write-only credential headers. Values are encrypted at rest and never
|
|
1060
2306
|
// returned in session responses or events; response metadata exposes names.
|
|
1061
|
-
headers: z.record(z.string(), z.string()).optional()
|
|
2307
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
2308
|
+
// Non-secret opaque pointer resolved at request time by the standalone
|
|
2309
|
+
// connection broker or an embedding host's mcpCredentials port.
|
|
2310
|
+
connectionRef: McpServerConnectionRef.optional()
|
|
1062
2311
|
});
|
|
1063
2312
|
var SessionMcpCredentialUpdateInput = z.object({
|
|
1064
2313
|
id: z.string().min(1).regex(registryId),
|
|
@@ -1069,7 +2318,8 @@ var SessionMcpServerMetadata = z.object({
|
|
|
1069
2318
|
name: z.string().min(1).nullable(),
|
|
1070
2319
|
url: httpsUrl,
|
|
1071
2320
|
headerNames: z.array(z.string()).default([]),
|
|
1072
|
-
credentialVersion: z.number().int().positive()
|
|
2321
|
+
credentialVersion: z.number().int().positive(),
|
|
2322
|
+
connectionRef: McpServerConnectionRef.nullable().default(null)
|
|
1073
2323
|
}).strict();
|
|
1074
2324
|
var ResourceRefConflictError = class extends Error {
|
|
1075
2325
|
constructor(message) {
|
|
@@ -1096,9 +2346,18 @@ function mergeToolRefs(existing, additions) {
|
|
|
1096
2346
|
return order.map((key) => byKey.get(key));
|
|
1097
2347
|
}
|
|
1098
2348
|
function mergeResourceRefs(existing, additions, options = {}) {
|
|
2349
|
+
if (options.rejectConflicts) {
|
|
2350
|
+
assertUniqueResourceMountPaths(existing);
|
|
2351
|
+
}
|
|
1099
2352
|
const out = [...existing];
|
|
1100
|
-
const mountPaths = new Map(
|
|
1101
|
-
|
|
2353
|
+
const mountPaths = new Map(
|
|
2354
|
+
existing.map(
|
|
2355
|
+
(resource) => [resourceMountPathCollisionKey(resourceMountPath(resource)), stableJson(resource)]
|
|
2356
|
+
)
|
|
2357
|
+
);
|
|
2358
|
+
const identities = new Map(
|
|
2359
|
+
existing.map((resource) => [resourceIdentityKey(resource), stableJson(resource)])
|
|
2360
|
+
);
|
|
1102
2361
|
const exact = new Set(existing.map(stableJson));
|
|
1103
2362
|
for (const resource of additions) {
|
|
1104
2363
|
const serialized = stableJson(resource);
|
|
@@ -1106,22 +2365,23 @@ function mergeResourceRefs(existing, additions, options = {}) {
|
|
|
1106
2365
|
continue;
|
|
1107
2366
|
}
|
|
1108
2367
|
if (options.rejectConflicts) {
|
|
1109
|
-
const
|
|
2368
|
+
const mountPath = resourceMountPath(resource);
|
|
2369
|
+
const existingAtMount = mountPaths.get(resourceMountPathCollisionKey(mountPath));
|
|
1110
2370
|
if (existingAtMount && existingAtMount !== serialized) {
|
|
1111
|
-
throw new ResourceRefConflictError(`resource mount path is already attached: ${
|
|
2371
|
+
throw new ResourceRefConflictError(`resource mount path is already attached: ${mountPath}`);
|
|
1112
2372
|
}
|
|
1113
2373
|
const identity = resourceIdentityKey(resource);
|
|
1114
2374
|
const existingIdentity = identities.get(identity);
|
|
1115
2375
|
if (existingIdentity && existingIdentity !== serialized) {
|
|
1116
|
-
throw new ResourceRefConflictError(
|
|
2376
|
+
throw new ResourceRefConflictError(
|
|
2377
|
+
`resource is already attached with different settings: ${identity}`
|
|
2378
|
+
);
|
|
1117
2379
|
}
|
|
1118
2380
|
}
|
|
1119
2381
|
out.push(resource);
|
|
1120
2382
|
exact.add(serialized);
|
|
1121
2383
|
identities.set(resourceIdentityKey(resource), serialized);
|
|
1122
|
-
|
|
1123
|
-
mountPaths.set(resource.mountPath, serialized);
|
|
1124
|
-
}
|
|
2384
|
+
mountPaths.set(resourceMountPathCollisionKey(resourceMountPath(resource)), serialized);
|
|
1125
2385
|
}
|
|
1126
2386
|
return out;
|
|
1127
2387
|
}
|
|
@@ -1143,17 +2403,39 @@ function sortJson(value) {
|
|
|
1143
2403
|
return value.map(sortJson);
|
|
1144
2404
|
}
|
|
1145
2405
|
if (value && typeof value === "object") {
|
|
1146
|
-
return Object.fromEntries(
|
|
2406
|
+
return Object.fromEntries(
|
|
2407
|
+
Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, nested]) => [key, sortJson(nested)])
|
|
2408
|
+
);
|
|
1147
2409
|
}
|
|
1148
2410
|
return value;
|
|
1149
2411
|
}
|
|
1150
|
-
var SessionTurnStatus = z.enum([
|
|
1151
|
-
|
|
2412
|
+
var SessionTurnStatus = z.enum([
|
|
2413
|
+
"queued",
|
|
2414
|
+
"running",
|
|
2415
|
+
"requires_action",
|
|
2416
|
+
"recovering",
|
|
2417
|
+
"waiting_capacity",
|
|
2418
|
+
"completed",
|
|
2419
|
+
"failed",
|
|
2420
|
+
"cancelled",
|
|
2421
|
+
"superseded",
|
|
2422
|
+
"withdrawn_for_edit"
|
|
2423
|
+
]);
|
|
2424
|
+
var SessionTurnSource = z.enum([
|
|
2425
|
+
"user",
|
|
2426
|
+
"scheduled_task",
|
|
2427
|
+
"api",
|
|
2428
|
+
"goal",
|
|
2429
|
+
"system",
|
|
2430
|
+
"compaction"
|
|
2431
|
+
]);
|
|
2432
|
+
var SessionControlState = z.enum(["active", "paused"]);
|
|
2433
|
+
var WorkspaceInferenceState = z.enum(["active", "paused"]);
|
|
1152
2434
|
var SessionGoalStatus = z.enum(["active", "paused", "completed"]);
|
|
1153
2435
|
var SessionGoalCreatedBy = z.enum(["api", "agent", "scheduled_task"]);
|
|
1154
2436
|
var SessionGoalPausedReason = z.enum([
|
|
1155
2437
|
"agent",
|
|
1156
|
-
"
|
|
2438
|
+
"user_pause",
|
|
1157
2439
|
"api",
|
|
1158
2440
|
"no_progress",
|
|
1159
2441
|
"max_auto_continuations",
|
|
@@ -1191,11 +2473,17 @@ var UpdateSessionGoalRequest = z.object({
|
|
|
1191
2473
|
var UpdateSessionRequest = z.object({
|
|
1192
2474
|
title: z.string().min(1).max(200)
|
|
1193
2475
|
});
|
|
2476
|
+
var UpdateSessionPinRequest = z.object({
|
|
2477
|
+
pinned: z.boolean(),
|
|
2478
|
+
expectedVersion: z.number().int().nonnegative().optional()
|
|
2479
|
+
});
|
|
1194
2480
|
var ClearSessionContextRequest = z.object({
|
|
1195
2481
|
confirm: z.literal(true)
|
|
1196
2482
|
});
|
|
1197
2483
|
var CLEARED_RUN_STATE_MARKER = "$opengeniCleared";
|
|
1198
|
-
var CLEARED_RUN_STATE_BLOB = JSON.stringify({
|
|
2484
|
+
var CLEARED_RUN_STATE_BLOB = JSON.stringify({
|
|
2485
|
+
[CLEARED_RUN_STATE_MARKER]: true
|
|
2486
|
+
});
|
|
1199
2487
|
function isClearedRunStateBlob(serialized) {
|
|
1200
2488
|
if (!serialized) {
|
|
1201
2489
|
return false;
|
|
@@ -1209,11 +2497,110 @@ function isClearedRunStateBlob(serialized) {
|
|
|
1209
2497
|
}
|
|
1210
2498
|
var CompactSessionContextRequest = z.object({}).strict();
|
|
1211
2499
|
var CompactSessionContextResult = z.object({
|
|
1212
|
-
//
|
|
1213
|
-
//
|
|
1214
|
-
|
|
2500
|
+
// pending: an active/paused session will compact at its next safe boundary.
|
|
2501
|
+
// completed: an idle compaction-only activity completed synchronously.
|
|
2502
|
+
// noop: there is no active history to compact.
|
|
2503
|
+
status: z.enum(["pending", "completed", "noop"]),
|
|
1215
2504
|
message: z.string()
|
|
1216
2505
|
});
|
|
2506
|
+
var TurnInitiator = z.object({
|
|
2507
|
+
kind: z.enum(["subject", "service"]),
|
|
2508
|
+
...turnInitiatorIdentityFields
|
|
2509
|
+
});
|
|
2510
|
+
var SessionAuthorizationSurface = z.enum([
|
|
2511
|
+
"http",
|
|
2512
|
+
"core",
|
|
2513
|
+
"stream",
|
|
2514
|
+
"first_party_mcp",
|
|
2515
|
+
"toolspace"
|
|
2516
|
+
]);
|
|
2517
|
+
var SessionAuthorizationOperation = z.enum([
|
|
2518
|
+
"session.read",
|
|
2519
|
+
"session.events.read",
|
|
2520
|
+
"session.stream.read",
|
|
2521
|
+
"session.stream.acknowledge",
|
|
2522
|
+
"session.turns.read",
|
|
2523
|
+
"session.append",
|
|
2524
|
+
"session.steer",
|
|
2525
|
+
"session.control",
|
|
2526
|
+
"session.queue.read",
|
|
2527
|
+
"session.queue.control",
|
|
2528
|
+
"session.composer.read",
|
|
2529
|
+
"session.composer.write",
|
|
2530
|
+
"session.lineage.read",
|
|
2531
|
+
"session.capture.read",
|
|
2532
|
+
"session.files.read",
|
|
2533
|
+
"session.files.write",
|
|
2534
|
+
"session.git.read",
|
|
2535
|
+
"session.terminal.read",
|
|
2536
|
+
"session.terminal.control",
|
|
2537
|
+
"session.viewer.read",
|
|
2538
|
+
"session.viewer.control",
|
|
2539
|
+
"session.first_party_mcp.call",
|
|
2540
|
+
"session.toolspace.call",
|
|
2541
|
+
"session.pin.write",
|
|
2542
|
+
"session.codex_account.write",
|
|
2543
|
+
"session.context.write",
|
|
2544
|
+
"session.approval.write",
|
|
2545
|
+
"session.human_input.read",
|
|
2546
|
+
"session.human_input.write",
|
|
2547
|
+
"session.title.write",
|
|
2548
|
+
"session.goal.read",
|
|
2549
|
+
"session.goal.write",
|
|
2550
|
+
"session.child.create"
|
|
2551
|
+
]);
|
|
2552
|
+
var SessionAuthorizationActor = z.discriminatedUnion("kind", [
|
|
2553
|
+
z.object({
|
|
2554
|
+
kind: z.literal("subject"),
|
|
2555
|
+
subjectId: z.string().min(1),
|
|
2556
|
+
subjectLabel: z.string().min(1).optional()
|
|
2557
|
+
}),
|
|
2558
|
+
z.object({
|
|
2559
|
+
kind: z.literal("agent_attempt"),
|
|
2560
|
+
/** Technical, authenticated first-party caller (not the host authority). */
|
|
2561
|
+
subjectId: z.string().min(1),
|
|
2562
|
+
callerSessionId: z.string().uuid(),
|
|
2563
|
+
callerRootSessionId: z.string().uuid(),
|
|
2564
|
+
turnId: z.string().uuid(),
|
|
2565
|
+
attemptId: z.string().uuid(),
|
|
2566
|
+
executionGeneration: z.number().int().positive(),
|
|
2567
|
+
/** Frozen authority that admitted the calling turn. */
|
|
2568
|
+
initiator: TurnInitiator,
|
|
2569
|
+
initiatorContext: TurnInitiatorContext
|
|
2570
|
+
})
|
|
2571
|
+
]);
|
|
2572
|
+
var SessionAuthorizationTarget = z.object({
|
|
2573
|
+
sessionId: z.string().uuid(),
|
|
2574
|
+
/** Server-resolved workspace lineage root; never accepted from a caller. */
|
|
2575
|
+
rootSessionId: z.string().uuid()
|
|
2576
|
+
});
|
|
2577
|
+
var SessionAuthorizationDecision = z.discriminatedUnion("allowed", [
|
|
2578
|
+
z.object({
|
|
2579
|
+
allowed: z.literal(true),
|
|
2580
|
+
/**
|
|
2581
|
+
* Whether related-session metadata may be projected with the target.
|
|
2582
|
+
* `target` is the fail-closed default for exact shares; `root` permits the
|
|
2583
|
+
* target's full lineage tree. This does not authorize a separate operation
|
|
2584
|
+
* against another session, which always requires its own decision.
|
|
2585
|
+
*/
|
|
2586
|
+
relatedSessionAccess: z.enum(["target", "root"]).optional(),
|
|
2587
|
+
/** A host may request a tighter stream reauthorization bound. */
|
|
2588
|
+
reauthorizeAfterMs: z.number().int().min(1e3).max(6e4).optional()
|
|
2589
|
+
}),
|
|
2590
|
+
z.object({
|
|
2591
|
+
allowed: z.literal(false),
|
|
2592
|
+
reason: z.enum(["not_found", "forbidden", "revoked"])
|
|
2593
|
+
})
|
|
2594
|
+
]);
|
|
2595
|
+
var SESSION_AUTHORIZATION_LIST_SCOPE_MAX_IDS = 1e4;
|
|
2596
|
+
var SessionAuthorizationListScope = z.discriminatedUnion("kind", [
|
|
2597
|
+
z.object({ kind: z.literal("all") }),
|
|
2598
|
+
z.object({
|
|
2599
|
+
kind: z.literal("scoped"),
|
|
2600
|
+
rootSessionIds: z.array(z.string().uuid()).max(SESSION_AUTHORIZATION_LIST_SCOPE_MAX_IDS),
|
|
2601
|
+
sessionIds: z.array(z.string().uuid()).max(SESSION_AUTHORIZATION_LIST_SCOPE_MAX_IDS)
|
|
2602
|
+
})
|
|
2603
|
+
]);
|
|
1217
2604
|
var SessionTurn = z.object({
|
|
1218
2605
|
id: z.string().uuid(),
|
|
1219
2606
|
workspaceId: z.string().uuid(),
|
|
@@ -1222,7 +2609,7 @@ var SessionTurn = z.object({
|
|
|
1222
2609
|
temporalWorkflowId: z.string(),
|
|
1223
2610
|
status: SessionTurnStatus,
|
|
1224
2611
|
source: SessionTurnSource,
|
|
1225
|
-
position: z.number().int()
|
|
2612
|
+
position: z.number().int(),
|
|
1226
2613
|
prompt: z.string().min(1),
|
|
1227
2614
|
resources: z.array(ResourceRef),
|
|
1228
2615
|
tools: z.array(ToolRef),
|
|
@@ -1232,55 +2619,492 @@ var SessionTurn = z.object({
|
|
|
1232
2619
|
// Per-turn OS override. NULL = inherit the session's sandboxOs.
|
|
1233
2620
|
sandboxOs: SandboxOs.nullable(),
|
|
1234
2621
|
metadata: z.record(z.string(), z.unknown()),
|
|
2622
|
+
version: z.number().int().positive(),
|
|
2623
|
+
executionGeneration: z.number().int().nonnegative(),
|
|
2624
|
+
activeAttemptId: z.string().uuid().nullable(),
|
|
2625
|
+
lineage: z.record(z.string(), z.unknown()),
|
|
2626
|
+
initiator: TurnInitiator,
|
|
2627
|
+
initiatorContext: TurnInitiatorContext,
|
|
2628
|
+
cancelledBy: z.string().nullable(),
|
|
2629
|
+
cancelReason: z.string().nullable(),
|
|
1235
2630
|
startedAt: z.string().nullable(),
|
|
1236
2631
|
finishedAt: z.string().nullable(),
|
|
1237
2632
|
createdAt: z.string(),
|
|
1238
2633
|
updatedAt: z.string()
|
|
1239
2634
|
});
|
|
1240
|
-
var
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
2635
|
+
var EffectiveControlBlocker = z.object({
|
|
2636
|
+
kind: z.enum(["session", "workspace"]),
|
|
2637
|
+
sessionId: z.string().uuid().optional(),
|
|
2638
|
+
displayName: z.string().min(1),
|
|
2639
|
+
actor: z.string().nullable(),
|
|
2640
|
+
reason: z.string().nullable(),
|
|
2641
|
+
changedAt: z.string().nullable(),
|
|
2642
|
+
revision: z.number().int().nonnegative()
|
|
2643
|
+
});
|
|
2644
|
+
var EffectiveControlResumeOption = z.object({
|
|
2645
|
+
scope: z.enum(["selected", "session", "workspace"]),
|
|
2646
|
+
targetId: z.string().uuid().optional(),
|
|
2647
|
+
selectedStateAfter: SessionControlState,
|
|
2648
|
+
remainingPrimaryBlocker: EffectiveControlBlocker.optional(),
|
|
2649
|
+
impactCopy: z.string().min(1)
|
|
2650
|
+
});
|
|
2651
|
+
var EffectiveSessionControl = z.object({
|
|
2652
|
+
state: SessionControlState,
|
|
2653
|
+
controlVersion: z.number().int().nonnegative(),
|
|
2654
|
+
controlEtag: z.string().min(1),
|
|
2655
|
+
directState: SessionControlState,
|
|
2656
|
+
primaryBlocker: EffectiveControlBlocker.nullable(),
|
|
2657
|
+
additionalBlockerCount: z.number().int().nonnegative(),
|
|
2658
|
+
blockers: z.array(EffectiveControlBlocker),
|
|
2659
|
+
resumeOptions: z.array(EffectiveControlResumeOption),
|
|
2660
|
+
override: z.object({
|
|
2661
|
+
rootSessionId: z.string().uuid(),
|
|
2662
|
+
revision: z.number().int().nonnegative()
|
|
2663
|
+
}).nullable(),
|
|
2664
|
+
settlement: z.object({
|
|
2665
|
+
state: z.literal("stopping"),
|
|
2666
|
+
attemptCount: z.number().int().positive(),
|
|
2667
|
+
interruptionPendingCount: z.number().int().nonnegative(),
|
|
2668
|
+
quiescencePendingCount: z.number().int().nonnegative()
|
|
2669
|
+
}).nullable()
|
|
2670
|
+
});
|
|
2671
|
+
var SESSION_OPERATION_KEY_MAX_CHARS = 256;
|
|
2672
|
+
var SessionOperationKey = z.string().min(1).max(SESSION_OPERATION_KEY_MAX_CHARS);
|
|
2673
|
+
var SessionCommandReceipt = z.object({
|
|
2674
|
+
id: z.string().uuid(),
|
|
2675
|
+
action: z.string().min(1),
|
|
2676
|
+
operationKey: z.string().min(1).max(SESSION_OPERATION_KEY_MAX_CHARS),
|
|
2677
|
+
targetSessionId: z.string().uuid().nullable(),
|
|
2678
|
+
targetTurnId: z.string().uuid().nullable(),
|
|
2679
|
+
appliedControlRevision: z.number().int().nonnegative().nullable(),
|
|
2680
|
+
appliedQueueVersion: z.number().int().nonnegative().nullable(),
|
|
2681
|
+
appliedTurnVersion: z.number().int().positive().nullable(),
|
|
2682
|
+
appliedDraftRevision: z.number().int().positive().nullable(),
|
|
2683
|
+
createdAt: z.string()
|
|
1248
2684
|
});
|
|
1249
|
-
var
|
|
1250
|
-
|
|
2685
|
+
var ComposerDraft = z.object({
|
|
2686
|
+
revision: z.number().int().nonnegative(),
|
|
2687
|
+
text: z.string(),
|
|
2688
|
+
resources: z.array(ResourceRef),
|
|
2689
|
+
tools: z.array(ToolRef),
|
|
2690
|
+
model: z.string().min(1),
|
|
2691
|
+
reasoningEffort: ReasoningEffort,
|
|
2692
|
+
sourceTurnId: z.string().uuid().nullable(),
|
|
2693
|
+
sourceTurnVersion: z.number().int().positive().nullable(),
|
|
2694
|
+
updatedAt: z.string().nullable()
|
|
2695
|
+
});
|
|
2696
|
+
var SessionQueueSnapshot = z.object({
|
|
2697
|
+
version: z.number().int().nonnegative(),
|
|
2698
|
+
effectiveControl: EffectiveSessionControl,
|
|
2699
|
+
/**
|
|
2700
|
+
* True while the latest attempt is interrupted but has not durably proved
|
|
2701
|
+
* quiescence: no more inference, user-visible output, or workspace-persistence
|
|
2702
|
+
* authority. Temporal cancellation/terminalization is not that proof. This is
|
|
2703
|
+
* distinct from ordinary capacity queueing, remains accurate with an empty
|
|
2704
|
+
* visible queue, and is independent of Steer-row metadata or withdrawal.
|
|
2705
|
+
*/
|
|
2706
|
+
stoppingPreviousAttempt: z.boolean(),
|
|
2707
|
+
items: z.array(SessionTurn)
|
|
2708
|
+
});
|
|
2709
|
+
var MoveSessionQueueItemRequest = z.object({
|
|
2710
|
+
clientEventId: SessionOperationKey,
|
|
2711
|
+
expectedQueueVersion: z.number().int().nonnegative(),
|
|
2712
|
+
beforeTurnId: z.string().uuid().nullable()
|
|
2713
|
+
});
|
|
2714
|
+
var EditSessionQueueItemRequest = z.object({
|
|
2715
|
+
clientEventId: SessionOperationKey,
|
|
2716
|
+
expectedTurnVersion: z.number().int().positive(),
|
|
2717
|
+
expectedDraftRevision: z.number().int().nonnegative(),
|
|
2718
|
+
replaceDraft: z.boolean()
|
|
2719
|
+
});
|
|
2720
|
+
var SteerSessionQueueItemRequest = z.object({
|
|
2721
|
+
clientEventId: SessionOperationKey,
|
|
2722
|
+
expectedTurnVersion: z.number().int().positive(),
|
|
2723
|
+
controlEtag: z.string().min(1).optional()
|
|
2724
|
+
});
|
|
2725
|
+
var DeleteSessionQueueItemRequest = z.object({
|
|
2726
|
+
clientEventId: SessionOperationKey,
|
|
2727
|
+
expectedTurnVersion: z.number().int().positive(),
|
|
2728
|
+
reason: z.string().min(1).optional()
|
|
2729
|
+
});
|
|
2730
|
+
var SaveComposerDraftRequest = ComposerDraft.pick({
|
|
2731
|
+
text: true,
|
|
2732
|
+
resources: true,
|
|
2733
|
+
tools: true,
|
|
2734
|
+
model: true,
|
|
2735
|
+
reasoningEffort: true
|
|
2736
|
+
}).extend({ expectedRevision: z.number().int().nonnegative() });
|
|
2737
|
+
var WORKSPACE_CONTROL_REASON_MAX_BYTES = 8 * 1024;
|
|
2738
|
+
var WORKSPACE_CONTROL_ACTOR_MAX_BYTES = 1024;
|
|
2739
|
+
var WORKSPACE_CONTROL_EVENT_MAX_BYTES = 16 * 1024;
|
|
2740
|
+
var WorkspaceControlReason = z.string().min(1).refine((value) => !value.includes("\0"), "reason must not contain NUL bytes").refine(
|
|
2741
|
+
(value) => workspaceControlUtf8Bytes(value) <= WORKSPACE_CONTROL_REASON_MAX_BYTES,
|
|
2742
|
+
`reason must not exceed ${WORKSPACE_CONTROL_REASON_MAX_BYTES} UTF-8 bytes`
|
|
2743
|
+
);
|
|
2744
|
+
var SessionControlRequest = z.object({
|
|
2745
|
+
action: z.enum(["pause", "resume"]),
|
|
2746
|
+
reason: WorkspaceControlReason.optional(),
|
|
2747
|
+
clientEventId: SessionOperationKey,
|
|
2748
|
+
expectedControlEtag: z.string().min(1).optional()
|
|
2749
|
+
});
|
|
2750
|
+
var WorkspaceInferenceControlRequest = z.object({
|
|
2751
|
+
action: z.enum(["pause", "resume"]),
|
|
2752
|
+
reason: WorkspaceControlReason.optional(),
|
|
2753
|
+
clientEventId: SessionOperationKey,
|
|
2754
|
+
expectedRevision: z.number().int().nonnegative().optional()
|
|
2755
|
+
});
|
|
2756
|
+
var WorkspaceInferenceControlResponse = z.object({
|
|
2757
|
+
receipt: SessionCommandReceipt,
|
|
2758
|
+
state: SessionControlState,
|
|
2759
|
+
revision: z.number().int().nonnegative(),
|
|
2760
|
+
interruptionCount: z.number().int().nonnegative(),
|
|
2761
|
+
wakeCount: z.number().int().nonnegative()
|
|
2762
|
+
});
|
|
2763
|
+
var WorkspaceControlEventTruncation = z.object({
|
|
2764
|
+
truncated: z.literal(true),
|
|
2765
|
+
surface: z.enum([
|
|
2766
|
+
"durable_control",
|
|
2767
|
+
"database_guard",
|
|
2768
|
+
"http_projection",
|
|
2769
|
+
"nats_legacy_guard",
|
|
2770
|
+
"sse_legacy_guard"
|
|
2771
|
+
]),
|
|
2772
|
+
deliveredBytes: z.number().int().nonnegative(),
|
|
2773
|
+
fields: z.array(
|
|
2774
|
+
z.object({
|
|
2775
|
+
field: z.enum(["reason", "actor"]),
|
|
2776
|
+
originalBytes: z.number().int().nonnegative(),
|
|
2777
|
+
deliveredBytes: z.number().int().nonnegative(),
|
|
2778
|
+
omittedBytes: z.number().int().nonnegative()
|
|
2779
|
+
})
|
|
2780
|
+
),
|
|
2781
|
+
fullEvidence: z.object({
|
|
2782
|
+
available: z.literal(false),
|
|
2783
|
+
reason: z.literal("not_retained")
|
|
2784
|
+
})
|
|
2785
|
+
});
|
|
2786
|
+
var WorkspaceControlEvent = z.object({
|
|
2787
|
+
id: z.string().uuid(),
|
|
2788
|
+
workspaceId: z.string().uuid(),
|
|
2789
|
+
sequence: z.number().int().positive(),
|
|
2790
|
+
revision: z.number().int().positive(),
|
|
2791
|
+
type: z.literal("workspace.control.changed"),
|
|
2792
|
+
scope: z.enum(["workspace", "session"]),
|
|
2793
|
+
rootSessionId: z.string().uuid().nullable(),
|
|
2794
|
+
action: z.enum(["pause", "resume"]),
|
|
2795
|
+
automatic: z.boolean(),
|
|
2796
|
+
reason: z.string().nullable(),
|
|
2797
|
+
actor: z.string().min(1),
|
|
2798
|
+
occurredAt: z.string(),
|
|
2799
|
+
truncation: WorkspaceControlEventTruncation.nullable().optional()
|
|
2800
|
+
});
|
|
2801
|
+
function workspaceControlUtf8Bytes(value) {
|
|
2802
|
+
return new TextEncoder().encode(value).byteLength;
|
|
2803
|
+
}
|
|
2804
|
+
function boundWorkspaceControlEvent(event, options = {}) {
|
|
2805
|
+
const existingFields = new Map(
|
|
2806
|
+
(event.truncation?.fields ?? []).map((field) => [field.field, field])
|
|
2807
|
+
);
|
|
2808
|
+
const reason = event.reason === null ? null : boundWorkspaceControlText(event.reason, WORKSPACE_CONTROL_REASON_MAX_BYTES);
|
|
2809
|
+
const actor = boundWorkspaceControlText(event.actor, WORKSPACE_CONTROL_ACTOR_MAX_BYTES);
|
|
2810
|
+
const reasonBytes = reason === null ? 0 : workspaceControlUtf8Bytes(reason);
|
|
2811
|
+
const actorBytes = workspaceControlUtf8Bytes(actor);
|
|
2812
|
+
const reasonOriginalBytes = event.reason === null ? null : Math.max(
|
|
2813
|
+
workspaceControlUtf8Bytes(event.reason),
|
|
2814
|
+
normalizedWorkspaceControlOriginalBytes(options.reasonOriginalBytes),
|
|
2815
|
+
existingFields.get("reason")?.originalBytes ?? 0
|
|
2816
|
+
);
|
|
2817
|
+
const actorOriginalBytes = Math.max(
|
|
2818
|
+
workspaceControlUtf8Bytes(event.actor),
|
|
2819
|
+
normalizedWorkspaceControlOriginalBytes(options.actorOriginalBytes),
|
|
2820
|
+
existingFields.get("actor")?.originalBytes ?? 0
|
|
2821
|
+
);
|
|
2822
|
+
const fields = [];
|
|
2823
|
+
if (reasonOriginalBytes !== null && reasonOriginalBytes > reasonBytes) {
|
|
2824
|
+
fields.push({
|
|
2825
|
+
field: "reason",
|
|
2826
|
+
originalBytes: reasonOriginalBytes,
|
|
2827
|
+
deliveredBytes: reasonBytes,
|
|
2828
|
+
omittedBytes: reasonOriginalBytes - reasonBytes
|
|
2829
|
+
});
|
|
2830
|
+
}
|
|
2831
|
+
if (actorOriginalBytes > actorBytes) {
|
|
2832
|
+
fields.push({
|
|
2833
|
+
field: "actor",
|
|
2834
|
+
originalBytes: actorOriginalBytes,
|
|
2835
|
+
deliveredBytes: actorBytes,
|
|
2836
|
+
omittedBytes: actorOriginalBytes - actorBytes
|
|
2837
|
+
});
|
|
2838
|
+
}
|
|
2839
|
+
if (fields.length === 0 && event.truncation == null) {
|
|
2840
|
+
if (sessionEventJsonBytes(event) > WORKSPACE_CONTROL_EVENT_MAX_BYTES) {
|
|
2841
|
+
throw new RangeError("Workspace control event exceeds its bounded envelope");
|
|
2842
|
+
}
|
|
2843
|
+
return event;
|
|
2844
|
+
}
|
|
2845
|
+
const truncation = {
|
|
2846
|
+
truncated: true,
|
|
2847
|
+
surface: event.truncation?.surface ?? options.surface ?? "durable_control",
|
|
2848
|
+
deliveredBytes: 0,
|
|
2849
|
+
fields,
|
|
2850
|
+
fullEvidence: { available: false, reason: "not_retained" }
|
|
2851
|
+
};
|
|
2852
|
+
const bounded = {
|
|
2853
|
+
...event,
|
|
2854
|
+
reason,
|
|
2855
|
+
actor,
|
|
2856
|
+
truncation
|
|
2857
|
+
};
|
|
2858
|
+
settleWorkspaceControlDeliveredBytes(bounded, truncation);
|
|
2859
|
+
const deliveredBytes = sessionEventJsonBytes(bounded);
|
|
2860
|
+
if (deliveredBytes > WORKSPACE_CONTROL_EVENT_MAX_BYTES) {
|
|
2861
|
+
throw new RangeError(
|
|
2862
|
+
`Bounded workspace control event exceeds its final envelope (${deliveredBytes} > ${WORKSPACE_CONTROL_EVENT_MAX_BYTES} bytes)`
|
|
2863
|
+
);
|
|
2864
|
+
}
|
|
2865
|
+
return bounded;
|
|
2866
|
+
}
|
|
2867
|
+
function boundWorkspaceControlText(value, maxBytes) {
|
|
2868
|
+
const encoder2 = new TextEncoder();
|
|
2869
|
+
const decoder = new TextDecoder();
|
|
2870
|
+
const bytes = encoder2.encode(value);
|
|
2871
|
+
if (bytes.byteLength <= maxBytes) return value;
|
|
2872
|
+
const marker = "\u2026[truncated]";
|
|
2873
|
+
const prefixBudget = Math.max(0, maxBytes - encoder2.encode(marker).byteLength);
|
|
2874
|
+
let prefixEnd = Math.min(prefixBudget, bytes.byteLength);
|
|
2875
|
+
while (prefixEnd > 0 && prefixEnd < bytes.byteLength && (bytes[prefixEnd] & 192) === 128) {
|
|
2876
|
+
prefixEnd -= 1;
|
|
2877
|
+
}
|
|
2878
|
+
return `${decoder.decode(bytes.subarray(0, prefixEnd))}${marker}`;
|
|
2879
|
+
}
|
|
2880
|
+
function normalizedWorkspaceControlOriginalBytes(value) {
|
|
2881
|
+
return value === null || value === void 0 || !Number.isFinite(value) ? 0 : Math.max(0, Math.floor(value));
|
|
2882
|
+
}
|
|
2883
|
+
function settleWorkspaceControlDeliveredBytes(event, truncation) {
|
|
2884
|
+
for (let attempt = 0; attempt < 16; attempt += 1) {
|
|
2885
|
+
const deliveredBytes2 = sessionEventJsonBytes(event);
|
|
2886
|
+
if (truncation.deliveredBytes === deliveredBytes2) return;
|
|
2887
|
+
truncation.deliveredBytes = deliveredBytes2;
|
|
2888
|
+
}
|
|
2889
|
+
const deliveredBytes = sessionEventJsonBytes(event);
|
|
2890
|
+
if (truncation.deliveredBytes !== deliveredBytes) {
|
|
2891
|
+
throw new RangeError("Workspace control event byte accounting did not converge");
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
var SystemUpdateClassification = z.enum(["success", "failure", "action_required", "info"]);
|
|
2895
|
+
var SessionSystemUpdateKind = z.enum([
|
|
2896
|
+
"scheduled_occurrence",
|
|
2897
|
+
"goal_continuation",
|
|
2898
|
+
"agent_message",
|
|
2899
|
+
"agent_steer_instruction",
|
|
2900
|
+
"child_terminal_result"
|
|
2901
|
+
]);
|
|
2902
|
+
var SessionSystemUpdatePayload = z.discriminatedUnion("type", [
|
|
2903
|
+
z.object({
|
|
2904
|
+
type: z.literal("scheduled_occurrence"),
|
|
2905
|
+
text: z.string().min(1),
|
|
2906
|
+
scheduledTaskId: z.string().uuid(),
|
|
2907
|
+
scheduledTaskRunId: z.string().uuid(),
|
|
2908
|
+
resources: z.array(ResourceRef).optional(),
|
|
2909
|
+
tools: z.array(ToolRef).optional()
|
|
2910
|
+
}).passthrough(),
|
|
2911
|
+
z.object({
|
|
2912
|
+
type: z.literal("goal_continuation"),
|
|
2913
|
+
goalId: z.string().uuid(),
|
|
2914
|
+
goalVersion: z.number().int().positive(),
|
|
2915
|
+
prompt: z.string().min(1),
|
|
2916
|
+
reason: z.string().optional()
|
|
2917
|
+
}).passthrough(),
|
|
2918
|
+
z.object({
|
|
2919
|
+
type: z.literal("agent_message"),
|
|
2920
|
+
text: z.string().min(1),
|
|
2921
|
+
operationId: z.string().uuid()
|
|
2922
|
+
}).passthrough(),
|
|
2923
|
+
z.object({
|
|
2924
|
+
type: z.literal("agent_steer_instruction"),
|
|
2925
|
+
instruction: z.string().min(1),
|
|
2926
|
+
operationId: z.string().uuid()
|
|
2927
|
+
}).passthrough(),
|
|
2928
|
+
z.object({
|
|
2929
|
+
type: z.literal("child_terminal_result"),
|
|
2930
|
+
childSessionId: z.string().uuid(),
|
|
2931
|
+
status: z.enum(["idle", "failed"])
|
|
2932
|
+
}).passthrough()
|
|
2933
|
+
]);
|
|
2934
|
+
var SessionSystemUpdateState = z.enum([
|
|
2935
|
+
"pending",
|
|
2936
|
+
"deferred",
|
|
2937
|
+
"delivered",
|
|
2938
|
+
"cancelled",
|
|
2939
|
+
"superseded",
|
|
2940
|
+
"failed"
|
|
2941
|
+
]);
|
|
2942
|
+
var SessionSystemUpdate = z.object({
|
|
2943
|
+
id: z.string().uuid(),
|
|
2944
|
+
sessionId: z.string().uuid(),
|
|
2945
|
+
kind: SessionSystemUpdateKind,
|
|
2946
|
+
classification: SystemUpdateClassification,
|
|
2947
|
+
sourceId: z.string(),
|
|
2948
|
+
dedupeKey: z.string(),
|
|
2949
|
+
summary: z.string(),
|
|
2950
|
+
payload: SessionSystemUpdatePayload,
|
|
2951
|
+
lineage: z.record(z.string(), z.unknown()),
|
|
2952
|
+
state: SessionSystemUpdateState,
|
|
2953
|
+
deliveredTurnId: z.string().uuid().nullable(),
|
|
2954
|
+
deliveredAt: z.string().nullable(),
|
|
2955
|
+
createdAt: z.string()
|
|
1251
2956
|
});
|
|
1252
|
-
var
|
|
1253
|
-
|
|
1254
|
-
|
|
2957
|
+
var VariableSetVariableName = z.string().regex(/^[A-Z][A-Z0-9_]*$/).max(128);
|
|
2958
|
+
function withVariableSetIdAlias(shape) {
|
|
2959
|
+
return z.preprocess((input) => {
|
|
2960
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
2961
|
+
return input;
|
|
2962
|
+
}
|
|
2963
|
+
const record = input;
|
|
2964
|
+
if (record.variableSetId !== void 0 || record.environmentId === void 0) {
|
|
2965
|
+
return record;
|
|
2966
|
+
}
|
|
2967
|
+
return { ...record, variableSetId: record.environmentId };
|
|
2968
|
+
}, z.object(shape));
|
|
2969
|
+
}
|
|
2970
|
+
var VariableSetVariableMetadata = z.object({
|
|
2971
|
+
name: VariableSetVariableName,
|
|
1255
2972
|
version: z.number().int().positive(),
|
|
1256
2973
|
createdAt: z.string(),
|
|
1257
2974
|
updatedAt: z.string()
|
|
1258
2975
|
});
|
|
1259
|
-
var
|
|
2976
|
+
var WorkspaceEnvironmentVariableMetadata = VariableSetVariableMetadata;
|
|
2977
|
+
var VariableSet = z.object({
|
|
1260
2978
|
id: z.string().uuid(),
|
|
1261
2979
|
accountId: z.string().uuid(),
|
|
1262
2980
|
workspaceId: z.string().uuid(),
|
|
1263
2981
|
name: z.string(),
|
|
1264
2982
|
description: z.string().nullable(),
|
|
1265
|
-
variables: z.array(
|
|
2983
|
+
variables: z.array(VariableSetVariableMetadata),
|
|
1266
2984
|
createdAt: z.string(),
|
|
1267
2985
|
updatedAt: z.string()
|
|
1268
2986
|
});
|
|
1269
|
-
var
|
|
2987
|
+
var WorkspaceEnvironment = VariableSet;
|
|
2988
|
+
var CreateVariableSetRequest = z.object({
|
|
1270
2989
|
name: z.string().min(1).max(120),
|
|
1271
2990
|
description: z.string().max(2e3).optional(),
|
|
1272
|
-
variables: z.array(
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
2991
|
+
variables: z.array(
|
|
2992
|
+
z.object({
|
|
2993
|
+
name: VariableSetVariableName,
|
|
2994
|
+
value: z.string().min(1).max(32768)
|
|
2995
|
+
})
|
|
2996
|
+
).default([])
|
|
1276
2997
|
});
|
|
1277
|
-
var
|
|
2998
|
+
var CreateWorkspaceEnvironmentRequest = CreateVariableSetRequest;
|
|
2999
|
+
var UpdateVariableSetRequest = z.object({
|
|
1278
3000
|
name: z.string().min(1).max(120).optional(),
|
|
1279
3001
|
description: z.string().max(2e3).nullable().optional()
|
|
1280
3002
|
});
|
|
1281
|
-
var
|
|
3003
|
+
var UpdateWorkspaceEnvironmentRequest = UpdateVariableSetRequest;
|
|
3004
|
+
var SetVariableSetVariableRequest = z.object({
|
|
1282
3005
|
value: z.string().min(1).max(32768)
|
|
1283
3006
|
});
|
|
3007
|
+
var SetWorkspaceEnvironmentVariableRequest = SetVariableSetVariableRequest;
|
|
3008
|
+
var RigCheck = z.object({
|
|
3009
|
+
name: z.string().min(1).max(120),
|
|
3010
|
+
command: z.string().min(1).max(8192)
|
|
3011
|
+
});
|
|
3012
|
+
var RigVersion = z.object({
|
|
3013
|
+
id: z.string().uuid(),
|
|
3014
|
+
rigId: z.string().uuid(),
|
|
3015
|
+
version: z.number().int().positive(),
|
|
3016
|
+
image: z.string().nullable(),
|
|
3017
|
+
setupScript: z.string().nullable(),
|
|
3018
|
+
checks: z.array(RigCheck),
|
|
3019
|
+
credentialHooks: z.array(z.string()),
|
|
3020
|
+
defaultVariableSetIds: z.array(z.string().uuid()),
|
|
3021
|
+
changelog: z.string().nullable(),
|
|
3022
|
+
// Attribution: 'user:<subject>' | 'session:<id>' | 'system'.
|
|
3023
|
+
createdBy: z.string().nullable(),
|
|
3024
|
+
active: z.boolean(),
|
|
3025
|
+
createdAt: z.string()
|
|
3026
|
+
});
|
|
3027
|
+
var RigVerificationHealth = z.object({
|
|
3028
|
+
checkHealth: z.enum(["passing", "failing", "unknown"]),
|
|
3029
|
+
lastVerifiedAt: z.string().nullable()
|
|
3030
|
+
});
|
|
3031
|
+
var Rig = z.object({
|
|
3032
|
+
id: z.string().uuid(),
|
|
3033
|
+
accountId: z.string().uuid(),
|
|
3034
|
+
workspaceId: z.string().uuid(),
|
|
3035
|
+
name: z.string(),
|
|
3036
|
+
description: z.string().nullable(),
|
|
3037
|
+
createdBy: z.string().nullable(),
|
|
3038
|
+
// The rig's currently-active version (present after create; nullable so a
|
|
3039
|
+
// partial/list read can omit it without a schema change).
|
|
3040
|
+
activeVersion: RigVersion.nullable(),
|
|
3041
|
+
// Summary for the currently active version. null only when there is no active
|
|
3042
|
+
// version; otherwise "unknown" means the active version has no verification.
|
|
3043
|
+
activeVersionHealth: RigVerificationHealth.nullable(),
|
|
3044
|
+
versionCount: z.number().int().nonnegative(),
|
|
3045
|
+
createdAt: z.string(),
|
|
3046
|
+
updatedAt: z.string()
|
|
3047
|
+
});
|
|
3048
|
+
var RigChangeKind = z.enum(["setup_append", "definition_edit"]);
|
|
3049
|
+
var RigChangeStatus = z.enum(["proposed", "verifying", "merged", "rejected", "failed"]);
|
|
3050
|
+
var RigCheckResult = z.object({
|
|
3051
|
+
name: z.string(),
|
|
3052
|
+
command: z.string(),
|
|
3053
|
+
exitCode: z.number().int().nullable(),
|
|
3054
|
+
output: z.string().optional()
|
|
3055
|
+
});
|
|
3056
|
+
var RigChangeVerification = z.object({
|
|
3057
|
+
startedAt: z.string().optional(),
|
|
3058
|
+
finishedAt: z.string().optional(),
|
|
3059
|
+
log: z.string().optional(),
|
|
3060
|
+
checkResults: z.array(RigCheckResult).optional()
|
|
3061
|
+
}).passthrough();
|
|
3062
|
+
var RigChange = z.object({
|
|
3063
|
+
id: z.string().uuid(),
|
|
3064
|
+
rigId: z.string().uuid(),
|
|
3065
|
+
baseVersionId: z.string().uuid().nullable(),
|
|
3066
|
+
kind: RigChangeKind,
|
|
3067
|
+
payload: z.record(z.string(), z.unknown()),
|
|
3068
|
+
status: RigChangeStatus,
|
|
3069
|
+
proposedBy: z.string().nullable(),
|
|
3070
|
+
verification: RigChangeVerification.nullable(),
|
|
3071
|
+
resultVersionId: z.string().uuid().nullable(),
|
|
3072
|
+
createdAt: z.string(),
|
|
3073
|
+
updatedAt: z.string()
|
|
3074
|
+
});
|
|
3075
|
+
var CreateRigRequest = z.object({
|
|
3076
|
+
name: z.string().min(1).max(120),
|
|
3077
|
+
description: z.string().max(2e3).optional(),
|
|
3078
|
+
// Initial (version 1) content, inline.
|
|
3079
|
+
image: z.string().max(1024).optional(),
|
|
3080
|
+
setupScript: z.string().max(131072).optional(),
|
|
3081
|
+
checks: z.array(RigCheck).max(100).default([]),
|
|
3082
|
+
credentialHooks: z.array(z.string().min(1).max(200)).max(50).default([]),
|
|
3083
|
+
defaultVariableSetIds: z.array(z.string().uuid()).max(25).default([])
|
|
3084
|
+
});
|
|
3085
|
+
var UpdateRigRequest = z.object({
|
|
3086
|
+
name: z.string().min(1).max(120).optional(),
|
|
3087
|
+
description: z.string().max(2e3).nullable().optional()
|
|
3088
|
+
});
|
|
3089
|
+
var RigSetupAppendPayload = z.object({
|
|
3090
|
+
command: z.string().min(1).max(8192),
|
|
3091
|
+
note: z.string().max(2e3).optional()
|
|
3092
|
+
});
|
|
3093
|
+
var RigDefinitionEditPayload = z.object({
|
|
3094
|
+
image: z.string().max(1024).nullish(),
|
|
3095
|
+
setupScript: z.string().max(131072).nullish(),
|
|
3096
|
+
checks: z.array(RigCheck).max(100).optional(),
|
|
3097
|
+
credentialHooks: z.array(z.string().min(1).max(200)).max(50).optional(),
|
|
3098
|
+
defaultVariableSetIds: z.array(z.string().uuid()).max(25).optional(),
|
|
3099
|
+
changelog: z.string().max(4096).nullish()
|
|
3100
|
+
});
|
|
3101
|
+
var ProposeRigChangeRequest = z.discriminatedUnion("kind", [
|
|
3102
|
+
z.object({ kind: z.literal("setup_append"), payload: RigSetupAppendPayload }),
|
|
3103
|
+
z.object({
|
|
3104
|
+
kind: z.literal("definition_edit"),
|
|
3105
|
+
payload: RigDefinitionEditPayload
|
|
3106
|
+
})
|
|
3107
|
+
]);
|
|
1284
3108
|
var ScheduledTaskStatus = z.enum(["active", "paused"]);
|
|
1285
3109
|
var ScheduledTaskRunStatus = z.enum(["queued", "dispatched", "failed"]);
|
|
1286
3110
|
var ScheduledTaskRunMode = z.enum(["new_session_per_run", "reusable_session"]);
|
|
@@ -1328,7 +3152,13 @@ var ScheduledTask = z.object({
|
|
|
1328
3152
|
overlapPolicy: ScheduledTaskOverlapPolicy,
|
|
1329
3153
|
agentConfig: ScheduledTaskAgentConfig,
|
|
1330
3154
|
reusableSessionId: z.string().uuid().nullable(),
|
|
1331
|
-
|
|
3155
|
+
variableSetId: z.string().uuid().nullable().default(null),
|
|
3156
|
+
/** @deprecated use variableSetId */
|
|
3157
|
+
environmentId: z.string().uuid().nullable().default(null),
|
|
3158
|
+
// The rig each run binds to (M3). Stored on the task; the ACTIVE version is
|
|
3159
|
+
// resolved PER FIRE (at dispatch), so a task always runs the rig's current
|
|
3160
|
+
// version rather than one frozen at task-create time. Null ⇒ rig-less runs.
|
|
3161
|
+
rigId: z.string().uuid().nullable().default(null),
|
|
1332
3162
|
metadata: z.record(z.string(), z.unknown()),
|
|
1333
3163
|
createdAt: z.string(),
|
|
1334
3164
|
updatedAt: z.string()
|
|
@@ -1348,24 +3178,31 @@ var ScheduledTaskRun = z.object({
|
|
|
1348
3178
|
createdAt: z.string(),
|
|
1349
3179
|
updatedAt: z.string()
|
|
1350
3180
|
});
|
|
1351
|
-
var CreateScheduledTaskRequest =
|
|
3181
|
+
var CreateScheduledTaskRequest = withVariableSetIdAlias({
|
|
1352
3182
|
name: z.string().min(1),
|
|
1353
3183
|
schedule: ScheduledTaskScheduleSpec,
|
|
1354
3184
|
runMode: ScheduledTaskRunMode.default("new_session_per_run"),
|
|
1355
3185
|
overlapPolicy: ScheduledTaskOverlapPolicy.default("allow_concurrent"),
|
|
1356
3186
|
agentConfig: ScheduledTaskAgentConfig,
|
|
1357
3187
|
status: ScheduledTaskStatus.default("active"),
|
|
3188
|
+
variableSetId: z.string().uuid().nullable().optional(),
|
|
1358
3189
|
environmentId: z.string().uuid().nullable().optional(),
|
|
3190
|
+
// The rig each run binds to (M3); its active version is resolved per fire.
|
|
3191
|
+
rigId: z.string().uuid().nullable().optional(),
|
|
1359
3192
|
metadata: z.record(z.string(), z.unknown()).default({})
|
|
1360
3193
|
});
|
|
1361
|
-
var UpdateScheduledTaskRequest =
|
|
3194
|
+
var UpdateScheduledTaskRequest = withVariableSetIdAlias({
|
|
1362
3195
|
name: z.string().min(1).optional(),
|
|
1363
3196
|
schedule: ScheduledTaskScheduleSpec.optional(),
|
|
1364
3197
|
runMode: ScheduledTaskRunMode.optional(),
|
|
1365
3198
|
overlapPolicy: ScheduledTaskOverlapPolicy.optional(),
|
|
1366
3199
|
agentConfig: ScheduledTaskAgentConfig.optional(),
|
|
1367
3200
|
status: ScheduledTaskStatus.optional(),
|
|
3201
|
+
variableSetId: z.string().uuid().nullable().optional(),
|
|
1368
3202
|
environmentId: z.string().uuid().nullable().optional(),
|
|
3203
|
+
// The rig each run binds to (M3); null clears it. Its active version is
|
|
3204
|
+
// resolved per fire, so an update takes effect on the next dispatch.
|
|
3205
|
+
rigId: z.string().uuid().nullable().optional(),
|
|
1369
3206
|
metadata: z.record(z.string(), z.unknown()).optional()
|
|
1370
3207
|
});
|
|
1371
3208
|
var TriggerScheduledTaskRequest = z.object({
|
|
@@ -1421,12 +3258,20 @@ var CapabilityPackSkill = z.object({
|
|
|
1421
3258
|
const seen = /* @__PURE__ */ new Set();
|
|
1422
3259
|
skill.files.forEach((file, index) => {
|
|
1423
3260
|
if (seen.has(file.path)) {
|
|
1424
|
-
ctx.addIssue({
|
|
3261
|
+
ctx.addIssue({
|
|
3262
|
+
code: "custom",
|
|
3263
|
+
message: `duplicate skill file path: ${file.path}`,
|
|
3264
|
+
path: ["files", index, "path"]
|
|
3265
|
+
});
|
|
1425
3266
|
}
|
|
1426
3267
|
seen.add(file.path);
|
|
1427
3268
|
});
|
|
1428
3269
|
if (!skill.files.some((file) => file.path === "SKILL.md")) {
|
|
1429
|
-
ctx.addIssue({
|
|
3270
|
+
ctx.addIssue({
|
|
3271
|
+
code: "custom",
|
|
3272
|
+
message: "skill must include a top-level SKILL.md file",
|
|
3273
|
+
path: ["files"]
|
|
3274
|
+
});
|
|
1430
3275
|
}
|
|
1431
3276
|
});
|
|
1432
3277
|
function isSafePackSkillRelativePath(path) {
|
|
@@ -1435,39 +3280,71 @@ function isSafePackSkillRelativePath(path) {
|
|
|
1435
3280
|
}
|
|
1436
3281
|
return path.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
|
|
1437
3282
|
}
|
|
1438
|
-
var
|
|
1439
|
-
id: z.string().min(1),
|
|
1440
|
-
name: z.string().min(1),
|
|
3283
|
+
var CapabilityPackVariableSet = z.object({
|
|
1441
3284
|
description: z.string().min(1),
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
version: z.string().min(1),
|
|
1445
|
-
// Container image ref (digest-pinned recommended) the pack's sessions run
|
|
1446
|
-
// in. At most one enabled pack per workspace may declare one; with none,
|
|
1447
|
-
// sessions use the deployment-wide image settings.
|
|
1448
|
-
sandboxImage: z.string().trim().min(1).max(512).optional(),
|
|
1449
|
-
// Skills delivered into the sandbox skill index when the pack is enabled.
|
|
1450
|
-
skills: z.array(CapabilityPackSkill).max(32).superRefine((skills, ctx) => {
|
|
1451
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1452
|
-
skills.forEach((skill, index) => {
|
|
1453
|
-
const key = skill.name.toLowerCase();
|
|
1454
|
-
if (seen.has(key)) {
|
|
1455
|
-
ctx.addIssue({ code: "custom", message: `duplicate pack skill name: ${skill.name}`, path: [index, "name"] });
|
|
1456
|
-
}
|
|
1457
|
-
seen.add(key);
|
|
1458
|
-
});
|
|
1459
|
-
}).default([]),
|
|
1460
|
-
tools: z.array(ToolRef).default([]),
|
|
1461
|
-
connectors: z.array(CapabilityPackConnector).default([]),
|
|
1462
|
-
knowledge: z.array(CapabilityPackKnowledge).default([]),
|
|
1463
|
-
scheduledTaskTemplates: z.array(CapabilityPackScheduledTaskTemplate).default([]),
|
|
1464
|
-
environment: z.object({
|
|
1465
|
-
description: z.string().min(1),
|
|
1466
|
-
requiredVariables: z.array(WorkspaceEnvironmentVariableName).default([]),
|
|
1467
|
-
required: z.boolean().default(false)
|
|
1468
|
-
}).optional(),
|
|
1469
|
-
metadata: z.record(z.string(), z.unknown()).default({})
|
|
3285
|
+
requiredVariables: z.array(VariableSetVariableName).default([]),
|
|
3286
|
+
required: z.boolean().default(false)
|
|
1470
3287
|
});
|
|
3288
|
+
var CapabilityPack = z.preprocess(
|
|
3289
|
+
(input) => {
|
|
3290
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
3291
|
+
return input;
|
|
3292
|
+
}
|
|
3293
|
+
const record = input;
|
|
3294
|
+
if (record.variableSet !== void 0) {
|
|
3295
|
+
return record;
|
|
3296
|
+
}
|
|
3297
|
+
if (record.environment !== void 0) {
|
|
3298
|
+
const { environment: _environment, ...rest } = record;
|
|
3299
|
+
return { ...rest, variableSet: record.environment };
|
|
3300
|
+
}
|
|
3301
|
+
if (record.requiredVariables !== void 0) {
|
|
3302
|
+
const { requiredVariables: _requiredVariables, ...rest } = record;
|
|
3303
|
+
return {
|
|
3304
|
+
...rest,
|
|
3305
|
+
variableSet: {
|
|
3306
|
+
description: "Required variables",
|
|
3307
|
+
requiredVariables: record.requiredVariables,
|
|
3308
|
+
required: Array.isArray(record.requiredVariables) && record.requiredVariables.length > 0
|
|
3309
|
+
}
|
|
3310
|
+
};
|
|
3311
|
+
}
|
|
3312
|
+
return record;
|
|
3313
|
+
},
|
|
3314
|
+
z.object({
|
|
3315
|
+
id: z.string().min(1),
|
|
3316
|
+
name: z.string().min(1),
|
|
3317
|
+
description: z.string().min(1),
|
|
3318
|
+
role: z.string().min(1),
|
|
3319
|
+
category: z.string().min(1),
|
|
3320
|
+
version: z.string().min(1),
|
|
3321
|
+
// Container image ref (digest-pinned recommended) the pack's sessions run
|
|
3322
|
+
// in. At most one enabled pack per workspace may declare one; with none,
|
|
3323
|
+
// sessions use the deployment-wide image settings.
|
|
3324
|
+
sandboxImage: z.string().trim().min(1).max(512).optional(),
|
|
3325
|
+
// Skills delivered into the sandbox skill index when the pack is enabled.
|
|
3326
|
+
skills: z.array(CapabilityPackSkill).max(32).superRefine((skills, ctx) => {
|
|
3327
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3328
|
+
skills.forEach((skill, index) => {
|
|
3329
|
+
const key = skill.name.toLowerCase();
|
|
3330
|
+
if (seen.has(key)) {
|
|
3331
|
+
ctx.addIssue({
|
|
3332
|
+
code: "custom",
|
|
3333
|
+
message: `duplicate pack skill name: ${skill.name}`,
|
|
3334
|
+
path: [index, "name"]
|
|
3335
|
+
});
|
|
3336
|
+
}
|
|
3337
|
+
seen.add(key);
|
|
3338
|
+
});
|
|
3339
|
+
}).default([]),
|
|
3340
|
+
tools: z.array(ToolRef).default([]),
|
|
3341
|
+
connectors: z.array(CapabilityPackConnector).default([]),
|
|
3342
|
+
knowledge: z.array(CapabilityPackKnowledge).default([]),
|
|
3343
|
+
scheduledTaskTemplates: z.array(CapabilityPackScheduledTaskTemplate).default([]),
|
|
3344
|
+
variableSet: CapabilityPackVariableSet.optional(),
|
|
3345
|
+
metadata: z.record(z.string(), z.unknown()).default({})
|
|
3346
|
+
})
|
|
3347
|
+
);
|
|
1471
3348
|
var RegisterCapabilityPackRequest = CapabilityPack;
|
|
1472
3349
|
var WorkspaceRegisteredPack = z.object({
|
|
1473
3350
|
accountId: z.string().uuid(),
|
|
@@ -1487,7 +3364,8 @@ var PackInstallation = z.object({
|
|
|
1487
3364
|
enabledAt: z.string(),
|
|
1488
3365
|
updatedAt: z.string()
|
|
1489
3366
|
});
|
|
1490
|
-
var EnablePackRequest =
|
|
3367
|
+
var EnablePackRequest = withVariableSetIdAlias({
|
|
3368
|
+
variableSetId: z.string().uuid().optional(),
|
|
1491
3369
|
environmentId: z.string().uuid().optional(),
|
|
1492
3370
|
metadata: z.record(z.string(), z.unknown()).default({})
|
|
1493
3371
|
});
|
|
@@ -1555,14 +3433,6 @@ var CreateSocialPostRequest = z.object({
|
|
|
1555
3433
|
});
|
|
1556
3434
|
var ConnectionKind = z.enum(["oauth2", "api_key", "app_install", "delegated"]);
|
|
1557
3435
|
var ConnectionStatus = z.enum(["active", "needs_reauth", "revoked", "error"]);
|
|
1558
|
-
var McpServerConnectionRef = z.object({
|
|
1559
|
-
connectionId: z.string().uuid().optional(),
|
|
1560
|
-
providerDomain: z.string().min(1),
|
|
1561
|
-
kind: ConnectionKind.optional(),
|
|
1562
|
-
scopes: z.array(z.string().min(1)).optional(),
|
|
1563
|
-
resource: z.string().min(1).optional(),
|
|
1564
|
-
subjectScope: z.enum(["workspace", "subject"]).optional()
|
|
1565
|
-
}).strict();
|
|
1566
3436
|
var ConnectionMetadata = z.object({
|
|
1567
3437
|
id: z.string().uuid(),
|
|
1568
3438
|
accountId: z.string().uuid(),
|
|
@@ -1615,7 +3485,12 @@ var OAuthStartRequest = z.object({
|
|
|
1615
3485
|
resource: z.string().url().optional(),
|
|
1616
3486
|
requestedScopes: z.array(z.string().min(1)).default([]),
|
|
1617
3487
|
returnPath: z.string().min(1).optional(),
|
|
1618
|
-
connectionId: z.string().uuid().optional()
|
|
3488
|
+
connectionId: z.string().uuid().optional(),
|
|
3489
|
+
oauthClient: z.object({
|
|
3490
|
+
clientId: z.string().min(1),
|
|
3491
|
+
clientSecret: z.string().min(1).optional(),
|
|
3492
|
+
tokenEndpointAuthMethod: z.enum(["none", "client_secret_post", "client_secret_basic"]).optional()
|
|
3493
|
+
}).optional()
|
|
1619
3494
|
}).refine((value) => Boolean(value.mcpUrl ?? value.resource), {
|
|
1620
3495
|
message: "mcpUrl is required",
|
|
1621
3496
|
path: ["mcpUrl"]
|
|
@@ -1646,7 +3521,14 @@ var MarketingDailyAnalysisTaskRequest = z.object({
|
|
|
1646
3521
|
overlapPolicy: ScheduledTaskOverlapPolicy.default("skip")
|
|
1647
3522
|
});
|
|
1648
3523
|
var CapabilityKind = z.enum(["pack", "mcp", "api", "skill", "plugin"]);
|
|
1649
|
-
var CapabilitySource = z.enum([
|
|
3524
|
+
var CapabilitySource = z.enum([
|
|
3525
|
+
"built_in",
|
|
3526
|
+
"library",
|
|
3527
|
+
"configured",
|
|
3528
|
+
"public_registry",
|
|
3529
|
+
"registry",
|
|
3530
|
+
"manual"
|
|
3531
|
+
]);
|
|
1650
3532
|
var CapabilityInstallationStatus = z.enum(["active", "disabled"]);
|
|
1651
3533
|
var CapabilityCatalogAuthKind = z.enum(["oauth2", "api_key", "none", "unknown"]);
|
|
1652
3534
|
var CapabilityCatalogTier = z.enum(["verified", "community"]);
|
|
@@ -1686,6 +3568,15 @@ var CapabilityCatalogItem = z.object({
|
|
|
1686
3568
|
runtime: CapabilityRuntime.default({ available: false, notes: null }),
|
|
1687
3569
|
enabled: z.boolean().default(false),
|
|
1688
3570
|
enabledReason: z.string().nullable().default(null),
|
|
3571
|
+
// The connection backing this enabled installation, when the enable-time
|
|
3572
|
+
// connectionRef resolved to one (null for header/credential-free items —
|
|
3573
|
+
// that means "no connection involved", not "broken"). Lets the UI match
|
|
3574
|
+
// connection health by id instead of guessing from providerDomain alone.
|
|
3575
|
+
connectionRef: z.object({
|
|
3576
|
+
connectionId: z.string().min(1),
|
|
3577
|
+
providerDomain: z.string().min(1),
|
|
3578
|
+
kind: z.string().min(1)
|
|
3579
|
+
}).nullable().default(null),
|
|
1689
3580
|
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
1690
3581
|
createdAt: z.string().optional(),
|
|
1691
3582
|
updatedAt: z.string().optional()
|
|
@@ -1716,23 +3607,24 @@ var CreateCapabilityCatalogItemRequest = z.object({
|
|
|
1716
3607
|
authModel: z.string().min(1).optional(),
|
|
1717
3608
|
metadata: z.record(z.string(), z.unknown()).default({})
|
|
1718
3609
|
});
|
|
1719
|
-
var EnableCapabilityRequest =
|
|
3610
|
+
var EnableCapabilityRequest = withVariableSetIdAlias({
|
|
1720
3611
|
config: z.record(z.string(), z.unknown()).default({}),
|
|
1721
3612
|
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
1722
3613
|
connectionRef: McpServerConnectionRef.optional(),
|
|
1723
3614
|
/**
|
|
1724
3615
|
* Credential headers for remote MCP capabilities (for example an
|
|
1725
3616
|
* Authorization bearer token). Values are encrypted at rest with the
|
|
1726
|
-
* workspace-
|
|
3617
|
+
* workspace-variable-sets key, injected only into the runtime MCP client,
|
|
1727
3618
|
* and never returned by the API — responses expose header names only.
|
|
1728
3619
|
*/
|
|
1729
3620
|
headers: z.record(z.string(), z.string()).default({}),
|
|
1730
3621
|
/**
|
|
1731
|
-
* Initial
|
|
3622
|
+
* Initial variableSet attachment for kind=pack capabilities. Mirrors the
|
|
1732
3623
|
* dedicated POST /packs/:id/enable body: required to enable an
|
|
1733
|
-
*
|
|
3624
|
+
* variableSet.required pack through the unified capability-enable path,
|
|
1734
3625
|
* optional otherwise. Ignored by non-pack capabilities.
|
|
1735
3626
|
*/
|
|
3627
|
+
variableSetId: z.string().uuid().optional(),
|
|
1736
3628
|
environmentId: z.string().uuid().optional()
|
|
1737
3629
|
});
|
|
1738
3630
|
var CapabilityCatalogResponse = z.object({
|
|
@@ -1759,6 +3651,9 @@ var Session = z.object({
|
|
|
1759
3651
|
resources: z.array(ResourceRef),
|
|
1760
3652
|
tools: z.array(ToolRef),
|
|
1761
3653
|
metadata: z.record(z.string(), z.unknown()),
|
|
3654
|
+
/** Frozen creator fact used only for creation attribution/idempotent repair. */
|
|
3655
|
+
createdBy: TurnInitiator,
|
|
3656
|
+
createdByContext: TurnInitiatorContext,
|
|
1762
3657
|
model: z.string(),
|
|
1763
3658
|
sandboxBackend: SandboxBackend,
|
|
1764
3659
|
// The OS the session's box runs. Defaults to 'linux' (today's only OS).
|
|
@@ -1774,7 +3669,16 @@ var Session = z.object({
|
|
|
1774
3669
|
// stale in-flight op and retry against the new active sandbox.
|
|
1775
3670
|
activeSandboxId: z.string().uuid().nullable(),
|
|
1776
3671
|
activeEpoch: z.number().int().nonnegative(),
|
|
1777
|
-
|
|
3672
|
+
variableSetId: z.string().uuid().nullable().default(null),
|
|
3673
|
+
/** @deprecated use variableSetId */
|
|
3674
|
+
environmentId: z.string().uuid().nullable().default(null),
|
|
3675
|
+
// The rig this session rides (M3 runtime binding). Both are resolved and
|
|
3676
|
+
// FROZEN at session create: rigId names the rig, rigVersionId pins the exact
|
|
3677
|
+
// active version the session's box/env/setup/doctrine are built from for the
|
|
3678
|
+
// session's whole life (a later promote does NOT move an existing session).
|
|
3679
|
+
// Both null ⇒ a rig-less session (byte-for-byte today's behavior).
|
|
3680
|
+
rigId: z.string().uuid().nullable().default(null),
|
|
3681
|
+
rigVersionId: z.string().uuid().nullable().default(null),
|
|
1778
3682
|
// Non-default first-party MCP token permissions (manager-style sessions);
|
|
1779
3683
|
// null means the fixed worker default set.
|
|
1780
3684
|
firstPartyMcpPermissions: z.array(Permission).nullable(),
|
|
@@ -1793,9 +3697,13 @@ var Session = z.object({
|
|
|
1793
3697
|
temporalWorkflowId: z.string().nullable(),
|
|
1794
3698
|
activeTurnId: z.string().uuid().nullable(),
|
|
1795
3699
|
// Actual input tokens of the last model call of the most recent turn; the
|
|
1796
|
-
// pre-turn
|
|
3700
|
+
// pre-turn portable context-compaction trigger reads it as its budget
|
|
1797
3701
|
// signal. Null until a turn with usage has completed.
|
|
1798
3702
|
lastInputTokens: z.number().int().nonnegative().nullable(),
|
|
3703
|
+
queueVersion: z.number().int().nonnegative(),
|
|
3704
|
+
queueHeadPosition: z.number().int(),
|
|
3705
|
+
queueTailPosition: z.number().int(),
|
|
3706
|
+
effectiveControl: EffectiveSessionControl,
|
|
1799
3707
|
lastSequence: z.number().int().nonnegative(),
|
|
1800
3708
|
// Multi-account Codex (P1). codexPinnedCredentialId: the account this session is
|
|
1801
3709
|
// manually PINNED to (null ⇒ follow the workspace active pointer).
|
|
@@ -1803,32 +3711,91 @@ var Session = z.object({
|
|
|
1803
3711
|
// "Running on:" indicator's source). Both are credential-row ids, null until set.
|
|
1804
3712
|
codexPinnedCredentialId: z.string().uuid().nullable(),
|
|
1805
3713
|
codexLastCredentialId: z.string().uuid().nullable(),
|
|
3714
|
+
/** Personal (authenticated subject) workspace pin state, never workspace-global. */
|
|
3715
|
+
pinned: z.boolean().default(false),
|
|
3716
|
+
/** Stable pin ordering key; null when this subject has not pinned the session. */
|
|
3717
|
+
pinnedAt: z.string().nullable().default(null),
|
|
3718
|
+
/** Optimistic pin-state revision; zero represents an absent pin relation. */
|
|
3719
|
+
pinVersion: z.number().int().nonnegative().default(0),
|
|
3720
|
+
/**
|
|
3721
|
+
* Server-authoritative hierarchy summary populated on session-list reads.
|
|
3722
|
+
* Detail reads may omit it. The rail uses this instead of guessing a tree
|
|
3723
|
+
* from whichever global recency page happened to be loaded.
|
|
3724
|
+
*/
|
|
3725
|
+
treeStats: z.object({
|
|
3726
|
+
directChildren: z.number().int().nonnegative(),
|
|
3727
|
+
totalDescendants: z.number().int().nonnegative(),
|
|
3728
|
+
runningDescendants: z.number().int().nonnegative(),
|
|
3729
|
+
queuedDescendants: z.number().int().nonnegative(),
|
|
3730
|
+
attentionDescendants: z.number().int().nonnegative(),
|
|
3731
|
+
pausedDescendants: z.number().int().nonnegative(),
|
|
3732
|
+
failedDescendants: z.number().int().nonnegative(),
|
|
3733
|
+
/** Counts are lower bounds rather than exact totals when true. */
|
|
3734
|
+
truncated: z.boolean().default(false)
|
|
3735
|
+
}).optional(),
|
|
1806
3736
|
createdAt: z.string(),
|
|
1807
3737
|
updatedAt: z.string()
|
|
1808
3738
|
});
|
|
3739
|
+
var CreateSessionResponse = Session.extend({
|
|
3740
|
+
initialTurnId: z.string().uuid().nullable()
|
|
3741
|
+
});
|
|
3742
|
+
var SessionListResponse = z.object({
|
|
3743
|
+
pinned: z.array(Session),
|
|
3744
|
+
/** True when older matching pins were omitted from this bounded page. */
|
|
3745
|
+
pinnedTruncated: z.boolean().optional(),
|
|
3746
|
+
sessions: z.array(Session),
|
|
3747
|
+
nextCursor: z.string().nullable()
|
|
3748
|
+
});
|
|
3749
|
+
var LineageNode = z.lazy(
|
|
3750
|
+
() => z.object({
|
|
3751
|
+
session: Session,
|
|
3752
|
+
children: z.array(LineageNode)
|
|
3753
|
+
})
|
|
3754
|
+
);
|
|
3755
|
+
var SessionLineageResponse = z.object({
|
|
3756
|
+
ancestors: z.array(Session),
|
|
3757
|
+
children: z.array(LineageNode),
|
|
3758
|
+
truncated: z.boolean().default(false)
|
|
3759
|
+
});
|
|
1809
3760
|
var SessionEventType = z.enum([
|
|
1810
3761
|
"session.created",
|
|
3762
|
+
// Defensive read/transport projection for a malformed or historically
|
|
3763
|
+
// oversized retained event envelope. The original row stays durable; this
|
|
3764
|
+
// explicit synthetic type prevents unbounded free-form envelope fields from
|
|
3765
|
+
// crossing NATS, SSE, REST, or browser boundaries.
|
|
3766
|
+
"session.event.envelope_omitted",
|
|
1811
3767
|
"session.status.changed",
|
|
1812
3768
|
"session.requiresAction",
|
|
3769
|
+
"session.humanInput.requested",
|
|
3770
|
+
"session.context.compaction.requested",
|
|
1813
3771
|
"session.context.compacted",
|
|
3772
|
+
"session.context.compaction.skipped",
|
|
1814
3773
|
"session.context.cleared",
|
|
1815
3774
|
"user.message",
|
|
1816
|
-
"user.
|
|
3775
|
+
"user.pause",
|
|
1817
3776
|
"user.approvalDecision",
|
|
3777
|
+
"user.humanInputResponse",
|
|
1818
3778
|
"turn.queued",
|
|
1819
|
-
"turn.updated",
|
|
1820
3779
|
"turn.started",
|
|
1821
3780
|
"turn.completed",
|
|
1822
3781
|
"turn.failed",
|
|
1823
3782
|
"turn.cancelled",
|
|
1824
|
-
"turn.
|
|
3783
|
+
"turn.superseded",
|
|
3784
|
+
"turn.recovery.requested",
|
|
3785
|
+
"turn.capacity_waiting",
|
|
1825
3786
|
"agent.message.delta",
|
|
1826
3787
|
"agent.message.completed",
|
|
1827
3788
|
"agent.reasoning.delta",
|
|
1828
3789
|
"agent.toolCall.created",
|
|
1829
3790
|
"agent.toolCall.output",
|
|
3791
|
+
"agent.model.usage",
|
|
1830
3792
|
"tool.auth_needed",
|
|
3793
|
+
"credential.auth_needed",
|
|
1831
3794
|
"agent.updated",
|
|
3795
|
+
"rig.setup.started",
|
|
3796
|
+
"rig.setup.completed",
|
|
3797
|
+
"rig.setup.skipped",
|
|
3798
|
+
"rig.setup.failed",
|
|
1832
3799
|
"sandbox.operation.started",
|
|
1833
3800
|
"sandbox.operation.completed",
|
|
1834
3801
|
"sandbox.operation.failed",
|
|
@@ -1839,7 +3806,23 @@ var SessionEventType = z.enum([
|
|
|
1839
3806
|
"goal.completed",
|
|
1840
3807
|
"goal.paused",
|
|
1841
3808
|
"goal.resumed",
|
|
3809
|
+
"goal.cleared",
|
|
1842
3810
|
"goal.continuation",
|
|
3811
|
+
"system.update.pending",
|
|
3812
|
+
"system.update.delivered",
|
|
3813
|
+
"session.control.paused",
|
|
3814
|
+
"session.control.resumed",
|
|
3815
|
+
"session.control.steer_requested",
|
|
3816
|
+
"workspace.inference.paused",
|
|
3817
|
+
"workspace.inference.resumed",
|
|
3818
|
+
"session.queue.changed",
|
|
3819
|
+
"session.queue.prompt.cancelled",
|
|
3820
|
+
"session.queue.history",
|
|
3821
|
+
// A terminal/stale activity callback is retained as an audit wrapper rather
|
|
3822
|
+
// than being dropped or emitted as though it belonged to the current turn.
|
|
3823
|
+
"turn.event.rejected_late",
|
|
3824
|
+
"memory.saved",
|
|
3825
|
+
"memory.corrected",
|
|
1843
3826
|
// Channel-B desktop pixel-plane signals (07-channel-b §1.2). The pixel socket
|
|
1844
3827
|
// carries opaque RFB and cannot carry a control message the client can act on,
|
|
1845
3828
|
// so these ride the durable, sequenced, gap-filled Channel-A SSE spine.
|
|
@@ -1851,8 +3834,8 @@ var SessionEventType = z.enum([
|
|
|
1851
3834
|
// a viewer detached / was reaped
|
|
1852
3835
|
"stream.revoked",
|
|
1853
3836
|
// a grant was revoked → connected clients MUST disconnect now
|
|
1854
|
-
//
|
|
1855
|
-
//
|
|
3837
|
+
// Desktop recording signals. The capture loop records the same display humans
|
|
3838
|
+
// watch, then stores the finalized artifact for replay.
|
|
1856
3839
|
// → storage. The artifact ref rides the AVAILABLE event (storageKey, NOT a
|
|
1857
3840
|
// long-lived URL — clients mint a short-TTL signed GET via the route).
|
|
1858
3841
|
"recording.started",
|
|
@@ -1861,8 +3844,8 @@ var SessionEventType = z.enum([
|
|
|
1861
3844
|
// finalized: bytes PUT to storage, replayable
|
|
1862
3845
|
"recording.failed",
|
|
1863
3846
|
// ffmpeg/box-death/rollover/upload error — no artifact
|
|
1864
|
-
//
|
|
1865
|
-
//
|
|
3847
|
+
// Structured-service notifications. File, Git, and terminal reads are
|
|
3848
|
+
// synchronous API-direct point
|
|
1866
3849
|
// queries (their result is the HTTP response, NEVER an event). What rides A1
|
|
1867
3850
|
// here are the side-effect NOTIFICATIONS — a path changed, git state changed,
|
|
1868
3851
|
// a pty opened/printed/exited — durable, sequenced, gap-filled like every
|
|
@@ -1883,19 +3866,239 @@ var SessionEventType = z.enum([
|
|
|
1883
3866
|
// Multi-account Codex (P1): the account a session's turn runs on changed
|
|
1884
3867
|
// (manual switch in P1; failover/rotation in P3 reuse the same event). Drives
|
|
1885
3868
|
// the in-session "Running on:" indicator's live flip.
|
|
1886
|
-
"codex.account.switched"
|
|
3869
|
+
"codex.account.switched",
|
|
3870
|
+
// credential allocator per-turn selection audit. Payload is metadata only: credential row
|
|
3871
|
+
// id, bounded strategy/reason, and pool counts — never token material.
|
|
3872
|
+
"codex.credential.selected",
|
|
3873
|
+
// credential allocator durable zero-capacity wait lifecycle. Runtime/system events only;
|
|
3874
|
+
// no synthetic user message is created when capacity returns.
|
|
3875
|
+
"codex.capacity.waiting",
|
|
3876
|
+
"codex.capacity.resumed",
|
|
3877
|
+
"codex.capacity.superseded",
|
|
3878
|
+
// Sandbox durability observability (sandbox-file-persistence). The 2026-07
|
|
3879
|
+
// incidents (mid-session box death with /workspace loss; a fatal manifest-env
|
|
3880
|
+
// delta on a live box) were near-unattributable because box lifecycle left no
|
|
3881
|
+
// durable trace — only worker logs, which rotate within hours. These events
|
|
3882
|
+
// make every box transition and env recomputation drift readable from the DB
|
|
3883
|
+
// alone. Payloads carry ids/flags/key NAMES only — never env values (secrets).
|
|
3884
|
+
"sandbox.box.created",
|
|
3885
|
+
// box cold-created/cold-restored ({hydrated: "archive"|"none"})
|
|
3886
|
+
"sandbox.box.lost",
|
|
3887
|
+
// resume-by-id found the box gone (provider NotFound)
|
|
3888
|
+
"sandbox.box.terminated",
|
|
3889
|
+
// reaper drain terminated the box ({actor, persisted})
|
|
3890
|
+
"sandbox.box.snapshot",
|
|
3891
|
+
// mid-session /workspace snapshot persisted ({trigger})
|
|
3892
|
+
"sandbox.env.drift",
|
|
3893
|
+
// recomputed manifest env != live box env (key names only)
|
|
3894
|
+
// Active-sandbox pointer reconcile (issue #341 invariant B). Turn start found the
|
|
3895
|
+
// persisted (active_sandbox_id, active_epoch) pointing at a target the turn cannot
|
|
3896
|
+
// establish — a deleted/absent sandbox, a Modal sibling with no establisher, or a
|
|
3897
|
+
// selfhosted sandbox with no enrollment — and reset it to the session HOME under
|
|
3898
|
+
// the epoch fence instead of routing every op into the dead target. A VISIBLE,
|
|
3899
|
+
// never-silent downgrade: payload carries the typed reason + from/to epoch, never a
|
|
3900
|
+
// target id or command content. Announce-only; hits the timeline projection default
|
|
3901
|
+
// (no rendered item) like the other sandbox.* diagnostics.
|
|
3902
|
+
"session.route.reconciled",
|
|
3903
|
+
// Workbench v2 turn-end workspace capture. ANNOUNCE-ONLY: a new
|
|
3904
|
+
// capture revision was persisted at turn end; the client refetches the latest
|
|
3905
|
+
// capture. It carries metadata only (revision/turnId/capturedAt/leaseEpoch/stats),
|
|
3906
|
+
// never file content. Hits the timeline projection default case (ignored) — it
|
|
3907
|
+
// must NEVER gain a rendered timeline item without regenerating the golden
|
|
3908
|
+
// snapshots (golden-grammar gate).
|
|
3909
|
+
"workspace.revision.captured",
|
|
3910
|
+
// Repository discovery could not prove a complete capture. The worker
|
|
3911
|
+
// persisted a failed/degraded revision marker and clients must fall back to
|
|
3912
|
+
// the live box rather than trust a zero-repository snapshot.
|
|
3913
|
+
"workspace.revision.degraded",
|
|
3914
|
+
// Connected Machine (selfhosted) op-outcome observability (failure-visibility
|
|
3915
|
+
// doctrine, out-of-band plane). SESSION-scoped facts only: these fire for the
|
|
3916
|
+
// session whose turn ran the op (the two-planes rule — machine-plane facts like
|
|
3917
|
+
// pressure live in the M10 metrics DB, never as session events). Payloads carry
|
|
3918
|
+
// the op kind + a typed fault class + attempt count — NEVER command content.
|
|
3919
|
+
//
|
|
3920
|
+
// `machine.op.failed` fires ONLY for INFRASTRUCTURE fault classes (offline,
|
|
3921
|
+
// draining-exhausted, payload-too-large, reconnecting-timeout, OS/stream/protocol)
|
|
3922
|
+
// — a semantic miss the model asked about (a missing path, a consent gate, a
|
|
3923
|
+
// nonzero exit) is an OUTCOME, not an infra fault, and never fires this.
|
|
3924
|
+
// `machine.op.recovered` is the healed-fault leading indicator (a blip/backpressure
|
|
3925
|
+
// the transport absorbed): announce-only, quiet. Both hit the timeline projection's
|
|
3926
|
+
// quiet status-tick tier (the severity split's "degraded"); adding a rendered item
|
|
3927
|
+
// requires regenerating the golden snapshots (the golden-grammar gate).
|
|
3928
|
+
"machine.op.failed",
|
|
3929
|
+
"machine.op.recovered",
|
|
3930
|
+
// Connected Machine (selfhosted) LINK-plane observability (failure-visibility
|
|
3931
|
+
// doctrine). SESSION-scoped, ANNOUNCE-ONLY facts fanned out to the sessions that
|
|
3932
|
+
// had an active op running on the machine when its control link changed — never
|
|
3933
|
+
// to idle/historical sessions. Payloads carry ids / a typed reason / key-names
|
|
3934
|
+
// only, NEVER command content.
|
|
3935
|
+
//
|
|
3936
|
+
// `machine.link.lost` — the machine announced a clean GoingOffline (its control
|
|
3937
|
+
// link is going away) while a session had a running turn on it. `machine.link.
|
|
3938
|
+
// restored` — a reconnect Hello re-established the link that was previously lost.
|
|
3939
|
+
// `machine.runner.restarted` — the additional signal that the going-offline was
|
|
3940
|
+
// a self-update restart specifically (link.lost also fires for it; this
|
|
3941
|
+
// distinguishes a restart from a plain stop / host shutdown). All three hit the
|
|
3942
|
+
// timeline projection's quiet default tier (no rendered item); adding a rendered
|
|
3943
|
+
// item requires regenerating the golden snapshots (the golden-grammar gate).
|
|
3944
|
+
"machine.link.lost",
|
|
3945
|
+
"machine.link.restored",
|
|
3946
|
+
"machine.runner.restarted"
|
|
1887
3947
|
]);
|
|
3948
|
+
var SessionEventSemanticClass = z.enum([
|
|
3949
|
+
"control",
|
|
3950
|
+
"terminal",
|
|
3951
|
+
"failure",
|
|
3952
|
+
"checkpoint",
|
|
3953
|
+
"tool_receipt",
|
|
3954
|
+
"provider_account"
|
|
3955
|
+
]);
|
|
3956
|
+
var SessionEventPayloadMode = z.enum(["none", "summary", "full"]);
|
|
3957
|
+
var SessionEventReadMode = z.enum(["monitoring", "forensic"]);
|
|
3958
|
+
var SessionEventReadDirection = z.enum(["after", "before"]);
|
|
3959
|
+
var SESSION_EVENT_RAW_DELTA_TYPES = [
|
|
3960
|
+
"agent.message.delta",
|
|
3961
|
+
"agent.reasoning.delta",
|
|
3962
|
+
"sandbox.command.output.delta",
|
|
3963
|
+
"terminal.pty.output.delta"
|
|
3964
|
+
];
|
|
3965
|
+
var SESSION_EVENT_SEMANTIC_CLASS_TYPES = {
|
|
3966
|
+
control: [
|
|
3967
|
+
"session.status.changed",
|
|
3968
|
+
"session.requiresAction",
|
|
3969
|
+
"session.humanInput.requested",
|
|
3970
|
+
"user.pause",
|
|
3971
|
+
"user.approvalDecision",
|
|
3972
|
+
"user.humanInputResponse",
|
|
3973
|
+
"goal.set",
|
|
3974
|
+
"goal.updated",
|
|
3975
|
+
"goal.completed",
|
|
3976
|
+
"goal.paused",
|
|
3977
|
+
"goal.resumed",
|
|
3978
|
+
"goal.cleared",
|
|
3979
|
+
"goal.continuation",
|
|
3980
|
+
"system.update.pending",
|
|
3981
|
+
"system.update.delivered",
|
|
3982
|
+
"session.control.paused",
|
|
3983
|
+
"session.control.resumed",
|
|
3984
|
+
"session.control.steer_requested",
|
|
3985
|
+
"workspace.inference.paused",
|
|
3986
|
+
"workspace.inference.resumed",
|
|
3987
|
+
"session.queue.changed",
|
|
3988
|
+
"session.queue.prompt.cancelled"
|
|
3989
|
+
],
|
|
3990
|
+
terminal: [
|
|
3991
|
+
"turn.completed",
|
|
3992
|
+
"turn.failed",
|
|
3993
|
+
"turn.cancelled",
|
|
3994
|
+
"turn.superseded",
|
|
3995
|
+
"goal.completed",
|
|
3996
|
+
"goal.paused",
|
|
3997
|
+
"rig.setup.completed",
|
|
3998
|
+
"rig.setup.skipped",
|
|
3999
|
+
"rig.setup.failed",
|
|
4000
|
+
"sandbox.operation.completed",
|
|
4001
|
+
"sandbox.operation.failed",
|
|
4002
|
+
"recording.available",
|
|
4003
|
+
"recording.failed",
|
|
4004
|
+
"terminal.pty.exited"
|
|
4005
|
+
],
|
|
4006
|
+
failure: [
|
|
4007
|
+
"session.event.envelope_omitted",
|
|
4008
|
+
"turn.failed",
|
|
4009
|
+
"tool.auth_needed",
|
|
4010
|
+
"credential.auth_needed",
|
|
4011
|
+
"rig.setup.failed",
|
|
4012
|
+
"sandbox.operation.failed",
|
|
4013
|
+
"recording.failed",
|
|
4014
|
+
"sandbox.box.lost",
|
|
4015
|
+
"workspace.revision.degraded",
|
|
4016
|
+
"machine.op.failed",
|
|
4017
|
+
"machine.link.lost"
|
|
4018
|
+
],
|
|
4019
|
+
checkpoint: [
|
|
4020
|
+
"session.context.compaction.requested",
|
|
4021
|
+
"session.context.compacted",
|
|
4022
|
+
"session.context.compaction.skipped",
|
|
4023
|
+
"session.context.cleared",
|
|
4024
|
+
"turn.recovery.requested",
|
|
4025
|
+
"session.queue.history",
|
|
4026
|
+
"sandbox.box.snapshot",
|
|
4027
|
+
"workspace.revision.captured"
|
|
4028
|
+
],
|
|
4029
|
+
tool_receipt: [
|
|
4030
|
+
"agent.toolCall.created",
|
|
4031
|
+
"agent.toolCall.output",
|
|
4032
|
+
"tool.auth_needed",
|
|
4033
|
+
"artifact.created"
|
|
4034
|
+
],
|
|
4035
|
+
provider_account: [
|
|
4036
|
+
"agent.model.usage",
|
|
4037
|
+
"codex.account.switched",
|
|
4038
|
+
"codex.credential.selected",
|
|
4039
|
+
"codex.capacity.waiting",
|
|
4040
|
+
"codex.capacity.resumed",
|
|
4041
|
+
"codex.capacity.superseded",
|
|
4042
|
+
"sandbox.box.created",
|
|
4043
|
+
"sandbox.box.lost",
|
|
4044
|
+
"sandbox.box.terminated",
|
|
4045
|
+
"sandbox.box.snapshot",
|
|
4046
|
+
"sandbox.env.drift",
|
|
4047
|
+
"session.route.reconciled",
|
|
4048
|
+
"machine.op.failed",
|
|
4049
|
+
"machine.op.recovered",
|
|
4050
|
+
"machine.link.lost",
|
|
4051
|
+
"machine.link.restored",
|
|
4052
|
+
"machine.runner.restarted"
|
|
4053
|
+
]
|
|
4054
|
+
};
|
|
4055
|
+
function resolveSessionEventTypeFilters(input) {
|
|
4056
|
+
const included = new Set(input.includeTypes ?? []);
|
|
4057
|
+
for (const semanticClass of input.includeClasses ?? []) {
|
|
4058
|
+
for (const type of SESSION_EVENT_SEMANTIC_CLASS_TYPES[semanticClass]) included.add(type);
|
|
4059
|
+
}
|
|
4060
|
+
const excluded = new Set(input.excludeTypes ?? []);
|
|
4061
|
+
for (const semanticClass of input.excludeClasses ?? []) {
|
|
4062
|
+
for (const type of SESSION_EVENT_SEMANTIC_CLASS_TYPES[semanticClass]) excluded.add(type);
|
|
4063
|
+
}
|
|
4064
|
+
for (const type of input.defaultExcludeTypes ?? []) {
|
|
4065
|
+
if (!included.has(type)) excluded.add(type);
|
|
4066
|
+
}
|
|
4067
|
+
for (const type of excluded) included.delete(type);
|
|
4068
|
+
return { includeTypes: [...included], excludeTypes: [...excluded] };
|
|
4069
|
+
}
|
|
1888
4070
|
var ToolAuthNeededPayload = z.object({
|
|
1889
4071
|
serverId: z.string().min(1),
|
|
1890
4072
|
toolName: z.string().min(1).nullable().optional(),
|
|
1891
4073
|
providerDomain: z.string().min(1),
|
|
1892
|
-
|
|
1893
|
-
|
|
4074
|
+
provider: z.string().min(1).max(128).optional(),
|
|
4075
|
+
// Embedded hosts may use an opaque connection identity; never assume an
|
|
4076
|
+
// OpenGeni UUID on the public event wire.
|
|
4077
|
+
connectionId: z.string().min(1).nullable().optional(),
|
|
4078
|
+
reason: z.enum([
|
|
4079
|
+
"missing_connection",
|
|
4080
|
+
"expired",
|
|
4081
|
+
"insufficient_scope",
|
|
4082
|
+
"refresh_failed",
|
|
4083
|
+
"unsupported_auth",
|
|
4084
|
+
"resource_scope_unavailable"
|
|
4085
|
+
]),
|
|
1894
4086
|
scopes: z.array(z.string().min(1)).optional(),
|
|
1895
4087
|
resource: z.string().min(1).optional(),
|
|
4088
|
+
selectedResources: McpConnectionResourceScopes.optional(),
|
|
1896
4089
|
authorizationUrl: z.string().url().optional(),
|
|
1897
4090
|
subjectId: z.string().min(1).nullable().optional()
|
|
1898
4091
|
});
|
|
4092
|
+
var CredentialAuthNeededPayload = z.object({
|
|
4093
|
+
credentialClass: z.literal("run"),
|
|
4094
|
+
providerDomain: z.string().min(1).optional(),
|
|
4095
|
+
connectionId: z.string().min(1).optional(),
|
|
4096
|
+
reason: z.enum(["missing_connection", "expired", "insufficient_scope", "refresh_failed"]),
|
|
4097
|
+
scopes: z.array(z.string().min(1)).optional(),
|
|
4098
|
+
resource: z.string().min(1).optional(),
|
|
4099
|
+
authorizationUrl: z.string().url().optional(),
|
|
4100
|
+
message: z.string().min(1).optional()
|
|
4101
|
+
});
|
|
1899
4102
|
var StreamUrlRotatedPayload = z.object({
|
|
1900
4103
|
url: z.string().url(),
|
|
1901
4104
|
token: z.string().nullable(),
|
|
@@ -1977,15 +4180,17 @@ var SandboxCommandOutputDeltaPayload = z.object({
|
|
|
1977
4180
|
});
|
|
1978
4181
|
var FsChangeKind = z.enum(["created", "modified", "deleted", "renamed"]);
|
|
1979
4182
|
var FsChangedPayload = z.object({
|
|
1980
|
-
changes: z.array(
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
4183
|
+
changes: z.array(
|
|
4184
|
+
z.object({
|
|
4185
|
+
path: z.string(),
|
|
4186
|
+
// workspace-relative POSIX path
|
|
4187
|
+
kind: FsChangeKind,
|
|
4188
|
+
isDir: z.boolean().default(false),
|
|
4189
|
+
sizeBytes: z.number().int().nonnegative().nullable().default(null),
|
|
4190
|
+
oldPath: z.string().optional()
|
|
4191
|
+
// for "renamed"
|
|
4192
|
+
})
|
|
4193
|
+
).min(1),
|
|
1989
4194
|
source: z.enum(["write", "watch", "agent"]).default("write"),
|
|
1990
4195
|
// Monotonic FS revision (per-lease, paired with leaseEpoch for staleness).
|
|
1991
4196
|
revision: z.number().int().nonnegative(),
|
|
@@ -2028,16 +4233,18 @@ var TerminalPtyExitedPayload = z.object({
|
|
|
2028
4233
|
reason: z.enum(["exit", "killed", "owner_gone", "timeout"])
|
|
2029
4234
|
});
|
|
2030
4235
|
var FsNodeType = z.enum(["file", "dir", "symlink", "other"]);
|
|
2031
|
-
var FsTreeNode = z.lazy(
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
4236
|
+
var FsTreeNode = z.lazy(
|
|
4237
|
+
() => z.object({
|
|
4238
|
+
name: z.string(),
|
|
4239
|
+
path: z.string(),
|
|
4240
|
+
type: FsNodeType,
|
|
4241
|
+
sizeBytes: z.number().int().nonnegative().nullable(),
|
|
4242
|
+
mtimeMs: z.number().int().nonnegative().nullable(),
|
|
4243
|
+
mode: z.number().int().nullable(),
|
|
4244
|
+
children: z.array(FsTreeNode).optional(),
|
|
4245
|
+
truncated: z.boolean().default(false)
|
|
4246
|
+
})
|
|
4247
|
+
);
|
|
2041
4248
|
var FsListRequest = z.object({
|
|
2042
4249
|
path: z.string().default(""),
|
|
2043
4250
|
// "" = workspace root
|
|
@@ -2089,7 +4296,9 @@ var FsDeleteRequest = z.object({
|
|
|
2089
4296
|
recursive: z.boolean().default(false)
|
|
2090
4297
|
// required true to delete a non-empty dir
|
|
2091
4298
|
});
|
|
2092
|
-
var FsDeleteResponse = z.object({
|
|
4299
|
+
var FsDeleteResponse = z.object({
|
|
4300
|
+
revision: z.number().int().nonnegative()
|
|
4301
|
+
});
|
|
2093
4302
|
var FsMoveRequest = z.object({
|
|
2094
4303
|
path: z.string(),
|
|
2095
4304
|
newPath: z.string(),
|
|
@@ -2186,6 +4395,9 @@ var GitDiffRequest = z.object({
|
|
|
2186
4395
|
// diff selectors, mutually exclusive precedence: refs > staged > worktree
|
|
2187
4396
|
staged: z.boolean().default(false),
|
|
2188
4397
|
// --cached (index vs HEAD)
|
|
4398
|
+
// Workspace review includes after-images that ordinary `git diff` omits.
|
|
4399
|
+
// Explicit so commit/staged consumers keep native Git semantics by default.
|
|
4400
|
+
includeUntracked: z.boolean().default(false),
|
|
2189
4401
|
fromRef: z.string().optional(),
|
|
2190
4402
|
toRef: z.string().optional(),
|
|
2191
4403
|
pathspec: z.array(z.string()).default([]),
|
|
@@ -2196,6 +4408,125 @@ var GitDiffResponse = z.object({
|
|
|
2196
4408
|
files: z.array(GitFileDiff),
|
|
2197
4409
|
revision: z.number().int().nonnegative()
|
|
2198
4410
|
});
|
|
4411
|
+
var WorkspaceCaptureFile = z.object({
|
|
4412
|
+
path: z.string(),
|
|
4413
|
+
status: GitFileStatusCode,
|
|
4414
|
+
// sha256 of the captured after-image bytes; null when deleted / tooLarge.
|
|
4415
|
+
hash: z.string().nullable(),
|
|
4416
|
+
// git blob sha of the HEAD version — the wake-on-edit flush guard (design
|
|
4417
|
+
// §10.1). null when the path is new/untracked (no HEAD blob).
|
|
4418
|
+
baseHash: z.string().nullable(),
|
|
4419
|
+
// Content-addressed storage key of the after-image; null when deleted /
|
|
4420
|
+
// tooLarge / binary (no inline content captured).
|
|
4421
|
+
contentRef: z.string().nullable(),
|
|
4422
|
+
sizeBytes: z.number().int().nonnegative(),
|
|
4423
|
+
isBinary: z.boolean().default(false),
|
|
4424
|
+
// >5MB per-file content guard tripped: content NOT captured, render "open live".
|
|
4425
|
+
tooLarge: z.boolean().default(false),
|
|
4426
|
+
deleted: z.boolean().default(false)
|
|
4427
|
+
});
|
|
4428
|
+
var WorkspaceCaptureRepo = z.object({
|
|
4429
|
+
root: z.string(),
|
|
4430
|
+
head: z.string().nullable(),
|
|
4431
|
+
detached: z.boolean().default(false),
|
|
4432
|
+
upstream: z.string().nullable(),
|
|
4433
|
+
ahead: z.number().int().nonnegative().default(0),
|
|
4434
|
+
behind: z.number().int().nonnegative().default(0),
|
|
4435
|
+
status: z.array(GitFileStatus),
|
|
4436
|
+
diff: z.array(GitFileDiff)
|
|
4437
|
+
});
|
|
4438
|
+
var WorkspaceCaptureDegradedReason = z.enum([
|
|
4439
|
+
"repository_discovery_command_failed",
|
|
4440
|
+
"repository_discovery_timed_out",
|
|
4441
|
+
"repository_discovery_result_limit_exceeded"
|
|
4442
|
+
]);
|
|
4443
|
+
var WorkspaceCaptureStats = z.object({
|
|
4444
|
+
repoCount: z.number().int().nonnegative(),
|
|
4445
|
+
fileCount: z.number().int().nonnegative(),
|
|
4446
|
+
additions: z.number().int().nonnegative(),
|
|
4447
|
+
deletions: z.number().int().nonnegative(),
|
|
4448
|
+
totalBytes: z.number().int().nonnegative(),
|
|
4449
|
+
tooLargeCount: z.number().int().nonnegative(),
|
|
4450
|
+
binaryCount: z.number().int().nonnegative(),
|
|
4451
|
+
treeEntryCount: z.number().int().nonnegative(),
|
|
4452
|
+
treeTruncated: z.boolean().default(false),
|
|
4453
|
+
durationMs: z.number().int().nonnegative(),
|
|
4454
|
+
// sha256 over the change surface (per-file path/hash/status + per-repo diff
|
|
4455
|
+
// summary, tree/mtime excluded). The empty-turn gate skips a capture whose
|
|
4456
|
+
// fingerprint equals the previous revision's — "no new revision when nothing
|
|
4457
|
+
// changed" holds even when the tree stays dirty across read-only turns.
|
|
4458
|
+
fingerprint: z.string().optional()
|
|
4459
|
+
});
|
|
4460
|
+
var WorkspaceCaptureManifest = z.object({
|
|
4461
|
+
version: z.literal(1),
|
|
4462
|
+
revision: z.number().int().nonnegative(),
|
|
4463
|
+
capturedAt: z.string(),
|
|
4464
|
+
turnId: z.string().nullable(),
|
|
4465
|
+
leaseEpoch: z.number().int().nonnegative(),
|
|
4466
|
+
treeIndex: FsTreeNode,
|
|
4467
|
+
treeTruncated: z.boolean().default(false),
|
|
4468
|
+
repos: z.array(WorkspaceCaptureRepo),
|
|
4469
|
+
files: z.array(WorkspaceCaptureFile),
|
|
4470
|
+
stats: WorkspaceCaptureStats
|
|
4471
|
+
});
|
|
4472
|
+
var WorkspaceRevisionCapturedPayload = z.object({
|
|
4473
|
+
revision: z.number().int().nonnegative(),
|
|
4474
|
+
turnId: z.string().nullable(),
|
|
4475
|
+
capturedAt: z.string(),
|
|
4476
|
+
leaseEpoch: z.number().int().nonnegative(),
|
|
4477
|
+
stats: WorkspaceCaptureStats
|
|
4478
|
+
});
|
|
4479
|
+
var WorkspaceRevisionDegradedPayload = z.object({
|
|
4480
|
+
revision: z.number().int().nonnegative(),
|
|
4481
|
+
turnId: z.string().nullable(),
|
|
4482
|
+
capturedAt: z.string(),
|
|
4483
|
+
leaseEpoch: z.number().int().nonnegative(),
|
|
4484
|
+
reason: WorkspaceCaptureDegradedReason
|
|
4485
|
+
});
|
|
4486
|
+
var WorkspaceCaptureSignedUrl = z.object({
|
|
4487
|
+
url: z.string().url(),
|
|
4488
|
+
expiresAt: z.string()
|
|
4489
|
+
});
|
|
4490
|
+
var GetWorkspaceCaptureResponse = z.discriminatedUnion("available", [
|
|
4491
|
+
z.object({
|
|
4492
|
+
available: z.literal(false),
|
|
4493
|
+
// Optional for additive compatibility with older servers. New servers set
|
|
4494
|
+
// these fields when the newest durable revision is an explicit degraded
|
|
4495
|
+
// marker rather than "no capture exists yet".
|
|
4496
|
+
degradedReason: WorkspaceCaptureDegradedReason.nullable().optional(),
|
|
4497
|
+
revision: z.number().int().nonnegative().nullable().optional(),
|
|
4498
|
+
capturedAt: z.string().nullable().optional(),
|
|
4499
|
+
turnId: z.string().nullable().optional(),
|
|
4500
|
+
leaseEpoch: z.number().int().nonnegative().nullable().optional()
|
|
4501
|
+
}),
|
|
4502
|
+
z.object({
|
|
4503
|
+
available: z.literal(true),
|
|
4504
|
+
revision: z.number().int().nonnegative(),
|
|
4505
|
+
capturedAt: z.string(),
|
|
4506
|
+
turnId: z.string().nullable(),
|
|
4507
|
+
leaseEpoch: z.number().int().nonnegative(),
|
|
4508
|
+
sizeBytes: z.number().int().nonnegative(),
|
|
4509
|
+
stats: WorkspaceCaptureStats,
|
|
4510
|
+
manifest: WorkspaceCaptureManifest.nullable().default(null),
|
|
4511
|
+
manifestUrl: WorkspaceCaptureSignedUrl.nullable().default(null)
|
|
4512
|
+
})
|
|
4513
|
+
]);
|
|
4514
|
+
var GetWorkspaceCaptureFileResponse = z.object({
|
|
4515
|
+
path: z.string(),
|
|
4516
|
+
revision: z.number().int().nonnegative(),
|
|
4517
|
+
status: GitFileStatusCode,
|
|
4518
|
+
hash: z.string().nullable(),
|
|
4519
|
+
baseHash: z.string().nullable(),
|
|
4520
|
+
sizeBytes: z.number().int().nonnegative(),
|
|
4521
|
+
isBinary: z.boolean(),
|
|
4522
|
+
tooLarge: z.boolean(),
|
|
4523
|
+
encoding: FsEncoding.nullable().default(null),
|
|
4524
|
+
// set iff content is inline
|
|
4525
|
+
content: z.string().nullable().default(null),
|
|
4526
|
+
// inline ≤256KB (per encoding)
|
|
4527
|
+
contentUrl: WorkspaceCaptureSignedUrl.nullable().default(null)
|
|
4528
|
+
// signed >256KB
|
|
4529
|
+
});
|
|
2199
4530
|
var GitLogRequest = z.object({
|
|
2200
4531
|
path: z.string().default(""),
|
|
2201
4532
|
ref: z.string().default("HEAD"),
|
|
@@ -2207,14 +4538,25 @@ var GitCommit = z.object({
|
|
|
2207
4538
|
sha: z.string(),
|
|
2208
4539
|
shortSha: z.string(),
|
|
2209
4540
|
parents: z.array(z.string()),
|
|
2210
|
-
author: z.object({
|
|
2211
|
-
|
|
4541
|
+
author: z.object({
|
|
4542
|
+
name: z.string(),
|
|
4543
|
+
email: z.string(),
|
|
4544
|
+
timestamp: z.number().int()
|
|
4545
|
+
}),
|
|
4546
|
+
committer: z.object({
|
|
4547
|
+
name: z.string(),
|
|
4548
|
+
email: z.string(),
|
|
4549
|
+
timestamp: z.number().int()
|
|
4550
|
+
}),
|
|
2212
4551
|
subject: z.string(),
|
|
2213
4552
|
body: z.string(),
|
|
2214
4553
|
refs: z.array(z.string()).default([])
|
|
2215
4554
|
// decorations: branch/tag pointers
|
|
2216
4555
|
});
|
|
2217
|
-
var GitLogResponse = z.object({
|
|
4556
|
+
var GitLogResponse = z.object({
|
|
4557
|
+
commits: z.array(GitCommit),
|
|
4558
|
+
hasMore: z.boolean()
|
|
4559
|
+
});
|
|
2218
4560
|
var GitShowRequest = z.object({
|
|
2219
4561
|
path: z.string().default(""),
|
|
2220
4562
|
ref: z.string(),
|
|
@@ -2229,7 +4571,12 @@ var GitShowResponse = z.object({
|
|
|
2229
4571
|
// null when fetching a raw blob
|
|
2230
4572
|
files: z.array(GitFileDiff),
|
|
2231
4573
|
// commit diff vs first parent
|
|
2232
|
-
blob: z.object({
|
|
4574
|
+
blob: z.object({
|
|
4575
|
+
content: z.string(),
|
|
4576
|
+
encoding: FsEncoding,
|
|
4577
|
+
sizeBytes: z.number().int(),
|
|
4578
|
+
truncated: z.boolean()
|
|
4579
|
+
}).nullable(),
|
|
2233
4580
|
revision: z.number().int().nonnegative()
|
|
2234
4581
|
});
|
|
2235
4582
|
var TerminalExecRequest = z.object({
|
|
@@ -2266,11 +4613,22 @@ var PtyOpenResponse = z.object({
|
|
|
2266
4613
|
supportsInput: z.boolean()
|
|
2267
4614
|
// false on backends without writeStdin
|
|
2268
4615
|
});
|
|
2269
|
-
var PtyWriteRequest = z.object({
|
|
2270
|
-
|
|
4616
|
+
var PtyWriteRequest = z.object({
|
|
4617
|
+
ptyId: z.string().uuid(),
|
|
4618
|
+
data: z.string()
|
|
4619
|
+
});
|
|
4620
|
+
var PtyResizeRequest = z.object({
|
|
4621
|
+
ptyId: z.string().uuid(),
|
|
4622
|
+
cols: z.number().int().positive(),
|
|
4623
|
+
rows: z.number().int().positive()
|
|
4624
|
+
});
|
|
2271
4625
|
var PtyCloseRequest = z.object({ ptyId: z.string().uuid() });
|
|
2272
4626
|
var SessionStructuredCapabilities = z.object({
|
|
2273
|
-
FileSystem: z.object({
|
|
4627
|
+
FileSystem: z.object({
|
|
4628
|
+
available: z.boolean(),
|
|
4629
|
+
readOnly: z.boolean(),
|
|
4630
|
+
root: z.string()
|
|
4631
|
+
}),
|
|
2274
4632
|
Terminal: z.object({
|
|
2275
4633
|
events: z.boolean(),
|
|
2276
4634
|
// command.output firehose (always on if a box exists)
|
|
@@ -2289,11 +4647,407 @@ var SessionEvent = z.object({
|
|
|
2289
4647
|
type: SessionEventType,
|
|
2290
4648
|
payload: z.unknown().default({}),
|
|
2291
4649
|
occurredAt: z.string(),
|
|
2292
|
-
clientEventId:
|
|
2293
|
-
turnId: z.string().uuid().nullable().optional()
|
|
4650
|
+
clientEventId: SessionOperationKey.nullable().optional(),
|
|
4651
|
+
turnId: z.string().uuid().nullable().optional(),
|
|
4652
|
+
turnGeneration: z.number().int().nonnegative().nullable().optional(),
|
|
4653
|
+
turnAttemptId: z.string().uuid().nullable().optional(),
|
|
4654
|
+
turnAssociation: z.enum(["current", "late_rejected", "duplicate"]).nullable().optional(),
|
|
4655
|
+
duplicateOfEventId: z.string().uuid().nullable().optional(),
|
|
4656
|
+
duplicateReason: z.string().min(1).max(1024).nullable().optional()
|
|
4657
|
+
});
|
|
4658
|
+
var OPENGENI_HOST_EXPORT_SCHEMA_REVISION = "2026-07-host-export-v1";
|
|
4659
|
+
var HostExportCursor = z.string().regex(/^(0|[1-9][0-9]*)$/);
|
|
4660
|
+
var HostExportConsumerId = z.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._:-]*$/);
|
|
4661
|
+
var HostExportInitiator = TurnInitiator.extend({
|
|
4662
|
+
subjectId: z.string().min(1).max(1024),
|
|
4663
|
+
label: z.string().min(1).max(256).optional()
|
|
4664
|
+
});
|
|
4665
|
+
var HostExportInitiatorContext = TurnInitiatorContext.refine(
|
|
4666
|
+
(value) => {
|
|
4667
|
+
try {
|
|
4668
|
+
return new TextEncoder().encode(JSON.stringify(value)).byteLength <= 4096;
|
|
4669
|
+
} catch {
|
|
4670
|
+
return false;
|
|
4671
|
+
}
|
|
4672
|
+
},
|
|
4673
|
+
{ message: "Host export initiator context exceeds 4096 UTF-8 bytes" }
|
|
4674
|
+
);
|
|
4675
|
+
var HostExportAttribution = {
|
|
4676
|
+
initiator: HostExportInitiator.nullable(),
|
|
4677
|
+
initiatorContext: HostExportInitiatorContext,
|
|
4678
|
+
origin: SessionTurnSource.nullable()
|
|
4679
|
+
};
|
|
4680
|
+
var HostSessionEvent = SessionEvent.extend({
|
|
4681
|
+
type: z.string().min(1).max(256),
|
|
4682
|
+
clientEventId: z.string().max(1024).nullable().optional(),
|
|
4683
|
+
turnAssociation: z.string().min(1).max(64).nullable().optional(),
|
|
4684
|
+
duplicateReason: z.string().max(4096).nullable().optional()
|
|
4685
|
+
});
|
|
4686
|
+
var HostUsageEvent = UsageEvent.extend({
|
|
4687
|
+
subjectId: z.string().max(1024).nullable(),
|
|
4688
|
+
eventType: z.string().min(1).max(256),
|
|
4689
|
+
unit: z.string().min(1).max(128),
|
|
4690
|
+
sourceResourceType: z.string().max(256).nullable(),
|
|
4691
|
+
sourceResourceId: z.string().max(2048).nullable(),
|
|
4692
|
+
idempotencyKey: z.string().min(1).max(2048),
|
|
4693
|
+
billingProviderEventId: z.string().max(2048).nullable()
|
|
4694
|
+
});
|
|
4695
|
+
var HostEventExport = z.object({
|
|
4696
|
+
schemaRevision: z.literal(OPENGENI_HOST_EXPORT_SCHEMA_REVISION),
|
|
4697
|
+
cursor: HostExportCursor,
|
|
4698
|
+
idempotencyKey: z.string().min(1).max(2048),
|
|
4699
|
+
accountId: z.string().uuid(),
|
|
4700
|
+
workspaceId: z.string().uuid(),
|
|
4701
|
+
/**
|
|
4702
|
+
* Immutable root of event.sessionId's session lineage at capture time. Null
|
|
4703
|
+
* only for an unresolved pre-lineage/legacy export row.
|
|
4704
|
+
*/
|
|
4705
|
+
rootSessionId: z.string().uuid().nullable(),
|
|
4706
|
+
...HostExportAttribution,
|
|
4707
|
+
event: HostSessionEvent
|
|
2294
4708
|
});
|
|
2295
|
-
var
|
|
4709
|
+
var HostUsageExport = z.object({
|
|
4710
|
+
schemaRevision: z.literal(OPENGENI_HOST_EXPORT_SCHEMA_REVISION),
|
|
4711
|
+
cursor: HostExportCursor,
|
|
4712
|
+
accountId: z.string().uuid(),
|
|
4713
|
+
workspaceId: z.string().uuid(),
|
|
4714
|
+
sessionId: z.string().uuid().nullable(),
|
|
4715
|
+
/** Null when sessionId is null or an unresolved pre-lineage legacy row. */
|
|
4716
|
+
rootSessionId: z.string().uuid().nullable(),
|
|
4717
|
+
turnId: z.string().uuid().nullable(),
|
|
4718
|
+
turnAttemptId: z.string().uuid().nullable(),
|
|
4719
|
+
...HostExportAttribution,
|
|
4720
|
+
usage: HostUsageEvent
|
|
4721
|
+
});
|
|
4722
|
+
var HostEventExportBatch = z.object({
|
|
4723
|
+
schemaRevision: z.literal(OPENGENI_HOST_EXPORT_SCHEMA_REVISION),
|
|
4724
|
+
consumerId: HostExportConsumerId,
|
|
4725
|
+
leaseToken: z.string().uuid(),
|
|
4726
|
+
checkpoint: HostExportCursor,
|
|
4727
|
+
throughCursor: HostExportCursor,
|
|
4728
|
+
events: z.array(HostEventExport).min(1).max(256)
|
|
4729
|
+
});
|
|
4730
|
+
var HostUsageExportBatch = z.object({
|
|
4731
|
+
schemaRevision: z.literal(OPENGENI_HOST_EXPORT_SCHEMA_REVISION),
|
|
4732
|
+
consumerId: HostExportConsumerId,
|
|
4733
|
+
leaseToken: z.string().uuid(),
|
|
4734
|
+
checkpoint: HostExportCursor,
|
|
4735
|
+
throughCursor: HostExportCursor,
|
|
4736
|
+
events: z.array(HostUsageExport).min(1).max(256)
|
|
4737
|
+
});
|
|
4738
|
+
var SESSION_EVENT_TYPE_MAX_BYTES = 256;
|
|
4739
|
+
var SESSION_EVENT_CLIENT_EVENT_ID_MAX_BYTES = SESSION_OPERATION_KEY_MAX_CHARS * 4;
|
|
4740
|
+
var SESSION_EVENT_TURN_ASSOCIATION_MAX_BYTES = 64;
|
|
4741
|
+
var SESSION_EVENT_DUPLICATE_REASON_MAX_BYTES = 4 * 1024;
|
|
4742
|
+
var SESSION_EVENT_ENVELOPE_MAX_BYTES = 80 * 1024;
|
|
4743
|
+
function boundSessionEvent(event, options = {}) {
|
|
4744
|
+
const surface = options.surface ?? "durable_audit";
|
|
4745
|
+
const maxBytes = Math.max(8 * 1024, options.maxBytes ?? SESSION_EVENT_ENVELOPE_MAX_BYTES);
|
|
4746
|
+
const originalBytes = measureSessionEventJson(event).bytes;
|
|
4747
|
+
const source = sessionEventOwnDataFields(event);
|
|
4748
|
+
const id = canonicalSessionEventUuid(source.id, SESSION_EVENT_ZERO_UUID);
|
|
4749
|
+
const workspaceId = canonicalSessionEventUuid(source.workspaceId, SESSION_EVENT_ZERO_UUID);
|
|
4750
|
+
const sessionId = canonicalSessionEventUuid(source.sessionId, SESSION_EVENT_ZERO_UUID);
|
|
4751
|
+
const sequence = source.sequence.readable && typeof source.sequence.value === "number" && Number.isSafeInteger(source.sequence.value) && source.sequence.value > 0 ? source.sequence.value : 1;
|
|
4752
|
+
const occurredAt = source.occurredAt.readable && typeof source.occurredAt.value === "string" && sessionEventUtf8Bytes(source.occurredAt.value) <= 256 ? source.occurredAt.value : "1970-01-01T00:00:00.000Z";
|
|
4753
|
+
const rawType = source.type.readable ? source.type.value : void 0;
|
|
4754
|
+
const typeIsSafe = typeof rawType === "string" && sessionEventUtf8Bytes(rawType) <= SESSION_EVENT_TYPE_MAX_BYTES && !rawType.includes("\n") && !rawType.includes("\r");
|
|
4755
|
+
const rawClientEventId = source.clientEventId.readable ? source.clientEventId.value : void 0;
|
|
4756
|
+
const clientEventId = boundOptionalSessionEventText(
|
|
4757
|
+
typeof rawClientEventId === "string" || rawClientEventId === null ? rawClientEventId : void 0,
|
|
4758
|
+
SESSION_EVENT_CLIENT_EVENT_ID_MAX_BYTES
|
|
4759
|
+
);
|
|
4760
|
+
const rawTurnAssociation = source.turnAssociation.readable ? source.turnAssociation.value : void 0;
|
|
4761
|
+
const turnAssociation = rawTurnAssociation === null || rawTurnAssociation === void 0 || rawTurnAssociation === "current" || rawTurnAssociation === "late_rejected" || rawTurnAssociation === "duplicate" ? rawTurnAssociation : null;
|
|
4762
|
+
const rawDuplicateReason = source.duplicateReason.readable ? source.duplicateReason.value : void 0;
|
|
4763
|
+
const duplicateReason = boundOptionalSessionEventText(
|
|
4764
|
+
typeof rawDuplicateReason === "string" || rawDuplicateReason === null ? rawDuplicateReason : void 0,
|
|
4765
|
+
SESSION_EVENT_DUPLICATE_REASON_MAX_BYTES
|
|
4766
|
+
);
|
|
4767
|
+
const turnId = canonicalOptionalSessionEventUuid(source.turnId);
|
|
4768
|
+
const turnGeneration = canonicalSessionEventGeneration(source.turnGeneration);
|
|
4769
|
+
const turnAttemptId = canonicalOptionalSessionEventUuid(source.turnAttemptId);
|
|
4770
|
+
const duplicateOfEventId = canonicalOptionalSessionEventUuid(source.duplicateOfEventId);
|
|
4771
|
+
const envelopeFields = [
|
|
4772
|
+
sessionEventCustomSerializerProjection(event),
|
|
4773
|
+
sessionEventAdditionalTopLevelFieldProjection(event),
|
|
4774
|
+
!typeIsSafe ? sessionEventEnvelopeFieldProjection(
|
|
4775
|
+
"type",
|
|
4776
|
+
rawType,
|
|
4777
|
+
"session.event.envelope_omitted",
|
|
4778
|
+
source.type.readable
|
|
4779
|
+
) : null,
|
|
4780
|
+
!source.clientEventId.readable || rawClientEventId !== clientEventId ? sessionEventEnvelopeFieldProjection(
|
|
4781
|
+
"clientEventId",
|
|
4782
|
+
rawClientEventId,
|
|
4783
|
+
clientEventId,
|
|
4784
|
+
source.clientEventId.readable
|
|
4785
|
+
) : null,
|
|
4786
|
+
!source.turnAssociation.readable || rawTurnAssociation !== turnAssociation ? sessionEventEnvelopeFieldProjection(
|
|
4787
|
+
"turnAssociation",
|
|
4788
|
+
rawTurnAssociation,
|
|
4789
|
+
turnAssociation,
|
|
4790
|
+
source.turnAssociation.readable
|
|
4791
|
+
) : null,
|
|
4792
|
+
!source.duplicateReason.readable || rawDuplicateReason !== duplicateReason ? sessionEventEnvelopeFieldProjection(
|
|
4793
|
+
"duplicateReason",
|
|
4794
|
+
rawDuplicateReason,
|
|
4795
|
+
duplicateReason,
|
|
4796
|
+
source.duplicateReason.readable
|
|
4797
|
+
) : null,
|
|
4798
|
+
...sessionEventCanonicalFieldProjections(source, {
|
|
4799
|
+
id,
|
|
4800
|
+
workspaceId,
|
|
4801
|
+
sessionId,
|
|
4802
|
+
sequence,
|
|
4803
|
+
occurredAt
|
|
4804
|
+
}),
|
|
4805
|
+
...sessionEventOptionalFieldProjections(source, {
|
|
4806
|
+
turnId,
|
|
4807
|
+
turnGeneration,
|
|
4808
|
+
turnAttemptId,
|
|
4809
|
+
duplicateOfEventId
|
|
4810
|
+
}),
|
|
4811
|
+
!source.payload.readable ? sessionEventEnvelopeFieldProjection("payload", void 0, null, false) : null
|
|
4812
|
+
].filter((field) => field !== null);
|
|
4813
|
+
const rawPayload = source.payload.readable ? source.payload.value : "[event payload accessor omitted at bounded projection boundary]";
|
|
4814
|
+
const payload = envelopeFields.length === 0 ? boundSessionEventPayload(rawPayload, { surface }) : boundSessionEventPayload(
|
|
4815
|
+
{
|
|
4816
|
+
preview: "[legacy event envelope normalized at bounded projection boundary]",
|
|
4817
|
+
originalEventBytes: originalBytes,
|
|
4818
|
+
originalType: typeof rawType === "string" ? boundSessionEventText(rawType, 256) : null,
|
|
4819
|
+
envelopeProjection: {
|
|
4820
|
+
truncated: true,
|
|
4821
|
+
surface,
|
|
4822
|
+
fields: envelopeFields
|
|
4823
|
+
},
|
|
4824
|
+
fullEvidence: { available: false, reason: "not_retained" }
|
|
4825
|
+
},
|
|
4826
|
+
{ surface, maxBytes: 8 * 1024 }
|
|
4827
|
+
);
|
|
4828
|
+
const bounded = {
|
|
4829
|
+
id,
|
|
4830
|
+
workspaceId,
|
|
4831
|
+
sessionId,
|
|
4832
|
+
sequence,
|
|
4833
|
+
type: typeIsSafe ? rawType : "session.event.envelope_omitted",
|
|
4834
|
+
payload,
|
|
4835
|
+
occurredAt,
|
|
4836
|
+
...sessionEventShouldEmitOptionalField(source.clientEventId) ? { clientEventId } : {},
|
|
4837
|
+
...sessionEventShouldEmitOptionalField(source.turnId) ? { turnId } : {},
|
|
4838
|
+
...sessionEventShouldEmitOptionalField(source.turnGeneration) ? { turnGeneration } : {},
|
|
4839
|
+
...sessionEventShouldEmitOptionalField(source.turnAttemptId) ? { turnAttemptId } : {},
|
|
4840
|
+
...sessionEventShouldEmitOptionalField(source.turnAssociation) ? { turnAssociation } : {},
|
|
4841
|
+
...sessionEventShouldEmitOptionalField(source.duplicateOfEventId) ? { duplicateOfEventId } : {},
|
|
4842
|
+
...sessionEventShouldEmitOptionalField(source.duplicateReason) ? { duplicateReason } : {}
|
|
4843
|
+
};
|
|
4844
|
+
if (sessionEventJsonBytes(bounded) <= maxBytes) return bounded;
|
|
4845
|
+
const fallback = {
|
|
4846
|
+
id,
|
|
4847
|
+
workspaceId,
|
|
4848
|
+
sessionId,
|
|
4849
|
+
sequence,
|
|
4850
|
+
type: "session.event.envelope_omitted",
|
|
4851
|
+
payload: boundSessionEventPayload(
|
|
4852
|
+
{
|
|
4853
|
+
preview: "[legacy event envelope omitted at bounded projection boundary]",
|
|
4854
|
+
originalEventBytes: originalBytes,
|
|
4855
|
+
originalType: typeof rawType === "string" ? boundSessionEventText(rawType, 256) : null,
|
|
4856
|
+
fullEvidence: { available: false, reason: "not_retained" }
|
|
4857
|
+
},
|
|
4858
|
+
{ surface, maxBytes: 4 * 1024 }
|
|
4859
|
+
),
|
|
4860
|
+
occurredAt,
|
|
4861
|
+
...sessionEventShouldEmitOptionalField(source.clientEventId) ? { clientEventId } : {},
|
|
4862
|
+
...sessionEventShouldEmitOptionalField(source.turnId) ? { turnId } : {},
|
|
4863
|
+
...sessionEventShouldEmitOptionalField(source.turnGeneration) ? { turnGeneration } : {},
|
|
4864
|
+
...sessionEventShouldEmitOptionalField(source.turnAttemptId) ? { turnAttemptId } : {},
|
|
4865
|
+
...sessionEventShouldEmitOptionalField(source.turnAssociation) ? { turnAssociation } : {},
|
|
4866
|
+
...sessionEventShouldEmitOptionalField(source.duplicateOfEventId) ? { duplicateOfEventId } : {},
|
|
4867
|
+
...sessionEventShouldEmitOptionalField(source.duplicateReason) ? { duplicateReason } : {}
|
|
4868
|
+
};
|
|
4869
|
+
const deliveredBytes = sessionEventJsonBytes(fallback);
|
|
4870
|
+
if (deliveredBytes > maxBytes) {
|
|
4871
|
+
throw new RangeError(
|
|
4872
|
+
`Bounded session event exceeds its final envelope (${deliveredBytes} > ${maxBytes} bytes)`
|
|
4873
|
+
);
|
|
4874
|
+
}
|
|
4875
|
+
return fallback;
|
|
4876
|
+
}
|
|
4877
|
+
function sessionEventEnvelopeFieldProjection(field, original, delivered, originalReadable = true) {
|
|
4878
|
+
return {
|
|
4879
|
+
field,
|
|
4880
|
+
originalBytes: originalReadable ? typeof original === "string" ? sessionEventUtf8Bytes(original) : typeof original === "number" || typeof original === "boolean" ? sessionEventJsonBytes(original) : original === null || original === void 0 ? 0 : null : null,
|
|
4881
|
+
deliveredBytes: typeof delivered === "string" ? sessionEventUtf8Bytes(delivered) : typeof delivered === "number" || typeof delivered === "boolean" ? sessionEventJsonBytes(delivered) : 0
|
|
4882
|
+
};
|
|
4883
|
+
}
|
|
4884
|
+
function sessionEventCustomSerializerProjection(event) {
|
|
4885
|
+
const projection = {
|
|
4886
|
+
field: "toJSON",
|
|
4887
|
+
originalBytes: null,
|
|
4888
|
+
deliveredBytes: 0
|
|
4889
|
+
};
|
|
4890
|
+
let candidate = event;
|
|
4891
|
+
try {
|
|
4892
|
+
for (let depth = 0; depth <= SESSION_EVENT_PROTOTYPE_MAX_DEPTH; depth += 1) {
|
|
4893
|
+
if (candidate === null) return null;
|
|
4894
|
+
const descriptor = Object.getOwnPropertyDescriptor(candidate, "toJSON");
|
|
4895
|
+
if (descriptor) {
|
|
4896
|
+
return !("value" in descriptor) || typeof descriptor.value === "function" ? projection : null;
|
|
4897
|
+
}
|
|
4898
|
+
candidate = Object.getPrototypeOf(candidate);
|
|
4899
|
+
}
|
|
4900
|
+
return projection;
|
|
4901
|
+
} catch {
|
|
4902
|
+
return projection;
|
|
4903
|
+
}
|
|
4904
|
+
}
|
|
4905
|
+
var SESSION_EVENT_PROTOTYPE_MAX_DEPTH = 32;
|
|
4906
|
+
var SESSION_EVENT_ZERO_UUID = "00000000-0000-4000-8000-000000000000";
|
|
4907
|
+
var SESSION_EVENT_UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
4908
|
+
var SESSION_EVENT_OWN_DATA_FIELDS = [
|
|
4909
|
+
"id",
|
|
4910
|
+
"workspaceId",
|
|
4911
|
+
"sessionId",
|
|
4912
|
+
"sequence",
|
|
4913
|
+
"type",
|
|
4914
|
+
"payload",
|
|
4915
|
+
"occurredAt",
|
|
4916
|
+
"clientEventId",
|
|
4917
|
+
"turnId",
|
|
4918
|
+
"turnGeneration",
|
|
4919
|
+
"turnAttemptId",
|
|
4920
|
+
"turnAssociation",
|
|
4921
|
+
"duplicateOfEventId",
|
|
4922
|
+
"duplicateReason"
|
|
4923
|
+
];
|
|
4924
|
+
var SESSION_EVENT_KNOWN_ENUMERABLE_FIELDS = /* @__PURE__ */ new Set([
|
|
4925
|
+
...SESSION_EVENT_OWN_DATA_FIELDS,
|
|
4926
|
+
"toJSON"
|
|
4927
|
+
]);
|
|
4928
|
+
function sessionEventAdditionalTopLevelFieldProjection(event) {
|
|
4929
|
+
const projection = {
|
|
4930
|
+
field: "additionalTopLevelFields",
|
|
4931
|
+
originalBytes: null,
|
|
4932
|
+
deliveredBytes: 0
|
|
4933
|
+
};
|
|
4934
|
+
let inspected = 0;
|
|
4935
|
+
try {
|
|
4936
|
+
for (const key in event) {
|
|
4937
|
+
inspected += 1;
|
|
4938
|
+
if (inspected > SESSION_EVENT_KNOWN_ENUMERABLE_FIELDS.size + 1) return projection;
|
|
4939
|
+
const descriptor = Object.getOwnPropertyDescriptor(event, key);
|
|
4940
|
+
if (descriptor?.enumerable && !SESSION_EVENT_KNOWN_ENUMERABLE_FIELDS.has(key)) {
|
|
4941
|
+
return projection;
|
|
4942
|
+
}
|
|
4943
|
+
}
|
|
4944
|
+
return null;
|
|
4945
|
+
} catch {
|
|
4946
|
+
return projection;
|
|
4947
|
+
}
|
|
4948
|
+
}
|
|
4949
|
+
function sessionEventOwnDataFields(event) {
|
|
4950
|
+
return Object.fromEntries(
|
|
4951
|
+
SESSION_EVENT_OWN_DATA_FIELDS.map((key) => {
|
|
4952
|
+
try {
|
|
4953
|
+
const descriptor = Object.getOwnPropertyDescriptor(event, key);
|
|
4954
|
+
if (!descriptor) return [key, { readable: true, value: void 0 }];
|
|
4955
|
+
return [
|
|
4956
|
+
key,
|
|
4957
|
+
"value" in descriptor ? { readable: true, value: descriptor.value } : { readable: false }
|
|
4958
|
+
];
|
|
4959
|
+
} catch {
|
|
4960
|
+
return [key, { readable: false }];
|
|
4961
|
+
}
|
|
4962
|
+
})
|
|
4963
|
+
);
|
|
4964
|
+
}
|
|
4965
|
+
function canonicalSessionEventUuid(field, fallback) {
|
|
4966
|
+
return field.readable && typeof field.value === "string" && SESSION_EVENT_UUID_PATTERN.test(field.value) ? field.value : fallback;
|
|
4967
|
+
}
|
|
4968
|
+
function canonicalOptionalSessionEventUuid(field) {
|
|
4969
|
+
return field.readable && typeof field.value === "string" && SESSION_EVENT_UUID_PATTERN.test(field.value) ? field.value : null;
|
|
4970
|
+
}
|
|
4971
|
+
function canonicalSessionEventGeneration(field) {
|
|
4972
|
+
return field.readable && typeof field.value === "number" && Number.isSafeInteger(field.value) && field.value >= 0 ? field.value : null;
|
|
4973
|
+
}
|
|
4974
|
+
function sessionEventShouldEmitOptionalField(field) {
|
|
4975
|
+
return !field.readable || field.value !== void 0;
|
|
4976
|
+
}
|
|
4977
|
+
function sessionEventCanonicalFieldProjections(source, delivered) {
|
|
4978
|
+
return ["id", "workspaceId", "sessionId", "sequence", "occurredAt"].flatMap(
|
|
4979
|
+
(field) => {
|
|
4980
|
+
const original = source[field].readable ? source[field].value : void 0;
|
|
4981
|
+
return source[field].readable && original === delivered[field] ? [] : [
|
|
4982
|
+
sessionEventEnvelopeFieldProjection(
|
|
4983
|
+
field,
|
|
4984
|
+
original,
|
|
4985
|
+
delivered[field],
|
|
4986
|
+
source[field].readable
|
|
4987
|
+
)
|
|
4988
|
+
];
|
|
4989
|
+
}
|
|
4990
|
+
);
|
|
4991
|
+
}
|
|
4992
|
+
function sessionEventOptionalFieldProjections(source, delivered) {
|
|
4993
|
+
return ["turnId", "turnGeneration", "turnAttemptId", "duplicateOfEventId"].flatMap(
|
|
4994
|
+
(field) => {
|
|
4995
|
+
const original = source[field].readable ? source[field].value : void 0;
|
|
4996
|
+
const canonicalOriginal = original ?? null;
|
|
4997
|
+
return source[field].readable && canonicalOriginal === delivered[field] ? [] : [
|
|
4998
|
+
sessionEventEnvelopeFieldProjection(
|
|
4999
|
+
field,
|
|
5000
|
+
original,
|
|
5001
|
+
delivered[field],
|
|
5002
|
+
source[field].readable
|
|
5003
|
+
)
|
|
5004
|
+
];
|
|
5005
|
+
}
|
|
5006
|
+
);
|
|
5007
|
+
}
|
|
5008
|
+
function boundOptionalSessionEventText(value, maxBytes) {
|
|
5009
|
+
return typeof value === "string" ? boundSessionEventText(value, maxBytes) : value;
|
|
5010
|
+
}
|
|
5011
|
+
function boundSessionEventText(value, maxBytes) {
|
|
5012
|
+
const encoder2 = new TextEncoder();
|
|
5013
|
+
const decoder = new TextDecoder();
|
|
5014
|
+
const bytes = encoder2.encode(value);
|
|
5015
|
+
if (bytes.byteLength <= maxBytes) return value;
|
|
5016
|
+
const marker = "\u2026[truncated]";
|
|
5017
|
+
const markerBytes = encoder2.encode(marker).byteLength;
|
|
5018
|
+
const prefixBudget = Math.max(0, maxBytes - markerBytes);
|
|
5019
|
+
let prefixEnd = Math.min(prefixBudget, bytes.byteLength);
|
|
5020
|
+
while (prefixEnd > 0 && prefixEnd < bytes.byteLength && (bytes[prefixEnd] & 192) === 128) {
|
|
5021
|
+
prefixEnd -= 1;
|
|
5022
|
+
}
|
|
5023
|
+
return `${decoder.decode(bytes.subarray(0, prefixEnd))}${marker}`;
|
|
5024
|
+
}
|
|
5025
|
+
function sessionEventUtf8Bytes(value) {
|
|
5026
|
+
return new TextEncoder().encode(value).byteLength;
|
|
5027
|
+
}
|
|
5028
|
+
var SessionQueueMutationResponse = z.object({
|
|
5029
|
+
receipt: SessionCommandReceipt,
|
|
5030
|
+
snapshot: SessionQueueSnapshot,
|
|
5031
|
+
draft: ComposerDraft.optional()
|
|
5032
|
+
});
|
|
5033
|
+
var SessionControlResponse = z.object({
|
|
5034
|
+
receipt: SessionCommandReceipt,
|
|
5035
|
+
effectiveControl: EffectiveSessionControl,
|
|
5036
|
+
interruptionCount: z.number().int().nonnegative(),
|
|
5037
|
+
wakeCount: z.number().int().nonnegative()
|
|
5038
|
+
});
|
|
5039
|
+
var CreateSessionRequest = withVariableSetIdAlias({
|
|
5040
|
+
/**
|
|
5041
|
+
* Optional UUID preallocated by an embedding host. This lets the host durably
|
|
5042
|
+
* link its own projection before OpenGeni admits the initial turn. Replays
|
|
5043
|
+
* must pair it with the same idempotency key; OpenGeni never derives host
|
|
5044
|
+
* identity or authorization from the UUID.
|
|
5045
|
+
*/
|
|
5046
|
+
requestedSessionId: z.string().uuid().optional(),
|
|
2296
5047
|
initialMessage: z.string().min(1),
|
|
5048
|
+
// System-level host context for the initial turn only. Unlike `instructions`,
|
|
5049
|
+
// this does not persist into later turns and is never emitted as a user event.
|
|
5050
|
+
turnInstructions: z.string().trim().min(1).max(32768).optional(),
|
|
2297
5051
|
// Per-session agent persona/system instructions (org-visible metadata, NOT a
|
|
2298
5052
|
// secret). Rides the SAME system-level instructions channel the per-workspace
|
|
2299
5053
|
// agentInstructions rides, composed AFTER the workspace persona so it refines
|
|
@@ -2301,9 +5055,16 @@ var CreateSessionRequest = z.object({
|
|
|
2301
5055
|
// leaking them into the user-visible timeline (it is NEVER emitted as an
|
|
2302
5056
|
// event, unlike goal/initialMessage). Trimmed, non-empty. The 32768-char cap
|
|
2303
5057
|
// matches the codebase's largest free-form string convention (workspace
|
|
2304
|
-
//
|
|
5058
|
+
// variable set variable values). Absent ⇒ byte-identical to today.
|
|
2305
5059
|
instructions: z.string().trim().min(1).max(32768).optional(),
|
|
5060
|
+
// For an agent-created child, omission inherits the trusted immediate
|
|
5061
|
+
// parent's repository/file context. An explicit array, including [], is
|
|
5062
|
+
// authoritative. Top-level omission remains []. Presence is resolved from
|
|
5063
|
+
// the raw request because this Zod default erases absent-vs-empty.
|
|
2306
5064
|
resources: z.array(ResourceRef).default([]),
|
|
5065
|
+
// The same child omission rule applies to selected MCP tool refs. Top-level
|
|
5066
|
+
// omission still applies workspace-default capability MCP tools; explicit []
|
|
5067
|
+
// suppresses those defaults (the first-party OpenGeni server remains added).
|
|
2307
5068
|
tools: z.array(ToolRef).default([]),
|
|
2308
5069
|
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
2309
5070
|
model: z.string().min(1).optional(),
|
|
@@ -2320,11 +5081,17 @@ var CreateSessionRequest = z.object({
|
|
|
2320
5081
|
// (the agent's resolve_cwd handles both). Only valid WITH targetSandboxId
|
|
2321
5082
|
// (workingDir alone is a 422); omitted ⇒ the machine's default workspace_root.
|
|
2322
5083
|
workingDir: z.string().min(1).optional(),
|
|
2323
|
-
//
|
|
5084
|
+
// Variable set attachment is fixed at session creation; follow-up
|
|
2324
5085
|
// user.message events cannot switch or add one.
|
|
5086
|
+
variableSetId: z.string().uuid().optional(),
|
|
2325
5087
|
environmentId: z.string().uuid().optional(),
|
|
5088
|
+
// The rig to bind this session to (M3). Its ACTIVE version is resolved and
|
|
5089
|
+
// FROZEN onto the session at create. Omitted ⇒ the workspace's default rig
|
|
5090
|
+
// (workspaces.default_rig_id) when set, else a rig-less session (today's
|
|
5091
|
+
// behavior). An id that does not name a rig in the workspace is a 422.
|
|
5092
|
+
rigId: z.string().uuid().optional(),
|
|
2326
5093
|
goal: GoalSpec.optional(),
|
|
2327
|
-
clientEventId:
|
|
5094
|
+
clientEventId: SessionOperationKey.optional(),
|
|
2328
5095
|
// Workspace-scoped CREATE idempotency key: collapses concurrent/retried
|
|
2329
5096
|
// create calls carrying the same key to a single session (partial unique
|
|
2330
5097
|
// index on (workspace_id, create_idempotency_key)). Distinct from
|
|
@@ -2332,13 +5099,19 @@ var CreateSessionRequest = z.object({
|
|
|
2332
5099
|
// creation of a brand-new session. Absent means no create-dedup (each call
|
|
2333
5100
|
// is an independent create).
|
|
2334
5101
|
idempotencyKey: z.string().min(1).max(200).optional(),
|
|
2335
|
-
// Permissions the session's first-party MCP token should carry
|
|
2336
|
-
// the
|
|
2337
|
-
// the
|
|
2338
|
-
// requested permission must be held by the creating grant
|
|
5102
|
+
// Permissions the session's first-party MCP token should carry. A top-level
|
|
5103
|
+
// omission uses the deployment's worker default; a child omission inherits
|
|
5104
|
+
// the creating session's effective grant. An explicit set is capped at
|
|
5105
|
+
// creation: every requested permission must be held by the creating grant.
|
|
5106
|
+
// A goal-bearing session whose explicit/effective set omits goals:manage is
|
|
5107
|
+
// rejected; creation never silently expands a child beyond that set.
|
|
2339
5108
|
firstPartyMcpPermissions: z.array(Permission).optional(),
|
|
2340
|
-
// Third-party MCP servers attached only to this session.
|
|
2341
|
-
//
|
|
5109
|
+
// Third-party MCP servers attached only to this session. For an agent-created
|
|
5110
|
+
// child, omission snapshots its trusted immediate parent's server definitions,
|
|
5111
|
+
// policies, connection refs, and encrypted credentials. Explicit arrays,
|
|
5112
|
+
// including [], are authoritative; non-empty explicit arrays require attach
|
|
5113
|
+
// permission. Credential headers are write-only: create responses and events
|
|
5114
|
+
// expose only SessionMcpServerMetadata.
|
|
2342
5115
|
mcpServers: z.array(SessionMcpServerInput).default([]),
|
|
2343
5116
|
// Shared-sandbox placement (addendum 05 §D.1). Three-way union; OMITTED ⇒
|
|
2344
5117
|
// today's behavior (a context-dependent default resolved server-side: from
|
|
@@ -2352,47 +5125,195 @@ var CreateSessionRequest = z.object({
|
|
|
2352
5125
|
// A shared spawn inherits the box's (backend, os) — it is literally the same
|
|
2353
5126
|
// box; the child cannot pick its own backend. Cross-workspace sharing is
|
|
2354
5127
|
// forbidden by construction (the parent/group reads are RLS-workspace-scoped).
|
|
2355
|
-
// ENV-AWARE: the box's
|
|
2356
|
-
// the SAME
|
|
5128
|
+
// ENV-AWARE: the box's variable set is fixed at creation, so a share requires
|
|
5129
|
+
// the SAME variableSetId as the creator's box. On a mismatch the inherited
|
|
2357
5130
|
// default silently falls back to an own box; an explicit "shared"/{groupId}
|
|
2358
5131
|
// request 422s at create (instead of the first turn dying on the SDK's
|
|
2359
5132
|
// manifest-env guard).
|
|
2360
|
-
sandbox: z.union([
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
5133
|
+
sandbox: z.union([z.literal("shared"), z.literal("new"), z.object({ groupId: z.string().uuid() })]).optional()
|
|
5134
|
+
});
|
|
5135
|
+
var HumanInputQuestionKind = z.enum(["text", "single_select", "multi_select"]);
|
|
5136
|
+
var HumanInputOption = z.object({
|
|
5137
|
+
id: z.string().min(1).max(64),
|
|
5138
|
+
label: z.string().min(1).max(256),
|
|
5139
|
+
description: z.string().max(2048).nullable().optional()
|
|
5140
|
+
});
|
|
5141
|
+
var HumanInputQuestion = z.object({
|
|
5142
|
+
id: z.string().min(1).max(64),
|
|
5143
|
+
kind: HumanInputQuestionKind,
|
|
5144
|
+
prompt: z.string().min(1).max(4096),
|
|
5145
|
+
label: z.string().min(1).max(128).nullable().optional(),
|
|
5146
|
+
helpText: z.string().max(2048).nullable().optional(),
|
|
5147
|
+
options: z.array(HumanInputOption).max(20).default([]),
|
|
5148
|
+
required: z.boolean().default(true),
|
|
5149
|
+
allowOther: z.boolean().default(false),
|
|
5150
|
+
validation: z.object({
|
|
5151
|
+
minLength: z.number().int().nonnegative().max(8192).nullable().optional(),
|
|
5152
|
+
maxLength: z.number().int().positive().max(8192).nullable().optional(),
|
|
5153
|
+
minSelections: z.number().int().nonnegative().max(20).nullable().optional(),
|
|
5154
|
+
maxSelections: z.number().int().positive().max(20).nullable().optional()
|
|
5155
|
+
}).nullable().optional()
|
|
5156
|
+
}).superRefine((question, ctx) => {
|
|
5157
|
+
const optionIds = new Set(question.options.map((option) => option.id));
|
|
5158
|
+
if (optionIds.size !== question.options.length) {
|
|
5159
|
+
ctx.addIssue({
|
|
5160
|
+
code: "custom",
|
|
5161
|
+
path: ["options"],
|
|
5162
|
+
message: "option ids must be unique"
|
|
5163
|
+
});
|
|
5164
|
+
}
|
|
5165
|
+
if (question.kind === "text") {
|
|
5166
|
+
if (question.options.length > 0) {
|
|
5167
|
+
ctx.addIssue({
|
|
5168
|
+
code: "custom",
|
|
5169
|
+
path: ["options"],
|
|
5170
|
+
message: "text questions cannot have options"
|
|
5171
|
+
});
|
|
5172
|
+
}
|
|
5173
|
+
if (question.allowOther) {
|
|
5174
|
+
ctx.addIssue({
|
|
5175
|
+
code: "custom",
|
|
5176
|
+
path: ["allowOther"],
|
|
5177
|
+
message: "text questions do not use Other"
|
|
5178
|
+
});
|
|
5179
|
+
}
|
|
5180
|
+
} else if (question.options.length === 0) {
|
|
5181
|
+
ctx.addIssue({
|
|
5182
|
+
code: "custom",
|
|
5183
|
+
path: ["options"],
|
|
5184
|
+
message: "select questions require options"
|
|
5185
|
+
});
|
|
5186
|
+
}
|
|
5187
|
+
const validation = question.validation;
|
|
5188
|
+
if (validation?.minLength != null && validation?.maxLength != null && validation.minLength > validation.maxLength) {
|
|
5189
|
+
ctx.addIssue({
|
|
5190
|
+
code: "custom",
|
|
5191
|
+
path: ["validation"],
|
|
5192
|
+
message: "minLength exceeds maxLength"
|
|
5193
|
+
});
|
|
5194
|
+
}
|
|
5195
|
+
if (validation?.minSelections != null && validation?.maxSelections != null && validation.minSelections > validation.maxSelections) {
|
|
5196
|
+
ctx.addIssue({
|
|
5197
|
+
code: "custom",
|
|
5198
|
+
path: ["validation"],
|
|
5199
|
+
message: "minSelections exceeds maxSelections"
|
|
5200
|
+
});
|
|
5201
|
+
}
|
|
5202
|
+
});
|
|
5203
|
+
var HumanInputRequestStatus = z.enum([
|
|
5204
|
+
"pending",
|
|
5205
|
+
"answered",
|
|
5206
|
+
"skipped",
|
|
5207
|
+
"expired",
|
|
5208
|
+
"cancelled"
|
|
5209
|
+
]);
|
|
5210
|
+
var RequestHumanInputToolInput = z.object({
|
|
5211
|
+
questions: z.array(HumanInputQuestion).min(1).max(20),
|
|
5212
|
+
allowSkip: z.boolean().default(false),
|
|
5213
|
+
expiresInSeconds: z.number().int().positive().max(30 * 24 * 60 * 60).nullable().optional()
|
|
5214
|
+
});
|
|
5215
|
+
var HumanInputAnswer = z.object({
|
|
5216
|
+
questionId: z.string().min(1).max(64),
|
|
5217
|
+
values: z.array(z.string().max(8192)).max(20),
|
|
5218
|
+
other: z.string().max(8192).nullable().optional()
|
|
5219
|
+
});
|
|
5220
|
+
var HumanInputResponse = z.discriminatedUnion("outcome", [
|
|
5221
|
+
z.object({
|
|
5222
|
+
outcome: z.literal("answered"),
|
|
5223
|
+
answers: z.array(HumanInputAnswer).max(20)
|
|
5224
|
+
}),
|
|
5225
|
+
z.object({ outcome: z.literal("skipped") }),
|
|
5226
|
+
z.object({ outcome: z.literal("expired") }),
|
|
5227
|
+
z.object({ outcome: z.literal("cancelled") })
|
|
5228
|
+
]);
|
|
5229
|
+
var SubmitHumanInputResponseRequest = z.discriminatedUnion("outcome", [
|
|
5230
|
+
z.object({
|
|
5231
|
+
outcome: z.literal("answered"),
|
|
5232
|
+
answers: z.array(HumanInputAnswer).max(20)
|
|
5233
|
+
}),
|
|
5234
|
+
z.object({ outcome: z.literal("skipped") })
|
|
5235
|
+
]);
|
|
5236
|
+
var SessionHumanInputRequest = z.object({
|
|
5237
|
+
id: z.string().uuid(),
|
|
5238
|
+
workspaceId: z.string().uuid(),
|
|
5239
|
+
sessionId: z.string().uuid(),
|
|
5240
|
+
turnId: z.string().uuid(),
|
|
5241
|
+
turnGeneration: z.number().int().positive(),
|
|
5242
|
+
creationAttemptId: z.string().uuid(),
|
|
5243
|
+
toolCallId: z.string().min(1).max(1024),
|
|
5244
|
+
status: HumanInputRequestStatus,
|
|
5245
|
+
questions: z.array(HumanInputQuestion).min(1).max(20),
|
|
5246
|
+
allowSkip: z.boolean(),
|
|
5247
|
+
response: HumanInputResponse.nullable(),
|
|
5248
|
+
respondedBy: z.string().max(1024).nullable(),
|
|
5249
|
+
respondedAt: z.string().nullable(),
|
|
5250
|
+
expiresAt: z.string().nullable(),
|
|
5251
|
+
createdAt: z.string(),
|
|
5252
|
+
updatedAt: z.string()
|
|
2365
5253
|
});
|
|
5254
|
+
function approvalIdentifier(value) {
|
|
5255
|
+
if (!value || typeof value !== "object") return null;
|
|
5256
|
+
const approval = value;
|
|
5257
|
+
const rawItem = approval.rawItem && typeof approval.rawItem === "object" ? approval.rawItem : null;
|
|
5258
|
+
const candidate = rawItem?.callId ?? rawItem?.id ?? approval.id ?? approval.name;
|
|
5259
|
+
if (typeof candidate !== "string" && typeof candidate !== "number") return null;
|
|
5260
|
+
return String(candidate);
|
|
5261
|
+
}
|
|
2366
5262
|
var ClientSessionEvent = z.discriminatedUnion("type", [
|
|
2367
5263
|
z.object({
|
|
2368
5264
|
type: z.literal("user.message"),
|
|
2369
|
-
clientEventId:
|
|
5265
|
+
clientEventId: SessionOperationKey.optional(),
|
|
2370
5266
|
payload: z.object({
|
|
2371
5267
|
text: z.string().min(1),
|
|
5268
|
+
// System-level host context for this exact turn only. Persisted on the
|
|
5269
|
+
// turn for retry/recovery, never copied into the visible user message.
|
|
5270
|
+
turnInstructions: z.string().trim().min(1).max(32768).optional(),
|
|
2372
5271
|
resources: z.array(ResourceRef).default([]),
|
|
2373
5272
|
tools: z.array(ToolRef).default([]),
|
|
2374
5273
|
model: z.string().min(1).optional(),
|
|
2375
5274
|
reasoningEffort: ReasoningEffort.optional(),
|
|
5275
|
+
controlEtag: z.string().min(1).optional(),
|
|
5276
|
+
expectedDraftRevision: z.number().int().nonnegative().optional(),
|
|
2376
5277
|
// Header-value rotation only. URL/name/tool settings are immutable after
|
|
2377
5278
|
// session create; persisted events expose metadata, never header values.
|
|
2378
5279
|
mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional()
|
|
2379
5280
|
})
|
|
2380
5281
|
}),
|
|
2381
|
-
z.object({
|
|
2382
|
-
type: z.literal("user.interrupt"),
|
|
2383
|
-
clientEventId: z.string().min(1).optional(),
|
|
2384
|
-
payload: z.object({ reason: z.string().optional() }).default({})
|
|
2385
|
-
}),
|
|
2386
5282
|
z.object({
|
|
2387
5283
|
type: z.literal("user.approvalDecision"),
|
|
2388
|
-
clientEventId:
|
|
5284
|
+
clientEventId: SessionOperationKey.optional(),
|
|
2389
5285
|
payload: z.object({
|
|
2390
|
-
approvalId: z.string().min(1),
|
|
5286
|
+
approvalId: z.string().min(1).max(SESSION_OPERATION_KEY_MAX_CHARS),
|
|
2391
5287
|
decision: z.enum(["approve", "reject"]),
|
|
2392
5288
|
message: z.string().optional()
|
|
2393
5289
|
})
|
|
5290
|
+
}),
|
|
5291
|
+
z.object({
|
|
5292
|
+
type: z.literal("user.humanInputResponse"),
|
|
5293
|
+
clientEventId: SessionOperationKey.optional(),
|
|
5294
|
+
payload: z.object({
|
|
5295
|
+
requestId: z.string().uuid(),
|
|
5296
|
+
response: SubmitHumanInputResponseRequest
|
|
5297
|
+
})
|
|
2394
5298
|
})
|
|
2395
5299
|
]);
|
|
5300
|
+
var SteerSessionMessageRequest = z.object({
|
|
5301
|
+
text: z.string().min(1),
|
|
5302
|
+
// Same per-turn system-level context as a queued user.message.
|
|
5303
|
+
turnInstructions: z.string().trim().min(1).max(32768).optional(),
|
|
5304
|
+
resources: z.array(ResourceRef).default([]),
|
|
5305
|
+
tools: z.array(ToolRef).default([]),
|
|
5306
|
+
model: z.string().min(1).optional(),
|
|
5307
|
+
reasoningEffort: ReasoningEffort.optional(),
|
|
5308
|
+
clientEventId: SessionOperationKey.optional(),
|
|
5309
|
+
controlEtag: z.string().min(1).optional(),
|
|
5310
|
+
expectedDraftRevision: z.number().int().nonnegative().optional(),
|
|
5311
|
+
mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional()
|
|
5312
|
+
});
|
|
5313
|
+
var SteerSessionMessageResponse = z.object({
|
|
5314
|
+
accepted: SessionEvent,
|
|
5315
|
+
turn: SessionTurn
|
|
5316
|
+
});
|
|
2396
5317
|
var SessionBusMessage = z.object({
|
|
2397
5318
|
workspaceId: z.string().uuid(),
|
|
2398
5319
|
sessionId: z.string().uuid(),
|
|
@@ -2416,6 +5337,29 @@ var GitHubRepository = z.object({
|
|
|
2416
5337
|
accountLogin: z.string(),
|
|
2417
5338
|
accountType: z.string().nullable()
|
|
2418
5339
|
});
|
|
5340
|
+
var GitHubRepositoryScope = z.enum(["all", "selected"]);
|
|
5341
|
+
var GitHubInstallationBinding = z.object({
|
|
5342
|
+
installationId: z.number().int().positive(),
|
|
5343
|
+
accountLogin: z.string().nullable(),
|
|
5344
|
+
accountType: z.string().nullable(),
|
|
5345
|
+
repositoryScope: GitHubRepositoryScope,
|
|
5346
|
+
repositoryCount: z.number().int().nonnegative(),
|
|
5347
|
+
createdAt: z.string(),
|
|
5348
|
+
updatedAt: z.string()
|
|
5349
|
+
});
|
|
5350
|
+
var GitHubAppInfo = z.object({
|
|
5351
|
+
configured: z.boolean(),
|
|
5352
|
+
appId: z.string().nullable(),
|
|
5353
|
+
clientId: z.string().nullable(),
|
|
5354
|
+
appSlug: z.string().nullable(),
|
|
5355
|
+
installUrl: z.string().nullable(),
|
|
5356
|
+
linkUrl: z.string().nullable(),
|
|
5357
|
+
installations: z.array(GitHubInstallationBinding),
|
|
5358
|
+
missing: z.array(z.string())
|
|
5359
|
+
});
|
|
5360
|
+
var GitHubRepositoriesResponse = z.object({
|
|
5361
|
+
repositories: z.array(GitHubRepository)
|
|
5362
|
+
});
|
|
2419
5363
|
var ClientAuthConfig = z.discriminatedUnion("mode", [
|
|
2420
5364
|
z.object({
|
|
2421
5365
|
mode: z.literal("none")
|
|
@@ -2544,7 +5488,7 @@ var ViewerHolder = z.object({
|
|
|
2544
5488
|
leaseEpoch: z.number().int().nonnegative(),
|
|
2545
5489
|
viewerHeartbeatIntervalMs: z.number().int().positive(),
|
|
2546
5490
|
// The desktop pixel tunnel URL the viewer connects to directly; null until
|
|
2547
|
-
//
|
|
5491
|
+
// a viewer grant is minted (gated until then).
|
|
2548
5492
|
dataPlaneUrl: z.string().nullable()
|
|
2549
5493
|
});
|
|
2550
5494
|
var AcknowledgeStreamRequest = z.object({
|
|
@@ -2611,7 +5555,13 @@ var DeviceEnrollmentApproveResponse = z.object({
|
|
|
2611
5555
|
var DeviceEnrollmentPollRequest = z.object({
|
|
2612
5556
|
deviceCode: z.string().min(1).max(256)
|
|
2613
5557
|
});
|
|
2614
|
-
var DeviceEnrollmentState = z.enum([
|
|
5558
|
+
var DeviceEnrollmentState = z.enum([
|
|
5559
|
+
"pending",
|
|
5560
|
+
"authorized",
|
|
5561
|
+
"denied",
|
|
5562
|
+
"expired",
|
|
5563
|
+
"disabled"
|
|
5564
|
+
]);
|
|
2615
5565
|
var EnrollmentCredentialsResponse = z.object({
|
|
2616
5566
|
agentId: z.string().uuid(),
|
|
2617
5567
|
workspaceId: z.string().uuid(),
|
|
@@ -2774,7 +5724,18 @@ var SwapActiveSandboxResponse = z.object({
|
|
|
2774
5724
|
swapped: z.boolean(),
|
|
2775
5725
|
activeSandboxId: z.string().nullable(),
|
|
2776
5726
|
activeEpoch: z.number().int(),
|
|
2777
|
-
reason: z.string().optional()
|
|
5727
|
+
reason: z.string().optional(),
|
|
5728
|
+
// Typed rejection discriminant (issue #341). Present only when swapped is false,
|
|
5729
|
+
// so a client distinguishes a deleted/absent target from an unaddressable
|
|
5730
|
+
// enrollment from a backend the turn cannot establish from a lost epoch race —
|
|
5731
|
+
// without parsing the human reason string.
|
|
5732
|
+
code: z.enum([
|
|
5733
|
+
"stale_pointer",
|
|
5734
|
+
"offline_enrollment",
|
|
5735
|
+
"unsupported_backend_context",
|
|
5736
|
+
"transient_establishment",
|
|
5737
|
+
"concurrent_swap"
|
|
5738
|
+
]).optional()
|
|
2778
5739
|
});
|
|
2779
5740
|
var MachineMetricsSeriesResponse = z.object({
|
|
2780
5741
|
samples: z.array(MetricSample)
|
|
@@ -2788,8 +5749,11 @@ var ClientModel = z.object({
|
|
|
2788
5749
|
api: z.enum(["responses", "chat"]),
|
|
2789
5750
|
contextWindowTokens: z.number().int().positive().optional()
|
|
2790
5751
|
});
|
|
5752
|
+
var OPENGENI_API_CONTRACT_REVISION = "2026-07-turn-instructions-v1";
|
|
5753
|
+
var OPENGENI_API_CONTRACT_HEADER = "x-opengeni-api-contract";
|
|
2791
5754
|
var ClientConfig = z.object({
|
|
2792
5755
|
deploymentRevision: z.string(),
|
|
5756
|
+
apiContractRevision: z.literal(OPENGENI_API_CONTRACT_REVISION),
|
|
2793
5757
|
// Release-train version of the server (absent on dev/source builds). The
|
|
2794
5758
|
// compatibility policy lives in docs/architecture.md — clients within the
|
|
2795
5759
|
// same major are supported; evolution is additive within a major.
|
|
@@ -2801,10 +5765,12 @@ var ClientConfig = z.object({
|
|
|
2801
5765
|
models: z.array(ClientModel).default([]),
|
|
2802
5766
|
defaultReasoningEffort: ReasoningEffort,
|
|
2803
5767
|
allowedReasoningEfforts: z.array(ReasoningEffort).min(1),
|
|
2804
|
-
mcpServers: z.array(
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
5768
|
+
mcpServers: z.array(
|
|
5769
|
+
z.object({
|
|
5770
|
+
id: z.string(),
|
|
5771
|
+
name: z.string()
|
|
5772
|
+
})
|
|
5773
|
+
).default([]),
|
|
2808
5774
|
fileUploads: z.object({
|
|
2809
5775
|
enabled: z.boolean(),
|
|
2810
5776
|
maxSizeBytes: z.number().int().positive()
|
|
@@ -2850,6 +5816,18 @@ function constantTimeEqual(actual, expected) {
|
|
|
2850
5816
|
}
|
|
2851
5817
|
return diff === 0;
|
|
2852
5818
|
}
|
|
5819
|
+
function evaluateWorkspaceModelPolicy(policy, candidate) {
|
|
5820
|
+
if (!policy) {
|
|
5821
|
+
return { allowed: true };
|
|
5822
|
+
}
|
|
5823
|
+
if (policy.allowedProviders !== null && !policy.allowedProviders.includes(candidate.providerId)) {
|
|
5824
|
+
return { allowed: false, reason: "provider" };
|
|
5825
|
+
}
|
|
5826
|
+
if (policy.allowedModels !== null && !policy.allowedModels.includes(candidate.modelId)) {
|
|
5827
|
+
return { allowed: false, reason: "model" };
|
|
5828
|
+
}
|
|
5829
|
+
return { allowed: true };
|
|
5830
|
+
}
|
|
2853
5831
|
export {
|
|
2854
5832
|
AccessContext,
|
|
2855
5833
|
AccessGrant,
|
|
@@ -2891,6 +5869,7 @@ export {
|
|
|
2891
5869
|
CompactSessionContextRequest,
|
|
2892
5870
|
CompactSessionContextResult,
|
|
2893
5871
|
CompleteFileUploadResponse,
|
|
5872
|
+
ComposerDraft,
|
|
2894
5873
|
ConnectionCredentialBundle,
|
|
2895
5874
|
ConnectionKind,
|
|
2896
5875
|
ConnectionMetadata,
|
|
@@ -2906,14 +5885,19 @@ export {
|
|
|
2906
5885
|
CreateFileUploadRequest,
|
|
2907
5886
|
CreateFileUploadResponse,
|
|
2908
5887
|
CreateKnowledgeMemoryRequest,
|
|
5888
|
+
CreateRigRequest,
|
|
2909
5889
|
CreateScheduledTaskRequest,
|
|
2910
5890
|
CreateSessionRequest,
|
|
5891
|
+
CreateSessionResponse,
|
|
2911
5892
|
CreateSocialConnectionRequest,
|
|
2912
5893
|
CreateSocialPostRequest,
|
|
5894
|
+
CreateVariableSetRequest,
|
|
2913
5895
|
CreateWorkspaceEnvironmentRequest,
|
|
2914
5896
|
CreateWorkspaceRequest,
|
|
5897
|
+
CredentialAuthNeededPayload,
|
|
2915
5898
|
DESKTOP_STREAM_PORT,
|
|
2916
5899
|
DelegatedAccessTokenPayload,
|
|
5900
|
+
DeleteSessionQueueItemRequest,
|
|
2917
5901
|
DeviceEnrollmentApproveRequest,
|
|
2918
5902
|
DeviceEnrollmentApproveResponse,
|
|
2919
5903
|
DeviceEnrollmentDenyRequest,
|
|
@@ -2933,6 +5917,10 @@ export {
|
|
|
2933
5917
|
DocumentSearchRequest,
|
|
2934
5918
|
DocumentSearchResult,
|
|
2935
5919
|
DocumentStatus,
|
|
5920
|
+
EditSessionQueueItemRequest,
|
|
5921
|
+
EffectiveControlBlocker,
|
|
5922
|
+
EffectiveControlResumeOption,
|
|
5923
|
+
EffectiveSessionControl,
|
|
2936
5924
|
EnableCapabilityRequest,
|
|
2937
5925
|
EnablePackRequest,
|
|
2938
5926
|
EnrollTokenExchangeRequest,
|
|
@@ -2971,8 +5959,13 @@ export {
|
|
|
2971
5959
|
FsTreeNode,
|
|
2972
5960
|
FsWriteRequest,
|
|
2973
5961
|
FsWriteResponse,
|
|
5962
|
+
GetWorkspaceCaptureFileResponse,
|
|
5963
|
+
GetWorkspaceCaptureResponse,
|
|
2974
5964
|
GitChangedPayload,
|
|
2975
5965
|
GitCommit,
|
|
5966
|
+
GitCredentialBindingId,
|
|
5967
|
+
GitCredentialProvider,
|
|
5968
|
+
GitCredentialRepositoryRef,
|
|
2976
5969
|
GitDiffHunk,
|
|
2977
5970
|
GitDiffLine,
|
|
2978
5971
|
GitDiffLineType,
|
|
@@ -2981,15 +5974,36 @@ export {
|
|
|
2981
5974
|
GitFileDiff,
|
|
2982
5975
|
GitFileStatus,
|
|
2983
5976
|
GitFileStatusCode,
|
|
5977
|
+
GitHubAppInfo,
|
|
2984
5978
|
GitHubAppManifestCreate,
|
|
5979
|
+
GitHubInstallationBinding,
|
|
5980
|
+
GitHubRepositoriesResponse,
|
|
2985
5981
|
GitHubRepository,
|
|
5982
|
+
GitHubRepositoryScope,
|
|
2986
5983
|
GitLogRequest,
|
|
2987
5984
|
GitLogResponse,
|
|
5985
|
+
GitRepositoryAccess,
|
|
2988
5986
|
GitShowRequest,
|
|
2989
5987
|
GitShowResponse,
|
|
2990
5988
|
GitStatusRequest,
|
|
2991
5989
|
GitStatusResponse,
|
|
2992
5990
|
GoalSpec,
|
|
5991
|
+
HostEventExport,
|
|
5992
|
+
HostEventExportBatch,
|
|
5993
|
+
HostExportConsumerId,
|
|
5994
|
+
HostExportCursor,
|
|
5995
|
+
HostExportInitiator,
|
|
5996
|
+
HostExportInitiatorContext,
|
|
5997
|
+
HostSessionEvent,
|
|
5998
|
+
HostUsageEvent,
|
|
5999
|
+
HostUsageExport,
|
|
6000
|
+
HostUsageExportBatch,
|
|
6001
|
+
HumanInputAnswer,
|
|
6002
|
+
HumanInputOption,
|
|
6003
|
+
HumanInputQuestion,
|
|
6004
|
+
HumanInputQuestionKind,
|
|
6005
|
+
HumanInputRequestStatus,
|
|
6006
|
+
HumanInputResponse,
|
|
2993
6007
|
IntegrationClientMetadata,
|
|
2994
6008
|
KnowledgeMemory,
|
|
2995
6009
|
KnowledgeMemoryKind,
|
|
@@ -2999,6 +6013,7 @@ export {
|
|
|
2999
6013
|
KnowledgeSourceRef,
|
|
3000
6014
|
LimitAction,
|
|
3001
6015
|
LimitDecision,
|
|
6016
|
+
LineageNode,
|
|
3002
6017
|
ListConnectionsResponse,
|
|
3003
6018
|
ListEnrollmentsResponse,
|
|
3004
6019
|
ListWorkspaceMembersResponse,
|
|
@@ -3009,16 +6024,22 @@ export {
|
|
|
3009
6024
|
MachinesResponse,
|
|
3010
6025
|
ManagedAccount,
|
|
3011
6026
|
MarketingDailyAnalysisTaskRequest,
|
|
6027
|
+
McpConnectionResourceScope,
|
|
3012
6028
|
McpServerConnectionRef,
|
|
3013
6029
|
MetricSample,
|
|
3014
6030
|
MintEnrollTokenRequest,
|
|
3015
6031
|
MintEnrollTokenResponse,
|
|
6032
|
+
MoveSessionQueueItemRequest,
|
|
3016
6033
|
OAuthStartRequest,
|
|
3017
6034
|
OAuthStartResponse,
|
|
6035
|
+
OPENGENI_API_CONTRACT_HEADER,
|
|
6036
|
+
OPENGENI_API_CONTRACT_REVISION,
|
|
6037
|
+
OPENGENI_HOST_EXPORT_SCHEMA_REVISION,
|
|
3018
6038
|
PackInstallation,
|
|
3019
6039
|
PackInstallationStatus,
|
|
3020
6040
|
Permission,
|
|
3021
6041
|
ProductAccessMode,
|
|
6042
|
+
ProposeRigChangeRequest,
|
|
3022
6043
|
PtyCloseRequest,
|
|
3023
6044
|
PtyOpenRequest,
|
|
3024
6045
|
PtyOpenResponse,
|
|
@@ -3034,15 +6055,38 @@ export {
|
|
|
3034
6055
|
RecordingStartedPayload,
|
|
3035
6056
|
RegisterCapabilityPackRequest,
|
|
3036
6057
|
RelayTokenPayload,
|
|
3037
|
-
ReorderSessionTurnsRequest,
|
|
3038
6058
|
RepositoryResourceRef,
|
|
6059
|
+
RequestHumanInputToolInput,
|
|
6060
|
+
ResourceMountPathError,
|
|
3039
6061
|
ResourceRef,
|
|
3040
6062
|
ResourceRefConflictError,
|
|
3041
6063
|
RevokeEnrollmentResponse,
|
|
6064
|
+
Rig,
|
|
6065
|
+
RigChange,
|
|
6066
|
+
RigChangeKind,
|
|
6067
|
+
RigChangeStatus,
|
|
6068
|
+
RigChangeVerification,
|
|
6069
|
+
RigCheck,
|
|
6070
|
+
RigCheckResult,
|
|
6071
|
+
RigDefinitionEditPayload,
|
|
6072
|
+
RigSetupAppendPayload,
|
|
6073
|
+
RigVerificationHealth,
|
|
6074
|
+
RigVersion,
|
|
6075
|
+
SESSION_AUTHORIZATION_LIST_SCOPE_MAX_IDS,
|
|
6076
|
+
SESSION_EVENT_CLIENT_EVENT_ID_MAX_BYTES,
|
|
6077
|
+
SESSION_EVENT_DUPLICATE_REASON_MAX_BYTES,
|
|
6078
|
+
SESSION_EVENT_ENVELOPE_MAX_BYTES,
|
|
6079
|
+
SESSION_EVENT_PAYLOAD_MAX_BYTES,
|
|
6080
|
+
SESSION_EVENT_RAW_DELTA_TYPES,
|
|
6081
|
+
SESSION_EVENT_SEMANTIC_CLASS_TYPES,
|
|
6082
|
+
SESSION_EVENT_TURN_ASSOCIATION_MAX_BYTES,
|
|
6083
|
+
SESSION_EVENT_TYPE_MAX_BYTES,
|
|
6084
|
+
SESSION_OPERATION_KEY_MAX_CHARS,
|
|
3042
6085
|
SandboxBackend,
|
|
3043
6086
|
SandboxCapabilityName,
|
|
3044
6087
|
SandboxCommandOutputDeltaPayload,
|
|
3045
6088
|
SandboxOs,
|
|
6089
|
+
SaveComposerDraftRequest,
|
|
3046
6090
|
ScheduledTask,
|
|
3047
6091
|
ScheduledTaskAgentConfig,
|
|
3048
6092
|
ScheduledTaskOverlapPolicy,
|
|
@@ -3052,36 +6096,68 @@ export {
|
|
|
3052
6096
|
ScheduledTaskScheduleSpec,
|
|
3053
6097
|
ScheduledTaskStatus,
|
|
3054
6098
|
ScheduledTaskTriggerType,
|
|
6099
|
+
ServiceTurnInitiator,
|
|
6100
|
+
ServiceTurnInitiatorContext,
|
|
3055
6101
|
Session,
|
|
6102
|
+
SessionAuthorizationActor,
|
|
6103
|
+
SessionAuthorizationDecision,
|
|
6104
|
+
SessionAuthorizationListScope,
|
|
6105
|
+
SessionAuthorizationOperation,
|
|
6106
|
+
SessionAuthorizationSurface,
|
|
6107
|
+
SessionAuthorizationTarget,
|
|
3056
6108
|
SessionBusMessage,
|
|
3057
6109
|
SessionCapabilities,
|
|
6110
|
+
SessionCommandReceipt,
|
|
6111
|
+
SessionControlRequest,
|
|
6112
|
+
SessionControlResponse,
|
|
6113
|
+
SessionControlState,
|
|
3058
6114
|
SessionEvent,
|
|
6115
|
+
SessionEventPayloadMode,
|
|
6116
|
+
SessionEventReadDirection,
|
|
6117
|
+
SessionEventReadMode,
|
|
6118
|
+
SessionEventSemanticClass,
|
|
3059
6119
|
SessionEventType,
|
|
3060
6120
|
SessionGoal,
|
|
3061
6121
|
SessionGoalCreatedBy,
|
|
3062
6122
|
SessionGoalPausedReason,
|
|
3063
6123
|
SessionGoalStatus,
|
|
6124
|
+
SessionHumanInputRequest,
|
|
6125
|
+
SessionLineageResponse,
|
|
6126
|
+
SessionListResponse,
|
|
3064
6127
|
SessionMcpCredentialUpdateInput,
|
|
3065
6128
|
SessionMcpServerInput,
|
|
3066
6129
|
SessionMcpServerMetadata,
|
|
6130
|
+
SessionQueueMutationResponse,
|
|
6131
|
+
SessionQueueSnapshot,
|
|
3067
6132
|
SessionStatus,
|
|
3068
6133
|
SessionStructuredCapabilities,
|
|
6134
|
+
SessionSystemUpdate,
|
|
6135
|
+
SessionSystemUpdateKind,
|
|
6136
|
+
SessionSystemUpdatePayload,
|
|
6137
|
+
SessionSystemUpdateState,
|
|
3069
6138
|
SessionTurn,
|
|
3070
6139
|
SessionTurnSource,
|
|
3071
6140
|
SessionTurnStatus,
|
|
6141
|
+
SetVariableSetVariableRequest,
|
|
6142
|
+
SetWorkspaceDefaultRigRequest,
|
|
3072
6143
|
SetWorkspaceEnvironmentVariableRequest,
|
|
3073
6144
|
SocialConnection,
|
|
3074
6145
|
SocialConnectionStatus,
|
|
3075
6146
|
SocialPost,
|
|
3076
6147
|
SocialProvider,
|
|
3077
6148
|
StaticUsageLimits,
|
|
6149
|
+
SteerSessionMessageRequest,
|
|
6150
|
+
SteerSessionMessageResponse,
|
|
6151
|
+
SteerSessionQueueItemRequest,
|
|
3078
6152
|
StreamClosedPayload,
|
|
3079
6153
|
StreamOpenedPayload,
|
|
3080
6154
|
StreamRevokedPayload,
|
|
3081
6155
|
StreamTokenPayload,
|
|
3082
6156
|
StreamUrlRotatedPayload,
|
|
6157
|
+
SubmitHumanInputResponseRequest,
|
|
3083
6158
|
SwapActiveSandboxRequest,
|
|
3084
6159
|
SwapActiveSandboxResponse,
|
|
6160
|
+
SystemUpdateClassification,
|
|
3085
6161
|
TERMINAL_STREAM_PORT,
|
|
3086
6162
|
TerminalExecRequest,
|
|
3087
6163
|
TerminalExecResponse,
|
|
@@ -3090,34 +6166,93 @@ export {
|
|
|
3090
6166
|
TerminalPtyStartedPayload,
|
|
3091
6167
|
ToolAuthNeededPayload,
|
|
3092
6168
|
ToolRef,
|
|
6169
|
+
TranscriptionErrorCode,
|
|
6170
|
+
TranscriptionEvent,
|
|
6171
|
+
TranscriptionResultMetadata,
|
|
6172
|
+
TranscriptionSpeaker,
|
|
6173
|
+
TranscriptionTimeSpan,
|
|
6174
|
+
TranscriptionWord,
|
|
3093
6175
|
TriggerScheduledTaskRequest,
|
|
6176
|
+
TurnInitiator,
|
|
6177
|
+
TurnInitiatorContext,
|
|
6178
|
+
UNATTRIBUTED_LEGACY_INITIATOR_SUBJECT_ID,
|
|
3094
6179
|
UpdateConnectionRequest,
|
|
3095
6180
|
UpdateKnowledgeMemoryRequest,
|
|
6181
|
+
UpdateRigRequest,
|
|
3096
6182
|
UpdateScheduledTaskRequest,
|
|
3097
6183
|
UpdateSessionGoalRequest,
|
|
6184
|
+
UpdateSessionPinRequest,
|
|
3098
6185
|
UpdateSessionRequest,
|
|
3099
|
-
|
|
6186
|
+
UpdateVariableSetRequest,
|
|
3100
6187
|
UpdateWorkspaceEnvironmentRequest,
|
|
3101
6188
|
UpdateWorkspaceMemberRequest,
|
|
6189
|
+
UpdateWorkspaceModelPolicyRequest,
|
|
3102
6190
|
UpdateWorkspaceRequest,
|
|
6191
|
+
UpdateWorkspaceSettingsRequest,
|
|
3103
6192
|
UsageEvent,
|
|
3104
6193
|
UsageEventType,
|
|
3105
6194
|
UsageLimitsMode,
|
|
6195
|
+
VariableSet,
|
|
6196
|
+
VariableSetVariableMetadata,
|
|
6197
|
+
VariableSetVariableName,
|
|
3106
6198
|
ViewerHeartbeatRequest,
|
|
3107
6199
|
ViewerHeartbeatResponse,
|
|
3108
6200
|
ViewerHolder,
|
|
6201
|
+
WORKSPACE_CONTROL_ACTOR_MAX_BYTES,
|
|
6202
|
+
WORKSPACE_CONTROL_EVENT_MAX_BYTES,
|
|
6203
|
+
WORKSPACE_CONTROL_REASON_MAX_BYTES,
|
|
3109
6204
|
Workspace,
|
|
6205
|
+
WorkspaceCaptureDegradedReason,
|
|
6206
|
+
WorkspaceCaptureFile,
|
|
6207
|
+
WorkspaceCaptureManifest,
|
|
6208
|
+
WorkspaceCaptureRepo,
|
|
6209
|
+
WorkspaceCaptureSignedUrl,
|
|
6210
|
+
WorkspaceCaptureStats,
|
|
6211
|
+
WorkspaceControlEvent,
|
|
6212
|
+
WorkspaceControlEventTruncation,
|
|
3110
6213
|
WorkspaceEnvironment,
|
|
3111
6214
|
WorkspaceEnvironmentVariableMetadata,
|
|
3112
|
-
|
|
6215
|
+
WorkspaceInferenceControlRequest,
|
|
6216
|
+
WorkspaceInferenceControlResponse,
|
|
6217
|
+
WorkspaceInferenceState,
|
|
3113
6218
|
WorkspaceMember,
|
|
6219
|
+
WorkspaceMemorySearchMode,
|
|
6220
|
+
WorkspaceMemorySearchRequest,
|
|
6221
|
+
WorkspaceMemorySearchResponse,
|
|
6222
|
+
WorkspaceMemorySearchResult,
|
|
3114
6223
|
WorkspaceRegisteredPack,
|
|
6224
|
+
WorkspaceRevisionCapturedPayload,
|
|
6225
|
+
WorkspaceRevisionDegradedPayload,
|
|
6226
|
+
WorkspaceSettingsSchema,
|
|
6227
|
+
WorkspaceTranscriptionPolicy,
|
|
6228
|
+
WorkspaceTranscriptionTarget,
|
|
6229
|
+
approvalIdentifier,
|
|
6230
|
+
approximateSessionEventTokens,
|
|
6231
|
+
assertUniqueResourceMountPaths,
|
|
6232
|
+
boundSessionEvent,
|
|
6233
|
+
boundSessionEventPayload,
|
|
6234
|
+
boundWorkspaceControlEvent,
|
|
6235
|
+
defaultRepositoryMountPath,
|
|
6236
|
+
evaluateWorkspaceModelPolicy,
|
|
6237
|
+
gitCredentialBindingIdForRepository,
|
|
6238
|
+
gitCredentialProviderForRepository,
|
|
3115
6239
|
isClearedRunStateBlob,
|
|
6240
|
+
measureSessionEventJson,
|
|
3116
6241
|
mergeResourceRefs,
|
|
3117
6242
|
mergeToolRefs,
|
|
6243
|
+
normalizeRepositorySubpath,
|
|
6244
|
+
normalizeResourceMountPath,
|
|
3118
6245
|
prefixedMcpToolName,
|
|
3119
6246
|
reasoningEffortForMetadata,
|
|
6247
|
+
resolveSessionEventTypeFilters,
|
|
6248
|
+
resolveWorkspaceMemoryEnabled,
|
|
3120
6249
|
resourceIdentityKey,
|
|
6250
|
+
resourceMountPath,
|
|
6251
|
+
resourceMountPathCollisionKey,
|
|
6252
|
+
sessionEventJsonBytes,
|
|
6253
|
+
sessionEventMediaPreview,
|
|
6254
|
+
sessionEventMediaPreviewFromDataUrl,
|
|
6255
|
+
sessionEventPayloadTruncation,
|
|
3121
6256
|
signDelegatedAccessToken,
|
|
3122
6257
|
signEnrollToken,
|
|
3123
6258
|
signEnrollmentBearer,
|
|
@@ -3128,6 +6263,7 @@ export {
|
|
|
3128
6263
|
verifyEnrollToken,
|
|
3129
6264
|
verifyEnrollmentBearer,
|
|
3130
6265
|
verifyRelayToken,
|
|
3131
|
-
verifyStreamToken
|
|
6266
|
+
verifyStreamToken,
|
|
6267
|
+
workspaceControlUtf8Bytes
|
|
3132
6268
|
};
|
|
3133
6269
|
//# sourceMappingURL=index.js.map
|