@opengeni/sdk 0.57.0 → 2.2.0-canary.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/README.md +123 -2
- package/dist/artifacts.js +5 -5
- package/dist/automations-client.d.ts +17 -0
- package/dist/automations.d.ts +3 -0
- package/dist/automations.js +78 -0
- package/dist/automations.js.map +1 -0
- package/dist/{chunk-JDLDDRNE.js → chunk-C2H7HBNP.js} +290 -33
- package/dist/chunk-C2H7HBNP.js.map +1 -0
- package/dist/{chunk-GU6JF75T.js → chunk-C4DJPZRU.js} +1 -1
- package/dist/{chunk-GU6JF75T.js.map → chunk-C4DJPZRU.js.map} +1 -1
- package/dist/{chunk-JRPFWI6T.js → chunk-G6LBVWKT.js} +2 -2
- package/dist/{chunk-HJ3HHUT5.js → chunk-GLDV5QY7.js} +16 -2
- package/dist/chunk-GLDV5QY7.js.map +1 -0
- package/dist/{chunk-ST5DDKJP.js → chunk-GW3EJ2GP.js} +52 -1
- package/dist/chunk-GW3EJ2GP.js.map +1 -0
- package/dist/{chunk-VWE2QIVO.js → chunk-XNG7YGR3.js} +23 -6
- package/dist/chunk-XNG7YGR3.js.map +1 -0
- package/dist/{chunk-PKQ377ED.js → chunk-YBQTKNTL.js} +696 -57
- package/dist/chunk-YBQTKNTL.js.map +1 -0
- package/dist/client.d.ts +151 -26
- package/dist/codex-realtime-controller.d.ts +3 -0
- package/dist/codex-realtime-controller.js +2 -2
- package/dist/codex-realtime-v3.d.ts +13 -2
- package/dist/company-brain.d.ts +32 -0
- package/dist/company-profile.d.ts +1 -1
- package/dist/core.js +4 -4
- package/dist/editable-artifacts/browser-session.d.ts +7 -3
- package/dist/editable-artifacts/controller.d.ts +4 -1
- package/dist/editable-artifacts/errors.d.ts +1 -1
- package/dist/editable-artifacts/http-live-transport.d.ts +6 -2
- package/dist/editable-artifacts/index.d.ts +2 -0
- package/dist/editable-artifacts/open-failure.d.ts +9 -0
- package/dist/editable-artifacts/types.d.ts +4 -3
- package/dist/editable-artifacts/worker/kernel-adapter.d.ts +1 -1
- package/dist/editable-artifacts-worker.js +44 -17
- package/dist/editable-artifacts-worker.js.map +1 -1
- package/dist/editable-artifacts.js +222 -119
- package/dist/editable-artifacts.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/index.d.ts +7 -4
- package/dist/index.js +61 -12
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +23 -0
- package/dist/interaction.js +4 -1
- package/dist/organization-private-session-settings.d.ts +6 -0
- package/dist/organization-private-session-settings.js +22 -0
- package/dist/organization-private-session-settings.js.map +1 -0
- package/dist/pr-review-client.d.ts +15 -0
- package/dist/pr-review.d.ts +4 -0
- package/dist/pr-review.js +56 -0
- package/dist/pr-review.js.map +1 -0
- package/dist/preference-registry.d.ts +8 -0
- package/dist/realtime.js +2 -2
- package/dist/retained-artifacts.d.ts +5 -1
- package/dist/types.d.ts +976 -17
- package/dist/workspace-instruction-policies.d.ts +22 -0
- package/dist/workspace-learning.d.ts +124 -0
- package/package.json +14 -2
- package/src/automations-client.ts +118 -0
- package/src/automations.ts +15 -0
- package/src/client.ts +974 -71
- package/src/codex-realtime-controller.ts +235 -5
- package/src/codex-realtime-v3.ts +162 -31
- package/src/company-brain.ts +99 -0
- package/src/company-profile.ts +4 -1
- package/src/editable-artifacts/browser-session.ts +36 -22
- package/src/editable-artifacts/controller.ts +66 -45
- package/src/editable-artifacts/errors.ts +2 -0
- package/src/editable-artifacts/http-live-transport.ts +62 -37
- package/src/editable-artifacts/index.ts +6 -0
- package/src/editable-artifacts/open-failure.ts +79 -0
- package/src/editable-artifacts/storage.ts +31 -40
- package/src/editable-artifacts/types.ts +4 -3
- package/src/editable-artifacts/worker/kernel-adapter.ts +23 -7
- package/src/editable-artifacts/worker/runtime.ts +26 -13
- package/src/editable-artifacts/worker/wire-codec.ts +23 -5
- package/src/errors.ts +1 -1
- package/src/index.ts +131 -0
- package/src/interaction.ts +95 -0
- package/src/organization-private-session-settings.ts +33 -0
- package/src/pr-review-client.ts +84 -0
- package/src/pr-review.ts +15 -0
- package/src/preference-registry.ts +9 -0
- package/src/retained-artifacts.ts +101 -0
- package/src/stream.ts +13 -2
- package/src/types.ts +1117 -16
- package/src/workspace-instruction-policies.ts +24 -0
- package/src/workspace-learning.ts +138 -0
- package/dist/chunk-HJ3HHUT5.js.map +0 -1
- package/dist/chunk-JDLDDRNE.js.map +0 -1
- package/dist/chunk-PKQ377ED.js.map +0 -1
- package/dist/chunk-ST5DDKJP.js.map +0 -1
- package/dist/chunk-VWE2QIVO.js.map +0 -1
- /package/dist/{chunk-JRPFWI6T.js.map → chunk-G6LBVWKT.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OpenGeniApiError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-C4DJPZRU.js";
|
|
4
4
|
|
|
5
5
|
// src/codex-realtime-v3-wire.ts
|
|
6
6
|
var CODEX_REALTIME_INITIAL_ITEMS_MAX_COUNT = 128;
|
|
@@ -231,6 +231,7 @@ var CODEX_REALTIME_V3_PENDING_MAX_ENTRIES = 256;
|
|
|
231
231
|
var CODEX_REALTIME_V3_PENDING_MAX_BYTES = 16 * 1024 * 1024;
|
|
232
232
|
var REALTIME_DELEGATION_TRANSCRIPT_MAX_BYTES = 65536;
|
|
233
233
|
var REALTIME_DELEGATION_INPUT_MAX_BYTES = 65536;
|
|
234
|
+
var REALTIME_MODEL_CONTEXT_MAX_CHARACTERS = 32768;
|
|
234
235
|
function createCodexRealtimeV3Bridge(options) {
|
|
235
236
|
let closed = false;
|
|
236
237
|
let sealed = false;
|
|
@@ -253,9 +254,27 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
253
254
|
const clientReceivedSequences = /* @__PURE__ */ new Set();
|
|
254
255
|
const sentSequences = /* @__PURE__ */ new Set();
|
|
255
256
|
const finalizedTurnIds = /* @__PURE__ */ new Set();
|
|
257
|
+
const acceptedDelegationItemIds = options.acceptedDelegationItemIds ?? /* @__PURE__ */ new Set();
|
|
258
|
+
const pendingDelegations = options.pendingDelegations ?? /* @__PURE__ */ new Map();
|
|
259
|
+
const locallyQueuedDelegationItemIds = /* @__PURE__ */ new Set();
|
|
256
260
|
let transcriptSinceDelegation = [];
|
|
257
261
|
let pendingDelegationUserTranscript = null;
|
|
258
262
|
const randomUUID = options.randomUUID ?? defaultRandomUUID;
|
|
263
|
+
const currentModelContext = () => {
|
|
264
|
+
let context;
|
|
265
|
+
try {
|
|
266
|
+
context = options.getModelContext?.()?.trim();
|
|
267
|
+
} catch {
|
|
268
|
+
lastError = "Realtime model context callback failed; the provider message continued without application context";
|
|
269
|
+
return void 0;
|
|
270
|
+
}
|
|
271
|
+
if (!context) return void 0;
|
|
272
|
+
if (context.length > REALTIME_MODEL_CONTEXT_MAX_CHARACTERS) {
|
|
273
|
+
lastError = "Realtime model context exceeded the 32768-character limit; the provider message continued without application context";
|
|
274
|
+
return void 0;
|
|
275
|
+
}
|
|
276
|
+
return context;
|
|
277
|
+
};
|
|
259
278
|
const snapshot = () => ({
|
|
260
279
|
connectionId: options.connectionId,
|
|
261
280
|
connectionEpoch: options.connectionEpoch,
|
|
@@ -274,9 +293,9 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
274
293
|
fatal
|
|
275
294
|
});
|
|
276
295
|
const publish = () => options.onSnapshot?.(snapshot());
|
|
277
|
-
const
|
|
296
|
+
const triggerFatalCode = (code, message) => {
|
|
278
297
|
if (closed || fatal) return;
|
|
279
|
-
fatal = { code
|
|
298
|
+
fatal = { code, message };
|
|
280
299
|
lastError = message;
|
|
281
300
|
publish();
|
|
282
301
|
try {
|
|
@@ -284,6 +303,9 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
284
303
|
} catch {
|
|
285
304
|
}
|
|
286
305
|
};
|
|
306
|
+
const triggerFatal = (message) => {
|
|
307
|
+
triggerFatalCode("pending_overflow", message);
|
|
308
|
+
};
|
|
287
309
|
const enqueue = (entry) => {
|
|
288
310
|
if (closed || sealed || fatal) return false;
|
|
289
311
|
const bytes = utf8ByteLength2(JSON.stringify(entry));
|
|
@@ -296,6 +318,9 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
296
318
|
pendingInboundBytes += bytes;
|
|
297
319
|
return true;
|
|
298
320
|
};
|
|
321
|
+
for (const [delegationItemId, entry] of pendingDelegations) {
|
|
322
|
+
if (enqueue(entry)) locallyQueuedDelegationItemIds.add(delegationItemId);
|
|
323
|
+
}
|
|
299
324
|
const hasWork = () => pendingInbound.length > 0 || !providerStartedAccepted && providerStarted !== void 0 || clientAckThroughSequence !== null || forceSync;
|
|
300
325
|
const runFlush = async () => {
|
|
301
326
|
while (true) {
|
|
@@ -321,7 +346,41 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
321
346
|
pendingInbound = [...batch, ...pendingInbound];
|
|
322
347
|
throw error;
|
|
323
348
|
}
|
|
349
|
+
const acceptedAfterSync = new Set(acceptedDelegationItemIds);
|
|
350
|
+
const pendingAfterSync = new Map(pendingDelegations);
|
|
351
|
+
let delegationReplayChanged = false;
|
|
352
|
+
for (const item of batch) {
|
|
353
|
+
if (item.entry.kind === "delegation_call" && item.entry.delegationItemId) {
|
|
354
|
+
delegationReplayChanged = true;
|
|
355
|
+
acceptedAfterSync.add(item.entry.delegationItemId);
|
|
356
|
+
if (pendingAfterSync.get(item.entry.delegationItemId) === item.entry) {
|
|
357
|
+
pendingAfterSync.delete(item.entry.delegationItemId);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (delegationReplayChanged) {
|
|
362
|
+
try {
|
|
363
|
+
options.onDelegationReplayStateChange?.({
|
|
364
|
+
acceptedDelegationItemIds: acceptedAfterSync,
|
|
365
|
+
pendingDelegations: pendingAfterSync
|
|
366
|
+
});
|
|
367
|
+
} catch (error) {
|
|
368
|
+
pendingInbound = [...batch, ...pendingInbound];
|
|
369
|
+
triggerFatalCode(
|
|
370
|
+
"replay_journal_failed",
|
|
371
|
+
`Codex realtime delegation replay journal failed: ${safeError(error)}`
|
|
372
|
+
);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
324
376
|
for (const item of batch) {
|
|
377
|
+
if (item.entry.kind === "delegation_call" && item.entry.delegationItemId) {
|
|
378
|
+
acceptedDelegationItemIds.add(item.entry.delegationItemId);
|
|
379
|
+
if (pendingDelegations.get(item.entry.delegationItemId) === item.entry) {
|
|
380
|
+
pendingDelegations.delete(item.entry.delegationItemId);
|
|
381
|
+
}
|
|
382
|
+
locallyQueuedDelegationItemIds.delete(item.entry.delegationItemId);
|
|
383
|
+
}
|
|
325
384
|
pendingInboundCount -= 1;
|
|
326
385
|
pendingInboundBytes -= item.bytes;
|
|
327
386
|
}
|
|
@@ -423,27 +482,60 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
423
482
|
}
|
|
424
483
|
} else if (event.type === "input_transcript.added" || event.type === "output_transcript.added") {
|
|
425
484
|
} else if (event.type === "delegation.created") {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
485
|
+
if (acceptedDelegationItemIds.has(event.delegationItemId)) {
|
|
486
|
+
ignoredEventCount += 1;
|
|
487
|
+
lastIgnoredEventType = event.type;
|
|
488
|
+
} else if (locallyQueuedDelegationItemIds.has(event.delegationItemId)) {
|
|
489
|
+
ignoredEventCount += 1;
|
|
490
|
+
lastIgnoredEventType = event.type;
|
|
491
|
+
durable = true;
|
|
492
|
+
} else {
|
|
493
|
+
let entry = pendingDelegations.get(event.delegationItemId);
|
|
494
|
+
if (!entry) {
|
|
495
|
+
const transcript = delegationTranscript(transcriptSinceDelegation, event.inputTranscript);
|
|
496
|
+
const coveredTurnIds = transcriptSinceDelegation.map((item) => item.turnId);
|
|
497
|
+
const modelContext = currentModelContext();
|
|
498
|
+
entry = {
|
|
499
|
+
operationId: randomUUID(),
|
|
500
|
+
kind: "delegation_call",
|
|
501
|
+
providerEventId: event.providerEventId,
|
|
502
|
+
delegationItemId: event.delegationItemId,
|
|
503
|
+
text: renderRealtimeDelegationInput(event.inputTranscript, transcript),
|
|
504
|
+
payload: {
|
|
505
|
+
offsetMs: event.offsetMs,
|
|
506
|
+
inputTranscript: event.inputTranscript,
|
|
507
|
+
transcriptFenceTurnIds: coveredTurnIds
|
|
508
|
+
},
|
|
509
|
+
...modelContext ? { modelContext } : {}
|
|
510
|
+
};
|
|
511
|
+
pendingDelegations.set(event.delegationItemId, entry);
|
|
512
|
+
}
|
|
513
|
+
try {
|
|
514
|
+
options.onDelegationReplayStateChange?.({
|
|
515
|
+
acceptedDelegationItemIds,
|
|
516
|
+
pendingDelegations
|
|
517
|
+
});
|
|
518
|
+
} catch (error) {
|
|
519
|
+
triggerFatalCode(
|
|
520
|
+
"replay_journal_failed",
|
|
521
|
+
`Codex realtime delegation replay journal failed: ${safeError(error)}`
|
|
522
|
+
);
|
|
523
|
+
return Promise.resolve();
|
|
524
|
+
}
|
|
525
|
+
durable = enqueue(entry);
|
|
526
|
+
if (durable) {
|
|
527
|
+
locallyQueuedDelegationItemIds.add(event.delegationItemId);
|
|
528
|
+
activeDelegationId = event.delegationItemId;
|
|
529
|
+
const frozenInputTranscript = typeof entry.payload.inputTranscript === "string" ? entry.payload.inputTranscript : event.inputTranscript;
|
|
530
|
+
const alreadyFinalized = transcriptSinceDelegation.some(
|
|
531
|
+
(item) => item.role === "user" && normalizedTranscript(item.text) === normalizedTranscript(frozenInputTranscript)
|
|
532
|
+
);
|
|
533
|
+
pendingDelegationUserTranscript = alreadyFinalized ? null : {
|
|
534
|
+
delegationItemId: event.delegationItemId,
|
|
535
|
+
text: frozenInputTranscript
|
|
536
|
+
};
|
|
537
|
+
transcriptSinceDelegation = [];
|
|
439
538
|
}
|
|
440
|
-
});
|
|
441
|
-
if (durable) {
|
|
442
|
-
const alreadyFinalized = transcriptSinceDelegation.some(
|
|
443
|
-
(entry) => entry.role === "user" && normalizedTranscript(entry.text) === normalizedTranscript(event.inputTranscript)
|
|
444
|
-
);
|
|
445
|
-
pendingDelegationUserTranscript = alreadyFinalized ? null : { delegationItemId: event.delegationItemId, text: event.inputTranscript };
|
|
446
|
-
transcriptSinceDelegation = [];
|
|
447
539
|
}
|
|
448
540
|
} else if (event.type === "output_audio.delta") {
|
|
449
541
|
speaking = true;
|
|
@@ -451,7 +543,9 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
451
543
|
speaking = false;
|
|
452
544
|
if (event.transcript.length > 0 && !finalizedTurnIds.has(event.turnId)) {
|
|
453
545
|
const coveredByDelegationItemId = event.role === "user" && pendingDelegationUserTranscript !== null && normalizedTranscript(event.transcript) === normalizedTranscript(pendingDelegationUserTranscript.text) ? pendingDelegationUserTranscript.delegationItemId : null;
|
|
454
|
-
durable = enqueue(
|
|
546
|
+
durable = enqueue(
|
|
547
|
+
finalTranscript(randomUUID, event, coveredByDelegationItemId, currentModelContext())
|
|
548
|
+
);
|
|
455
549
|
if (durable) {
|
|
456
550
|
finalizedTurnIds.add(event.turnId);
|
|
457
551
|
if (coveredByDelegationItemId) {
|
|
@@ -508,7 +602,7 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
508
602
|
}
|
|
509
603
|
};
|
|
510
604
|
}
|
|
511
|
-
function finalTranscript(randomUUID, event, coveredByDelegationItemId) {
|
|
605
|
+
function finalTranscript(randomUUID, event, coveredByDelegationItemId, modelContext) {
|
|
512
606
|
return {
|
|
513
607
|
operationId: randomUUID(),
|
|
514
608
|
kind: event.role === "user" ? "user_transcript" : "assistant_transcript",
|
|
@@ -517,7 +611,8 @@ function finalTranscript(randomUUID, event, coveredByDelegationItemId) {
|
|
|
517
611
|
payload: {
|
|
518
612
|
turnId: event.turnId,
|
|
519
613
|
...coveredByDelegationItemId ? { coveredByDelegationItemId } : {}
|
|
520
|
-
}
|
|
614
|
+
},
|
|
615
|
+
...modelContext ? { modelContext } : {}
|
|
521
616
|
};
|
|
522
617
|
}
|
|
523
618
|
function delegationTranscript(entries, inputTranscript) {
|
|
@@ -573,7 +668,10 @@ function sendOutbound(events, entry) {
|
|
|
573
668
|
delegationItemId: entry.delegationItemId,
|
|
574
669
|
text,
|
|
575
670
|
channel: payloadChannel ?? "speakable"
|
|
576
|
-
}) : encodeCodexRealtimeV3SessionContextAppend({
|
|
671
|
+
}) : encodeCodexRealtimeV3SessionContextAppend({
|
|
672
|
+
text,
|
|
673
|
+
channel: payloadChannel
|
|
674
|
+
});
|
|
577
675
|
for (const message of messages) events.send(JSON.stringify(message));
|
|
578
676
|
}
|
|
579
677
|
function sendDelegationProgress(events, delegationItemId, entries) {
|
|
@@ -972,7 +1070,29 @@ var OUTBOUND_SYNC_INTERVAL_MS = 1e3;
|
|
|
972
1070
|
var CODEX_REALTIME_NEGOTIATION_TIMEOUT_MS = 2e4;
|
|
973
1071
|
var DEFAULT_CONNECTION_ROTATION_INTERVAL_MS = 15 * 6e4;
|
|
974
1072
|
var DEFAULT_RECONNECT_BACKOFF_MS = [250, 1e3, 2e3, 5e3];
|
|
1073
|
+
var MAX_BROWSER_TIMEOUT_MS = 2147483647;
|
|
975
1074
|
var OWNER_RECORD_VERSION = 1;
|
|
1075
|
+
var OWNER_DELEGATION_REPLAY_VERSION = 1;
|
|
1076
|
+
var OWNER_DELEGATION_REPLAY_MAX_CALLS = 4096;
|
|
1077
|
+
var OWNER_DELEGATION_REPLAY_MAX_BYTES = 4 * 1024 * 1024;
|
|
1078
|
+
var SESSION_REALTIME_INBOUND_ENTRY_KEYS = /* @__PURE__ */ new Set([
|
|
1079
|
+
"operationId",
|
|
1080
|
+
"kind",
|
|
1081
|
+
"role",
|
|
1082
|
+
"providerEventId",
|
|
1083
|
+
"delegationItemId",
|
|
1084
|
+
"text",
|
|
1085
|
+
"payload",
|
|
1086
|
+
"modelContext"
|
|
1087
|
+
]);
|
|
1088
|
+
var SESSION_REALTIME_INBOUND_KINDS = /* @__PURE__ */ new Set([
|
|
1089
|
+
"user_transcript",
|
|
1090
|
+
"assistant_transcript",
|
|
1091
|
+
"delegation_call",
|
|
1092
|
+
"interruption",
|
|
1093
|
+
"error"
|
|
1094
|
+
]);
|
|
1095
|
+
var 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}$/iu;
|
|
976
1096
|
function sessionRealtimeOwnerStorageNamespace(model) {
|
|
977
1097
|
if (model === "gpt-live-1-boulder-alpha") return "codex-realtime-owner";
|
|
978
1098
|
if (model === "supergrok/grok-voice-think-fast-2.0") return "xai-realtime-owner";
|
|
@@ -1001,6 +1121,7 @@ function createCodexRealtimeController(options) {
|
|
|
1001
1121
|
);
|
|
1002
1122
|
const model = options.model ?? "gpt-live-1-boulder-alpha";
|
|
1003
1123
|
const randomUUID = options.randomUUID ?? defaultRandomUUID2;
|
|
1124
|
+
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
1004
1125
|
const scheduleInterval = options.setInterval ?? ((callback, delay) => globalThis.setInterval(callback, delay));
|
|
1005
1126
|
const unscheduleInterval = options.clearInterval ?? ((handle) => globalThis.clearInterval(handle));
|
|
1006
1127
|
const scheduleTimeout = options.setTimeout ?? ((callback, delay) => globalThis.setTimeout(callback, delay));
|
|
@@ -1041,6 +1162,7 @@ function createCodexRealtimeController(options) {
|
|
|
1041
1162
|
let rotationTimer = null;
|
|
1042
1163
|
let reconnectTimer = null;
|
|
1043
1164
|
let negotiationTimer = null;
|
|
1165
|
+
let lostOwnerExpiryTimer = null;
|
|
1044
1166
|
let closed = false;
|
|
1045
1167
|
let stopping = false;
|
|
1046
1168
|
let generation = 0;
|
|
@@ -1048,6 +1170,45 @@ function createCodexRealtimeController(options) {
|
|
|
1048
1170
|
let recoveryTerminal = false;
|
|
1049
1171
|
let mutationTail = Promise.resolve();
|
|
1050
1172
|
let connectionTask = null;
|
|
1173
|
+
const acceptedDelegationItemIds = new Set(
|
|
1174
|
+
owner?.delegationReplay?.acceptedDelegationItemIds ?? []
|
|
1175
|
+
);
|
|
1176
|
+
const pendingDelegations = new Map(
|
|
1177
|
+
(owner?.delegationReplay?.pendingDelegations ?? []).flatMap(
|
|
1178
|
+
(entry) => entry.delegationItemId ? [[entry.delegationItemId, entry]] : []
|
|
1179
|
+
)
|
|
1180
|
+
);
|
|
1181
|
+
const invalidateStoredOwner = () => {
|
|
1182
|
+
try {
|
|
1183
|
+
storage?.removeItem(storageKey);
|
|
1184
|
+
} catch {
|
|
1185
|
+
}
|
|
1186
|
+
};
|
|
1187
|
+
const persistDelegationReplay = (input) => {
|
|
1188
|
+
if (!owner || !storage) return;
|
|
1189
|
+
const delegationReplay = {
|
|
1190
|
+
version: OWNER_DELEGATION_REPLAY_VERSION,
|
|
1191
|
+
acceptedDelegationItemIds: [...input.acceptedDelegationItemIds],
|
|
1192
|
+
pendingDelegations: [...input.pendingDelegations.values()]
|
|
1193
|
+
};
|
|
1194
|
+
if (delegationReplay.pendingDelegations.length > CODEX_REALTIME_V3_PENDING_MAX_ENTRIES || delegationReplay.acceptedDelegationItemIds.length + delegationReplay.pendingDelegations.length > OWNER_DELEGATION_REPLAY_MAX_CALLS) {
|
|
1195
|
+
invalidateStoredOwner();
|
|
1196
|
+
throw new Error("Realtime delegation replay journal exceeded its call limit");
|
|
1197
|
+
}
|
|
1198
|
+
const next = { ...owner, delegationReplay };
|
|
1199
|
+
const serialized = JSON.stringify(next);
|
|
1200
|
+
if (new TextEncoder().encode(serialized).byteLength > OWNER_DELEGATION_REPLAY_MAX_BYTES) {
|
|
1201
|
+
invalidateStoredOwner();
|
|
1202
|
+
throw new Error("Realtime delegation replay journal exceeded its byte limit");
|
|
1203
|
+
}
|
|
1204
|
+
try {
|
|
1205
|
+
storage.setItem(storageKey, serialized);
|
|
1206
|
+
} catch (error) {
|
|
1207
|
+
invalidateStoredOwner();
|
|
1208
|
+
throw error;
|
|
1209
|
+
}
|
|
1210
|
+
owner = next;
|
|
1211
|
+
};
|
|
1051
1212
|
const publish = (patch) => {
|
|
1052
1213
|
state = { ...state, ...patch };
|
|
1053
1214
|
for (const listener of listeners) listener({ ...state });
|
|
@@ -1073,11 +1234,13 @@ function createCodexRealtimeController(options) {
|
|
|
1073
1234
|
if (rotationTimer !== null) unscheduleTimeout(rotationTimer);
|
|
1074
1235
|
if (reconnectTimer !== null) unscheduleTimeout(reconnectTimer);
|
|
1075
1236
|
if (negotiationTimer !== null) unscheduleTimeout(negotiationTimer);
|
|
1237
|
+
if (lostOwnerExpiryTimer !== null) unscheduleTimeout(lostOwnerExpiryTimer);
|
|
1076
1238
|
heartbeatTimer = null;
|
|
1077
1239
|
syncTimer = null;
|
|
1078
1240
|
rotationTimer = null;
|
|
1079
1241
|
reconnectTimer = null;
|
|
1080
1242
|
negotiationTimer = null;
|
|
1243
|
+
lostOwnerExpiryTimer = null;
|
|
1081
1244
|
};
|
|
1082
1245
|
const stopNegotiationTimers = () => {
|
|
1083
1246
|
if (heartbeatTimer !== null) unscheduleInterval(heartbeatTimer);
|
|
@@ -1117,6 +1280,8 @@ function createCodexRealtimeController(options) {
|
|
|
1117
1280
|
const clearOwner = () => {
|
|
1118
1281
|
owner = null;
|
|
1119
1282
|
storage?.removeItem(storageKey);
|
|
1283
|
+
acceptedDelegationItemIds.clear();
|
|
1284
|
+
pendingDelegations.clear();
|
|
1120
1285
|
};
|
|
1121
1286
|
const transitionEnded = (message = "Realtime mode ended") => {
|
|
1122
1287
|
stopping = false;
|
|
@@ -1194,7 +1359,10 @@ function createCodexRealtimeController(options) {
|
|
|
1194
1359
|
});
|
|
1195
1360
|
return;
|
|
1196
1361
|
}
|
|
1197
|
-
publish({
|
|
1362
|
+
publish({
|
|
1363
|
+
audibleOutput: next,
|
|
1364
|
+
...next === "audible" ? { error: null } : {}
|
|
1365
|
+
});
|
|
1198
1366
|
};
|
|
1199
1367
|
const startActiveIntervals = () => {
|
|
1200
1368
|
if (heartbeatTimer === null) {
|
|
@@ -1511,6 +1679,10 @@ function createCodexRealtimeController(options) {
|
|
|
1511
1679
|
listen: false,
|
|
1512
1680
|
sync: async (request) => await syncForGeneration(targetGeneration, activated.mode.id, request),
|
|
1513
1681
|
randomUUID,
|
|
1682
|
+
...options.getModelContext ? { getModelContext: options.getModelContext } : {},
|
|
1683
|
+
acceptedDelegationItemIds,
|
|
1684
|
+
pendingDelegations,
|
|
1685
|
+
onDelegationReplayStateChange: persistDelegationReplay,
|
|
1514
1686
|
onSnapshot: (nextBridge) => {
|
|
1515
1687
|
if (active?.generation === targetGeneration) publish({ bridge: nextBridge });
|
|
1516
1688
|
},
|
|
@@ -1676,7 +1848,12 @@ function createCodexRealtimeController(options) {
|
|
|
1676
1848
|
await handleConnectionFailure(error, "reconnect", false);
|
|
1677
1849
|
} else {
|
|
1678
1850
|
clearOwner();
|
|
1679
|
-
publish({
|
|
1851
|
+
publish({
|
|
1852
|
+
status: "error",
|
|
1853
|
+
realtimeId: null,
|
|
1854
|
+
mode: null,
|
|
1855
|
+
error: safeError2(error)
|
|
1856
|
+
});
|
|
1680
1857
|
}
|
|
1681
1858
|
throw error;
|
|
1682
1859
|
}
|
|
@@ -1730,6 +1907,12 @@ function createCodexRealtimeController(options) {
|
|
|
1730
1907
|
if (!record2 || record2.operationId !== lifecycle.operationId) {
|
|
1731
1908
|
closeBrowserResources();
|
|
1732
1909
|
owner = null;
|
|
1910
|
+
const leaseExpiresAt = Date.parse(lifecycle.leaseExpiresAt);
|
|
1911
|
+
const remainingLeaseMs = leaseExpiresAt - now().getTime();
|
|
1912
|
+
if (Number.isFinite(remainingLeaseMs) && remainingLeaseMs <= 0) {
|
|
1913
|
+
transitionEnded("Realtime lease expired");
|
|
1914
|
+
return;
|
|
1915
|
+
}
|
|
1733
1916
|
const message = "Realtime is active in another browser owner. It can resume after that owner stops or its lease expires.";
|
|
1734
1917
|
publish({
|
|
1735
1918
|
status: "lost_owner",
|
|
@@ -1739,13 +1922,26 @@ function createCodexRealtimeController(options) {
|
|
|
1739
1922
|
diagnostic: diagnostic("lost_owner", message, false),
|
|
1740
1923
|
error: message
|
|
1741
1924
|
});
|
|
1925
|
+
if (Number.isFinite(remainingLeaseMs) && remainingLeaseMs <= MAX_BROWSER_TIMEOUT_MS) {
|
|
1926
|
+
const observedRealtimeId = lifecycle.realtimeId;
|
|
1927
|
+
lostOwnerExpiryTimer = scheduleTimeout(() => {
|
|
1928
|
+
lostOwnerExpiryTimer = null;
|
|
1929
|
+
if (state.status === "lost_owner" && state.realtimeId === observedRealtimeId) {
|
|
1930
|
+
transitionEnded("Realtime lease expired");
|
|
1931
|
+
}
|
|
1932
|
+
}, remainingLeaseMs);
|
|
1933
|
+
}
|
|
1742
1934
|
return;
|
|
1743
1935
|
}
|
|
1744
1936
|
if (connectionTask || state.status === "starting") return;
|
|
1745
1937
|
closed = false;
|
|
1746
1938
|
stopping = false;
|
|
1747
1939
|
owner = record2;
|
|
1748
|
-
publish({
|
|
1940
|
+
publish({
|
|
1941
|
+
status: "recovering",
|
|
1942
|
+
realtimeId: lifecycle.realtimeId,
|
|
1943
|
+
error: null
|
|
1944
|
+
});
|
|
1749
1945
|
connectionTask = begin(record2, true).then(() => void 0).catch(async (error) => {
|
|
1750
1946
|
connectionTask = null;
|
|
1751
1947
|
await handleConnectionFailure(error, "reload", false);
|
|
@@ -1912,18 +2108,79 @@ function ownerStorageKey(workspaceId, sessionId, namespace = "codex-realtime-own
|
|
|
1912
2108
|
function readOwnerRecord(storage, key, scope) {
|
|
1913
2109
|
const raw = storage?.getItem(key);
|
|
1914
2110
|
if (!raw) return null;
|
|
2111
|
+
if (new TextEncoder().encode(raw).byteLength > OWNER_DELEGATION_REPLAY_MAX_BYTES) {
|
|
2112
|
+
storage?.removeItem(key);
|
|
2113
|
+
return null;
|
|
2114
|
+
}
|
|
1915
2115
|
try {
|
|
1916
2116
|
const parsed = recordValue2(JSON.parse(raw));
|
|
1917
|
-
|
|
2117
|
+
const delegationReplay = readOwnerDelegationReplay(parsed?.delegationReplay);
|
|
2118
|
+
if (parsed?.version !== OWNER_RECORD_VERSION || parsed.workspaceId !== scope.workspaceId || parsed.sessionId !== scope.sessionId || !stringValue2(parsed.operationId) || !stringValue2(parsed.browserInstanceId) || !stringValue2(parsed.ownerKey) || String(parsed.ownerKey).length < 32 || delegationReplay === null) {
|
|
1918
2119
|
storage?.removeItem(key);
|
|
1919
2120
|
return null;
|
|
1920
2121
|
}
|
|
1921
|
-
return
|
|
2122
|
+
return {
|
|
2123
|
+
...parsed,
|
|
2124
|
+
...delegationReplay ? { delegationReplay } : {}
|
|
2125
|
+
};
|
|
1922
2126
|
} catch {
|
|
1923
2127
|
storage?.removeItem(key);
|
|
1924
2128
|
return null;
|
|
1925
2129
|
}
|
|
1926
2130
|
}
|
|
2131
|
+
function readOwnerDelegationReplay(value) {
|
|
2132
|
+
if (value === void 0) return void 0;
|
|
2133
|
+
const record2 = recordValue2(value);
|
|
2134
|
+
if (record2?.version !== OWNER_DELEGATION_REPLAY_VERSION || !Array.isArray(record2.acceptedDelegationItemIds) || !Array.isArray(record2.pendingDelegations) || record2.acceptedDelegationItemIds.length + record2.pendingDelegations.length > OWNER_DELEGATION_REPLAY_MAX_CALLS || record2.pendingDelegations.length > CODEX_REALTIME_V3_PENDING_MAX_ENTRIES) {
|
|
2135
|
+
return null;
|
|
2136
|
+
}
|
|
2137
|
+
const acceptedDelegationItemIds = [];
|
|
2138
|
+
const accepted = /* @__PURE__ */ new Set();
|
|
2139
|
+
for (const candidate of record2.acceptedDelegationItemIds) {
|
|
2140
|
+
if (typeof candidate !== "string" || candidate.length < 1 || candidate.length > 1024) {
|
|
2141
|
+
return null;
|
|
2142
|
+
}
|
|
2143
|
+
if (!accepted.has(candidate)) {
|
|
2144
|
+
accepted.add(candidate);
|
|
2145
|
+
acceptedDelegationItemIds.push(candidate);
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
const pendingDelegations = [];
|
|
2149
|
+
const pendingIds = /* @__PURE__ */ new Set();
|
|
2150
|
+
for (const candidate of record2.pendingDelegations) {
|
|
2151
|
+
const parsed = readSessionRealtimeInboundEntry(candidate);
|
|
2152
|
+
if (!parsed || parsed.kind !== "delegation_call" || !parsed.delegationItemId || accepted.has(parsed.delegationItemId) || pendingIds.has(parsed.delegationItemId)) {
|
|
2153
|
+
return null;
|
|
2154
|
+
}
|
|
2155
|
+
pendingIds.add(parsed.delegationItemId);
|
|
2156
|
+
pendingDelegations.push(parsed);
|
|
2157
|
+
}
|
|
2158
|
+
const replay = {
|
|
2159
|
+
version: OWNER_DELEGATION_REPLAY_VERSION,
|
|
2160
|
+
acceptedDelegationItemIds,
|
|
2161
|
+
pendingDelegations
|
|
2162
|
+
};
|
|
2163
|
+
if (new TextEncoder().encode(JSON.stringify(replay)).byteLength > OWNER_DELEGATION_REPLAY_MAX_BYTES) {
|
|
2164
|
+
return null;
|
|
2165
|
+
}
|
|
2166
|
+
return replay;
|
|
2167
|
+
}
|
|
2168
|
+
function readSessionRealtimeInboundEntry(value) {
|
|
2169
|
+
const record2 = recordValue2(value);
|
|
2170
|
+
if (!record2 || Object.keys(record2).some((key) => !SESSION_REALTIME_INBOUND_ENTRY_KEYS.has(key)) || typeof record2.operationId !== "string" || !UUID_PATTERN.test(record2.operationId) || typeof record2.kind !== "string" || !SESSION_REALTIME_INBOUND_KINDS.has(record2.kind) || !optionalNullableEnum(record2.role, ["user", "assistant"]) || !optionalNullableBoundedString(record2.providerEventId, 1024) || !optionalNullableBoundedString(record2.delegationItemId, 1024) || !optionalNullableBoundedString(record2.text, 131072) || record2.payload !== void 0 && recordValue2(record2.payload) === null || !optionalModelContext(record2.modelContext)) {
|
|
2171
|
+
return null;
|
|
2172
|
+
}
|
|
2173
|
+
return record2;
|
|
2174
|
+
}
|
|
2175
|
+
function optionalNullableEnum(value, allowed) {
|
|
2176
|
+
return value === void 0 || value === null || typeof value === "string" && allowed.includes(value);
|
|
2177
|
+
}
|
|
2178
|
+
function optionalNullableBoundedString(value, maxLength) {
|
|
2179
|
+
return value === void 0 || value === null || typeof value === "string" && value.length <= maxLength;
|
|
2180
|
+
}
|
|
2181
|
+
function optionalModelContext(value) {
|
|
2182
|
+
return value === void 0 || typeof value === "string" && value.length >= 1 && value.length <= 32768 && value.trim() === value;
|
|
2183
|
+
}
|
|
1927
2184
|
function defaultStorage() {
|
|
1928
2185
|
return typeof sessionStorage === "undefined" ? void 0 : sessionStorage;
|
|
1929
2186
|
}
|
|
@@ -2021,4 +2278,4 @@ export {
|
|
|
2021
2278
|
hasStoredSessionRealtimeOwnerProof,
|
|
2022
2279
|
createCodexRealtimeController
|
|
2023
2280
|
};
|
|
2024
|
-
//# sourceMappingURL=chunk-
|
|
2281
|
+
//# sourceMappingURL=chunk-C2H7HBNP.js.map
|