@openclaw/codex 2026.9.1-beta.1 → 2026.9.1
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/api.js +5 -6
- package/dist/{attempt-client-cleanup-bfsmcQ6m.js → attempt-client-cleanup-DYHcRQAa.js} +31 -45
- package/dist/attempt-context-DmQUNWwT.js +634 -0
- package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
- package/dist/{binding-connection-BMvPX73o.js → binding-connection-E6uDsPlx.js} +2 -2
- package/dist/{bounded-turn-B7iBUcuP.js → bounded-turn-wzJrwKKe.js} +15 -20
- package/dist/{capabilities-BRMh0aIq.js → capabilities-dIjNVCYH.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-DEsIufkt.js → command-formatters-CLHhEB1Q.js} +5 -4
- package/dist/{command-handlers-D_-1_qRp.js → command-handlers-CTGb2csu.js} +124 -101
- package/dist/{compact-BglNFZrQ.js → compact-_t0HQrUS.js} +38 -29
- package/dist/{config-giW8X0QA.js → config-BhmfC1s6.js} +294 -282
- package/dist/{context-compaction-activity-BOeJf7yo.js → context-compaction-activity-CMla5FPJ.js} +4 -1
- package/dist/{conversation-binding-data-CW2GuupV.js → conversation-binding-data-BiodpIzq.js} +2 -1
- package/dist/doctor-contract-api.js +143 -12
- package/dist/{dynamic-tools-Dnlfa--w.js → dynamic-tools-BU9tmlYm.js} +599 -655
- package/dist/{effective-mcp-catalog-CTeGrnfO.js → effective-mcp-catalog-DzYBW4h1.js} +2 -2
- package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-DHRFXKbS.js} +4 -4
- package/dist/{event-projector-usage-Bk1I90Bg.js → event-projector-usage-C5mcrGjp.js} +15 -148
- package/dist/{harness-Csz0F-DK.js → harness-DXVZ5II5.js} +42 -52
- package/dist/harness.js +1 -1
- package/dist/index.js +458 -404
- package/dist/{isolated-completion-Cv6FqygM.js → isolated-completion-kg9kv4iH.js} +4 -4
- package/dist/launch-args-RXQwn8zV.js +90 -0
- package/dist/{managed-binary-DFYK4DWq.js → managed-binary-4-Vjz5GH.js} +14 -9
- package/dist/media-understanding-provider.js +1 -1
- package/dist/model-catalog-CUM68Hkl.js +101 -0
- package/dist/{models-TS3HBU-q.js → models-sYnEc0gd.js} +25 -28
- package/dist/{native-subagent-monitor-4Mfq2HDs.js → native-subagent-monitor-CnH147jH.js} +55 -115
- package/dist/{node-exec-server.runtime-BpWqJO1V.js → node-exec-server.runtime-CstNHCmC.js} +9 -6
- package/dist/{plugin-approval-roundtrip-bUm777tR.js → plugin-approval-roundtrip-CNe-Xrjx.js} +30 -3
- package/dist/{plugin-marketplace-discovery-B9DvaAG-.js → plugin-marketplace-discovery-CfFlKqDl.js} +15 -14
- package/dist/{plugin-metadata-cache-CTCT3w5L.js → plugin-metadata-cache-BFrPhb2c.js} +6 -6
- package/dist/provider-capabilities-DW5p4k9w.js +101 -0
- package/dist/{rate-limits-C5_D8Gmb.js → rate-limits-CawQJfUS.js} +3 -2
- package/dist/{sandbox-guard-kuWTn9C5.js → request-DYAI5FQE.js} +195 -2
- package/dist/{run-attempt-DYc0QCBF.js → run-attempt-D1hJO4fX.js} +828 -2100
- package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-C3jVimFn.js} +21 -14
- package/dist/{session-binding-Bcynfd-_.js → session-binding-BHuTCRZQ.js} +198 -127
- package/dist/{session-catalog-DaLKVtpH.js → session-catalog-yyvTWFOw.js} +564 -408
- package/dist/{session-cli-DMc4oS2w.js → session-cli-CmFEXMAM.js} +1 -1
- package/dist/session-history-C5J1AKzG.js +87 -0
- package/dist/session-initialization-BeWzjGiR.js +74 -0
- package/dist/{session-permission-policy-BrNH1bjy.js → session-permission-policy-DeWVTCMj.js} +2 -2
- package/dist/session-retirement-BujDjXVF.js +97 -0
- package/dist/{session-upstream-marker-BIkusb95.js → session-upstream-marker-C351-5Qw.js} +19 -4
- package/dist/settled-turn-context-D3SNWtUn.js +268 -0
- package/dist/settled-turn-finalizer-BVJx4yoc.js +104 -0
- package/dist/{shared-client-DKz23hHY.js → shared-client-DxcfF9KX.js} +3480 -679
- package/dist/{side-question-DjA_jsNe.js → side-question-BTZAII4l.js} +108 -70
- package/dist/{thread-lifecycle-L7oEkTlq.js → thread-lifecycle-DAcEJ_Om.js} +2188 -1915
- package/dist/{thread-ownership-DZeuKH1j.js → thread-ownership-zGokd8i1.js} +25 -14
- package/dist/thread-policy-g4KbJPzp.js +54 -0
- package/dist/{plugin-app-cache-key-C1CAdfcP.js → thread-resume-C7pyVKeW.js} +59 -7
- package/dist/{transcript-mirror-DsCMWBca.js → transcript-mirror-DTUxFWa_.js} +79 -17
- package/dist/transport-stdio-CyPldczm.js +726 -0
- package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
- package/dist/upstream-session-fork-CYlBIGVt.js +966 -0
- package/dist/{usage-ROIaW3wo.js → usage-Bj-rrzkR.js} +3 -3
- package/dist/{web-search-provider.runtime-ClaNPV7N.js → web-search-provider.runtime-D2FWSK4w.js} +3 -3
- package/openclaw.plugin.json +1 -30
- package/package.json +6 -6
- package/dist/command-rpc-CCeCkf_v.js +0 -90
- package/dist/incognito-session-ET_ufDH-.js +0 -2
- package/dist/model-catalog-i9rNBthX.js +0 -48
- package/dist/protocol-validators-VeJxxJ0U.js +0 -2421
- package/dist/request-DXXGHko0.js +0 -157
- package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
- package/dist/session-retirement-CcNC3YSY.js +0 -36
- package/dist/settled-turn-finalizer-Dc3ApjU4.js +0 -328
- package/dist/thread-resume-BE9qNEW0.js +0 -30
- package/dist/transport-stdio-DhoGy33Z.js +0 -99
- package/dist/upstream-session-fork-DlaHxSLC.js +0 -326
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as resolvePackagedCodexNativeCommand } from "./managed-binary-4-Vjz5GH.js";
|
|
2
|
+
import { n as resolveCodexAppServerSpawnEnv } from "./transport-stdio-CyPldczm.js";
|
|
2
3
|
import fs from "node:fs/promises";
|
|
3
4
|
import path from "node:path";
|
|
5
|
+
import { isPathInside } from "openclaw/plugin-sdk/file-access-runtime";
|
|
4
6
|
import { createHash } from "node:crypto";
|
|
5
7
|
import { constants } from "node:fs";
|
|
6
8
|
import { resolveWindowsExecutablePath, resolveWindowsSpawnProgram } from "openclaw/plugin-sdk/windows-spawn";
|
|
7
|
-
import { isPathInside } from "openclaw/plugin-sdk/file-access-runtime";
|
|
8
9
|
//#region extensions/codex/src/app-server/runtime-artifact.ts
|
|
9
10
|
/** Exact local runtime artifact identity for verified Codex setup turns. */
|
|
10
11
|
const ARTIFACT_ID_PREFIX = "codex-app-server:v1:";
|
|
11
12
|
const ARTIFACT_HASH_DOMAIN = "openclaw-codex-app-server-runtime-artifact-v1\0";
|
|
12
|
-
const MAX_ARTIFACT_ID_BYTES =
|
|
13
|
+
const MAX_ARTIFACT_ID_BYTES = 32768;
|
|
13
14
|
const MAX_ARTIFACT_PATH_BYTES = 4096;
|
|
14
15
|
const MAX_ARTIFACT_INVOCATION_PATHS = 8;
|
|
15
16
|
const MAX_ARTIFACT_DEPTH = 64;
|
|
16
17
|
const MAX_ARTIFACT_ENTRIES = 32768;
|
|
17
18
|
const MAX_ARTIFACT_FILES = 8192;
|
|
18
19
|
const MAX_ARTIFACT_TOTAL_BYTES = 1024n * 1024n * 1024n;
|
|
19
|
-
const READ_CHUNK_BYTES =
|
|
20
|
+
const READ_CHUNK_BYTES = 65536;
|
|
20
21
|
const CODE_MODE_HOST_PATH_ENV = "CODEX_CODE_MODE_HOST_PATH";
|
|
21
22
|
const SAFE_NODE_OPTIONS_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
22
23
|
"--enable-network-family-autoselection",
|
|
@@ -363,6 +364,8 @@ async function captureFilesystemDescriptor(params) {
|
|
|
363
364
|
const spawnCwd = path.resolve(params.startOptions.cwd ?? process.cwd());
|
|
364
365
|
const commandPath = await resolveCommandPath(params.startOptions.command, env, spawnCwd);
|
|
365
366
|
const commandRealPath = await fs.realpath(commandPath);
|
|
367
|
+
let nativeCommand = params.spawnIdentity.nativeCommand;
|
|
368
|
+
let nativeCandidate = commandRealPath;
|
|
366
369
|
let invocationPaths;
|
|
367
370
|
if (process.platform === "win32") {
|
|
368
371
|
const program = resolveWindowsSpawnProgram({
|
|
@@ -372,7 +375,10 @@ async function captureFilesystemDescriptor(params) {
|
|
|
372
375
|
execPath: process.execPath,
|
|
373
376
|
packageName: "@openai/codex"
|
|
374
377
|
});
|
|
375
|
-
|
|
378
|
+
const entrypoint = program.leadingArgv[0];
|
|
379
|
+
if (program.resolution === "node-entrypoint" && entrypoint && !nativeCommand) nativeCommand = resolvePackagedCodexNativeCommand(await fs.realpath(entrypoint));
|
|
380
|
+
if (program.resolution === "node-entrypoint" && !nativeCommand) throw new Error("Codex runtime cannot attest a custom Node launcher without its native target");
|
|
381
|
+
nativeCandidate = program.command;
|
|
376
382
|
const invocationCandidates = [
|
|
377
383
|
commandRealPath,
|
|
378
384
|
program.command,
|
|
@@ -383,17 +389,18 @@ async function captureFilesystemDescriptor(params) {
|
|
|
383
389
|
const resolved = await resolveCommandPath(candidate, env, spawnCwd);
|
|
384
390
|
invocationPaths.push(await fs.realpath(resolved));
|
|
385
391
|
}
|
|
386
|
-
} else
|
|
387
|
-
commandRealPath
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
+
} else {
|
|
393
|
+
nativeCommand ??= resolvePackagedCodexNativeCommand(commandRealPath);
|
|
394
|
+
invocationPaths = await resolvePosixInvocationPaths({
|
|
395
|
+
commandRealPath,
|
|
396
|
+
env,
|
|
397
|
+
cwd: spawnCwd,
|
|
398
|
+
nativeCommand
|
|
399
|
+
});
|
|
400
|
+
}
|
|
392
401
|
invocationPaths = [...new Set(invocationPaths)].toSorted(compareArtifactNames);
|
|
393
402
|
if (invocationPaths.length > MAX_ARTIFACT_INVOCATION_PATHS) throw new Error("Codex runtime launcher exceeds the bounded invocation file count");
|
|
394
|
-
const
|
|
395
|
-
if (!nativeCandidate) throw new Error("Codex runtime did not resolve a native executable");
|
|
396
|
-
const nativePath = await fs.realpath(await resolveCommandPath(nativeCandidate, env, spawnCwd));
|
|
403
|
+
const nativePath = await fs.realpath(await resolveCommandPath(nativeCommand ?? nativeCandidate, env, spawnCwd));
|
|
397
404
|
const packageRoot = await resolvePackageRoot(nativePath);
|
|
398
405
|
const configuredCodeModeHost = readEffectiveSpawnEnvironmentValue(env, CODE_MODE_HOST_PATH_ENV)?.trim();
|
|
399
406
|
const adjacentCodeModeHost = path.join(path.dirname(nativePath), process.platform === "win32" ? "codex-code-mode-host.exe" : "codex-code-mode-host");
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { P as
|
|
2
|
+
import { P as CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN, j as normalizeCodexServiceTier } from "./config-BhmfC1s6.js";
|
|
3
3
|
import { n as CODEX_APP_SERVER_BINDING_NAMESPACE, t as CODEX_APP_SERVER_BINDING_MAX_ENTRIES } from "./session-binding-meta-B7aEMU7g.js";
|
|
4
4
|
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { AgentHarnessSessionSupersededError, embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
|
-
import {
|
|
7
|
+
import { isDeepStrictEqual } from "node:util";
|
|
8
|
+
import { ensureAuthProfileStore, resolveDefaultAgentDir, resolveProviderIdForAuth } from "openclaw/plugin-sdk/agent-runtime";
|
|
9
|
+
import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
8
10
|
import { z } from "zod";
|
|
9
11
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
10
12
|
import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
@@ -29,7 +31,8 @@ var session_binding_exports = /* @__PURE__ */ __exportAll({
|
|
|
29
31
|
reclaimCurrentCodexSessionGeneration: () => reclaimCurrentCodexSessionGeneration,
|
|
30
32
|
resolveCodexRunSessionBindingAuthority: () => resolveCodexRunSessionBindingAuthority,
|
|
31
33
|
scopeCodexRunBindingStore: () => scopeCodexRunBindingStore,
|
|
32
|
-
sessionBindingIdentity: () => sessionBindingIdentity
|
|
34
|
+
sessionBindingIdentity: () => sessionBindingIdentity,
|
|
35
|
+
validateBindingForWrite: () => validateBindingForWrite
|
|
33
36
|
});
|
|
34
37
|
const CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER = "openai";
|
|
35
38
|
const PUBLIC_OPENAI_MODEL_PROVIDER = "openai";
|
|
@@ -42,7 +45,7 @@ const BINDING_LEASE_RENEW_INTERVAL_MS = Math.floor(BINDING_LEASE_STALE_MS / 3);
|
|
|
42
45
|
const PHYSICAL_SESSION_RETIRE_TTL_MS = BINDING_LEASE_WAIT_MS;
|
|
43
46
|
/** Resolves the same agent scope OpenClaw uses for transcript/session ownership. */
|
|
44
47
|
function sessionBindingIdentity(params) {
|
|
45
|
-
const { sessionAgentId } =
|
|
48
|
+
const { sessionAgentId } = resolveSessionAgentIdsStrict(params);
|
|
46
49
|
const sessionKey = params.sessionKey?.trim();
|
|
47
50
|
return {
|
|
48
51
|
kind: "session",
|
|
@@ -147,6 +150,7 @@ const threadBindingSchema = z.object({
|
|
|
147
150
|
model: optionalStringSchema,
|
|
148
151
|
preserveNativeModel: z.literal(true).optional().catch(void 0),
|
|
149
152
|
pendingSupervisionBranch: pendingSupervisionBranchSchema.optional(),
|
|
153
|
+
pendingResumeConfiguration: z.literal(true).optional(),
|
|
150
154
|
modelProvider: z.string().transform((value) => value.trim()).pipe(z.string().min(1)).optional().catch(void 0),
|
|
151
155
|
approvalPolicy: z.preprocess((value) => value === "on-failure" ? "on-request" : value, z.enum([
|
|
152
156
|
"never",
|
|
@@ -318,20 +322,23 @@ function scopeCodexRunBindingStore(params) {
|
|
|
318
322
|
...params.bindingStore,
|
|
319
323
|
read: (identity) => params.bindingStore.read(mapIdentity(identity)),
|
|
320
324
|
hasOtherThreadOwner: (threadId, identity) => params.bindingStore.hasOtherThreadOwner(threadId, identity ? mapIdentity(identity) : void 0),
|
|
321
|
-
mutate: (identity, mutation) => params.bindingStore.mutate(mapIdentity(identity), mutation),
|
|
325
|
+
mutate: (identity, mutation, assertCurrent) => params.bindingStore.mutate(mapIdentity(identity), mutation, assertCurrent),
|
|
322
326
|
prepareSessionGenerationReclaim: (identity) => params.bindingStore.prepareSessionGenerationReclaim(mapSessionIdentity(identity)),
|
|
323
327
|
adoptSessionGeneration: (identity, expectedPreviousSessionId) => params.bindingStore.adoptSessionGeneration(mapSessionIdentity(identity), expectedPreviousSessionId),
|
|
324
328
|
resetSessionGeneration: (identity) => params.bindingStore.resetSessionGeneration(mapSessionIdentity(identity)),
|
|
325
329
|
retireSessionGeneration: (identity) => params.bindingStore.retireSessionGeneration(mapSessionIdentity(identity)),
|
|
330
|
+
withSessionDeletion: (identity, assertCurrent, run) => params.bindingStore.withSessionDeletion(mapSessionIdentity(identity), assertCurrent, run),
|
|
326
331
|
withThreadArchiveFence: (run) => params.bindingStore.withThreadArchiveFence(run),
|
|
327
332
|
withLease: (identity, run) => params.bindingStore.withLease(mapIdentity(identity), run)
|
|
328
333
|
};
|
|
329
334
|
}
|
|
330
335
|
/** Lets the authoritative OpenClaw session generation claim a stale stable binding row. */
|
|
331
336
|
async function reclaimCurrentCodexSessionGeneration(params) {
|
|
337
|
+
params.assertCurrent?.();
|
|
332
338
|
const sessionKey = params.identity.sessionKey?.trim();
|
|
333
339
|
if (!sessionKey) return true;
|
|
334
340
|
const plan = await params.bindingStore.prepareSessionGenerationReclaim(params.identity);
|
|
341
|
+
params.assertCurrent?.();
|
|
335
342
|
if (plan.kind === "resolved") return plan.result;
|
|
336
343
|
try {
|
|
337
344
|
const storePath = params.storePath?.trim() || resolveStorePath(params.config?.session?.store, { agentId: params.identity.agentId });
|
|
@@ -348,7 +355,7 @@ async function reclaimCurrentCodexSessionGeneration(params) {
|
|
|
348
355
|
return await params.bindingStore.mutate(params.identity, {
|
|
349
356
|
kind: "reclaim-generation",
|
|
350
357
|
expectedPreviousSessionId: plan.expectedPreviousSessionId
|
|
351
|
-
});
|
|
358
|
+
}, params.assertCurrent);
|
|
352
359
|
}
|
|
353
360
|
/** Creates the single binding facade owned by the Codex plugin runtime. */
|
|
354
361
|
function createCodexAppServerBindingStore(state) {
|
|
@@ -382,9 +389,10 @@ function createCodexAppServerBindingStore(state) {
|
|
|
382
389
|
}
|
|
383
390
|
};
|
|
384
391
|
const renewLease = (key, owner) => {
|
|
385
|
-
if (owner.failure) return;
|
|
392
|
+
if (owner.failure || owner.phase !== "held") return;
|
|
386
393
|
try {
|
|
387
394
|
let renewed = false;
|
|
395
|
+
owner.assertCurrent?.();
|
|
388
396
|
const stored = update(key, (raw) => {
|
|
389
397
|
const current = readStoredCodexAppServerBinding(raw);
|
|
390
398
|
if (raw !== void 0 && !current) throw new Error(`Invalid Codex app-server binding row: ${key}`);
|
|
@@ -405,15 +413,18 @@ function createCodexAppServerBindingStore(state) {
|
|
|
405
413
|
owner.failure = bindingLeaseLostError(key, error);
|
|
406
414
|
}
|
|
407
415
|
};
|
|
408
|
-
const transactKey = async (key, apply, ttlMs) => {
|
|
416
|
+
const transactKey = async (key, apply, ttlMs, assertCurrent) => {
|
|
409
417
|
const deadline = Date.now() + BINDING_LEASE_WAIT_MS;
|
|
410
418
|
while (true) {
|
|
411
419
|
let busy = false;
|
|
412
420
|
let leaseLost = false;
|
|
413
421
|
let result;
|
|
414
422
|
const ownedLease = leaseContext.getStore()?.get(key);
|
|
423
|
+
if (ownedLease && ownedLease.phase !== "held") throw bindingLeaseLostError(key);
|
|
415
424
|
if (ownedLease?.failure) throw ownedLease.failure;
|
|
416
425
|
const ownedToken = ownedLease?.token;
|
|
426
|
+
assertCurrent?.();
|
|
427
|
+
ownedLease?.assertCurrent?.();
|
|
417
428
|
update(key, (raw) => {
|
|
418
429
|
const current = readStoredCodexAppServerBinding(raw);
|
|
419
430
|
if (raw !== void 0 && !current) throw new Error(`Invalid Codex app-server binding row: ${key}`);
|
|
@@ -441,6 +452,115 @@ function createCodexAppServerBindingStore(state) {
|
|
|
441
452
|
await sleep(BINDING_LEASE_RETRY_INTERVAL_MS);
|
|
442
453
|
}
|
|
443
454
|
};
|
|
455
|
+
const withBindingLease = async (identity, run, options = {}) => {
|
|
456
|
+
options.assertCurrent?.();
|
|
457
|
+
const key = bindingStoreKey(identity);
|
|
458
|
+
const owned = leaseContext.getStore();
|
|
459
|
+
const existingOwner = owned?.get(key);
|
|
460
|
+
if (existingOwner) {
|
|
461
|
+
if (existingOwner.phase !== "held") throw bindingLeaseLostError(key);
|
|
462
|
+
const failureBeforeRun = existingOwner.failure;
|
|
463
|
+
if (failureBeforeRun) throw failureBeforeRun;
|
|
464
|
+
const result = await run();
|
|
465
|
+
options.assertCurrent?.();
|
|
466
|
+
const failureAfterRun = existingOwner.failure;
|
|
467
|
+
if (failureAfterRun) throw failureAfterRun;
|
|
468
|
+
return result;
|
|
469
|
+
}
|
|
470
|
+
const token = randomUUID();
|
|
471
|
+
const acquired = await transactKey(key, (current) => {
|
|
472
|
+
if (current?.state === "cleared" && current.retired === true && ownsStoredSessionGeneration(identity, current) && !options.allowRetired) return { result: false };
|
|
473
|
+
const lease = {
|
|
474
|
+
token,
|
|
475
|
+
expiresAt: Date.now() + BINDING_LEASE_STALE_MS
|
|
476
|
+
};
|
|
477
|
+
if (current?.state === "active") return {
|
|
478
|
+
result: true,
|
|
479
|
+
next: {
|
|
480
|
+
...current,
|
|
481
|
+
...preservedSessionGeneration(identity, current),
|
|
482
|
+
lease
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
if (current?.state === "cleared" && current.retired === true) return {
|
|
486
|
+
result: true,
|
|
487
|
+
next: {
|
|
488
|
+
...current,
|
|
489
|
+
lease
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
return {
|
|
493
|
+
result: true,
|
|
494
|
+
next: {
|
|
495
|
+
version: 1,
|
|
496
|
+
state: "cleared",
|
|
497
|
+
...preservedSessionGeneration(identity, current),
|
|
498
|
+
lease
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
}, void 0, options.assertCurrent);
|
|
502
|
+
options.assertCurrent?.();
|
|
503
|
+
if (!acquired) throw new Error(`Codex binding generation was retired: ${key}`);
|
|
504
|
+
const owner = {
|
|
505
|
+
token,
|
|
506
|
+
phase: "held",
|
|
507
|
+
assertCurrent: options.assertCurrent
|
|
508
|
+
};
|
|
509
|
+
const nested = new Map(owned);
|
|
510
|
+
nested.set(key, owner);
|
|
511
|
+
const heartbeat = setInterval(() => renewLease(key, owner), BINDING_LEASE_RENEW_INTERVAL_MS);
|
|
512
|
+
heartbeat.unref();
|
|
513
|
+
try {
|
|
514
|
+
const result = await leaseContext.run(nested, run);
|
|
515
|
+
options.assertCurrent?.();
|
|
516
|
+
if (owner.failure) throw owner.failure;
|
|
517
|
+
return result;
|
|
518
|
+
} finally {
|
|
519
|
+
clearInterval(heartbeat);
|
|
520
|
+
owner.phase = "closed";
|
|
521
|
+
options.assertCurrent?.();
|
|
522
|
+
try {
|
|
523
|
+
const current = readStoredCodexAppServerBinding(state.lookup(key));
|
|
524
|
+
if (current?.lease?.token === token) {
|
|
525
|
+
const ttlMs = current.state === "active" || current.retired === true && !key.startsWith("session:") ? void 0 : current.retired === true ? PHYSICAL_SESSION_RETIRE_TTL_MS : 1;
|
|
526
|
+
options.assertCurrent?.();
|
|
527
|
+
update(key, (raw) => {
|
|
528
|
+
const stored = readStoredCodexAppServerBinding(raw);
|
|
529
|
+
if (stored?.lease?.token !== token) return;
|
|
530
|
+
const { lease: _lease, ...released } = stored;
|
|
531
|
+
return released;
|
|
532
|
+
}, ttlMs === void 0 ? void 0 : { ttlMs });
|
|
533
|
+
}
|
|
534
|
+
} catch (error) {
|
|
535
|
+
options.assertCurrent?.();
|
|
536
|
+
embeddedAgentLog.warn("failed to release codex app-server binding lease", {
|
|
537
|
+
key,
|
|
538
|
+
error
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
const transitionSessionGeneration = async (identity, mode) => {
|
|
544
|
+
return await runBindingMutation(async () => {
|
|
545
|
+
const key = bindingStoreKey(identity);
|
|
546
|
+
const ttlMs = mode === "reset" ? leaseContext.getStore()?.has(key) ? void 0 : 1 : identity.sessionKey?.trim() ? void 0 : PHYSICAL_SESSION_RETIRE_TTL_MS;
|
|
547
|
+
return await transactKey(key, (current, leaseToken) => {
|
|
548
|
+
if (!current) return { result: "absent" };
|
|
549
|
+
if (!ownsStoredSessionGeneration(identity, current)) return { result: "conflict" };
|
|
550
|
+
if (current.state === "cleared" && current.retired === true) return { result: mode === "retire" ? "applied" : "conflict" };
|
|
551
|
+
return {
|
|
552
|
+
result: "applied",
|
|
553
|
+
next: {
|
|
554
|
+
version: 1,
|
|
555
|
+
state: "cleared",
|
|
556
|
+
...mode === "retire" ? { retired: true } : {},
|
|
557
|
+
...storedSessionGeneration(identity, current),
|
|
558
|
+
...current.lease && current.lease.token === leaseToken ? { lease: current.lease } : {}
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
}, ttlMs);
|
|
562
|
+
});
|
|
563
|
+
};
|
|
444
564
|
return {
|
|
445
565
|
async read(identity) {
|
|
446
566
|
const key = bindingStoreKey(identity);
|
|
@@ -485,7 +605,7 @@ function createCodexAppServerBindingStore(state) {
|
|
|
485
605
|
expectedPreviousSessionId: currentSessionId
|
|
486
606
|
};
|
|
487
607
|
},
|
|
488
|
-
async mutate(identity, mutation) {
|
|
608
|
+
async mutate(identity, mutation, assertCurrent) {
|
|
489
609
|
return await runBindingMutation(async () => {
|
|
490
610
|
const key = bindingStoreKey(identity);
|
|
491
611
|
const retainLegacyClear = mutation.kind === "clear" && key.startsWith("conversation:legacy-");
|
|
@@ -523,9 +643,8 @@ function createCodexAppServerBindingStore(state) {
|
|
|
523
643
|
const active = ownsGeneration ? storedActive : void 0;
|
|
524
644
|
const retiredGeneration = current?.state === "cleared" && current.retired === true && ownsGeneration;
|
|
525
645
|
const preservesSupervisionOwner = mutation.kind === "set" && active?.binding.connectionScope === "supervision" && isSameSupervisionOwner(active.binding, mutation.binding);
|
|
526
|
-
const clearsPendingSupervisionOwner = mutation.kind === "clear" && active?.binding.connectionScope === "supervision" && matchesPendingSupervisionClear(active.binding, mutation.threadId, mutation.expectedPendingSupervisionBranch);
|
|
527
646
|
const replacesExpectedOrdinaryOwner = mutation.kind === "replace-thread" && active?.binding.threadId === mutation.expectedThreadId && active.binding.connectionScope !== "supervision" && mutation.binding.connectionScope !== "supervision" && mutation.binding.threadId !== mutation.expectedThreadId;
|
|
528
|
-
if (mutation.kind === "set" && (mutation.if?.kind === "absent" && storedActive || current !== void 0 && !ownsGeneration || retiredGeneration || active?.binding.connectionScope === "supervision" && !preservesSupervisionOwner) || mutation.kind === "patch" && active?.binding.threadId !== mutation.threadId || mutation.kind === "replace-thread" && !replacesExpectedOrdinaryOwner || (mutation.kind === "patch-pending-supervision-branch" || mutation.kind === "commit-pending-supervision-branch") && !matchesPendingSupervisionBranch(active?.binding, mutation.expected) || mutation.kind === "clear" && (mutation.threadId !== void 0 && active?.binding.threadId !== mutation.threadId ||
|
|
647
|
+
if (mutation.kind === "set" && (mutation.if?.kind === "absent" && storedActive || current !== void 0 && !ownsGeneration || retiredGeneration || active?.binding.connectionScope === "supervision" && !preservesSupervisionOwner) || mutation.kind === "patch" && active?.binding.threadId !== mutation.threadId || mutation.kind === "replace-thread" && !replacesExpectedOrdinaryOwner || (mutation.kind === "patch-pending-supervision-branch" || mutation.kind === "commit-pending-supervision-branch") && !matchesPendingSupervisionBranch(active?.binding, mutation.expected) || mutation.kind === "clear" && (!ownsGeneration || mutation.threadId !== void 0 && active?.binding.threadId !== mutation.threadId || active?.binding.connectionScope === "supervision")) return { result: false };
|
|
529
648
|
if (mutation.kind === "clear" && retiredGeneration) return { result: true };
|
|
530
649
|
if (mutation.kind === "clear") return {
|
|
531
650
|
result: true,
|
|
@@ -563,7 +682,7 @@ function createCodexAppServerBindingStore(state) {
|
|
|
563
682
|
...ownedLease
|
|
564
683
|
}
|
|
565
684
|
};
|
|
566
|
-
}, mutation.kind === "clear" && !retainLegacyClear && !leaseContext.getStore()?.has(key) ? 1 : void 0);
|
|
685
|
+
}, mutation.kind === "clear" && !retainLegacyClear && !leaseContext.getStore()?.has(key) ? 1 : void 0, assertCurrent);
|
|
567
686
|
});
|
|
568
687
|
},
|
|
569
688
|
async adoptSessionGeneration(identity, expectedPreviousSessionId) {
|
|
@@ -586,45 +705,8 @@ function createCodexAppServerBindingStore(state) {
|
|
|
586
705
|
});
|
|
587
706
|
});
|
|
588
707
|
},
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
const key = bindingStoreKey(identity);
|
|
592
|
-
return await transactKey(key, (current, leaseToken) => {
|
|
593
|
-
if (!current) return { result: "absent" };
|
|
594
|
-
if (!ownsStoredSessionGeneration(identity, current)) return { result: "conflict" };
|
|
595
|
-
if (current.state === "cleared" && current.retired === true) return { result: "conflict" };
|
|
596
|
-
return {
|
|
597
|
-
result: "applied",
|
|
598
|
-
next: {
|
|
599
|
-
version: 1,
|
|
600
|
-
state: "cleared",
|
|
601
|
-
...storedSessionGeneration(identity, current),
|
|
602
|
-
...current.lease && current.lease.token === leaseToken ? { lease: current.lease } : {}
|
|
603
|
-
}
|
|
604
|
-
};
|
|
605
|
-
}, leaseContext.getStore()?.has(key) ? void 0 : 1);
|
|
606
|
-
});
|
|
607
|
-
},
|
|
608
|
-
async retireSessionGeneration(identity) {
|
|
609
|
-
return await runBindingMutation(async () => {
|
|
610
|
-
const key = bindingStoreKey(identity);
|
|
611
|
-
return await transactKey(key, (current, leaseToken) => {
|
|
612
|
-
if (!current) return { result: "absent" };
|
|
613
|
-
if (!ownsStoredSessionGeneration(identity, current)) return { result: "conflict" };
|
|
614
|
-
if (current.state === "cleared" && current.retired === true) return { result: "applied" };
|
|
615
|
-
return {
|
|
616
|
-
result: "applied",
|
|
617
|
-
next: {
|
|
618
|
-
version: 1,
|
|
619
|
-
state: "cleared",
|
|
620
|
-
retired: true,
|
|
621
|
-
...storedSessionGeneration(identity, current),
|
|
622
|
-
...current.lease && current.lease.token === leaseToken ? { lease: current.lease } : {}
|
|
623
|
-
}
|
|
624
|
-
};
|
|
625
|
-
}, identity.sessionKey?.trim() ? void 0 : PHYSICAL_SESSION_RETIRE_TTL_MS);
|
|
626
|
-
});
|
|
627
|
-
},
|
|
708
|
+
resetSessionGeneration: (identity) => transitionSessionGeneration(identity, "reset"),
|
|
709
|
+
retireSessionGeneration: (identity) => transitionSessionGeneration(identity, "retire"),
|
|
628
710
|
async withThreadArchiveFence(run) {
|
|
629
711
|
pendingArchives += 1;
|
|
630
712
|
const operation = archiveTail.then(async () => {
|
|
@@ -638,79 +720,73 @@ function createCodexAppServerBindingStore(state) {
|
|
|
638
720
|
pendingArchives -= 1;
|
|
639
721
|
}
|
|
640
722
|
},
|
|
641
|
-
async
|
|
723
|
+
async withSessionDeletion(identity, assertCurrent, run) {
|
|
642
724
|
const key = bindingStoreKey(identity);
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
if (
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
};
|
|
660
|
-
if (current?.state === "active") return {
|
|
661
|
-
result: true,
|
|
662
|
-
next: {
|
|
663
|
-
...current,
|
|
664
|
-
...preservedSessionGeneration(identity, current),
|
|
665
|
-
lease
|
|
666
|
-
}
|
|
667
|
-
};
|
|
668
|
-
if (current?.state === "cleared" && current.retired === true) return {
|
|
669
|
-
result: true,
|
|
670
|
-
next: {
|
|
671
|
-
...current,
|
|
672
|
-
lease
|
|
673
|
-
}
|
|
674
|
-
};
|
|
675
|
-
return {
|
|
676
|
-
result: true,
|
|
677
|
-
next: {
|
|
678
|
-
version: 1,
|
|
679
|
-
state: "cleared",
|
|
680
|
-
...preservedSessionGeneration(identity, current),
|
|
681
|
-
lease
|
|
725
|
+
const deleteIf = state.deleteIf?.bind(state);
|
|
726
|
+
if (!deleteIf) throw new Error("Codex session deletion requires conditional plugin-state deletion");
|
|
727
|
+
return await runBindingMutation(async () => {
|
|
728
|
+
assertCurrent();
|
|
729
|
+
if (state.lookup(key) === void 0) {
|
|
730
|
+
let active = true;
|
|
731
|
+
try {
|
|
732
|
+
return await run(void 0, {
|
|
733
|
+
commit() {
|
|
734
|
+
assertCurrent();
|
|
735
|
+
if (!active || state.lookup(key) !== void 0) throw new Error("Codex binding changed before session deletion");
|
|
736
|
+
},
|
|
737
|
+
rollback() {}
|
|
738
|
+
});
|
|
739
|
+
} finally {
|
|
740
|
+
active = false;
|
|
682
741
|
}
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
} finally {
|
|
695
|
-
clearInterval(heartbeat);
|
|
696
|
-
try {
|
|
697
|
-
const removeOwnedLease = (raw, matches) => {
|
|
698
|
-
const current = readStoredCodexAppServerBinding(raw);
|
|
699
|
-
if (!current || !matches(current) || current.lease?.token !== token) return;
|
|
700
|
-
const { lease: _lease, ...released } = current;
|
|
701
|
-
return released;
|
|
742
|
+
}
|
|
743
|
+
return await withBindingLease(identity, async () => {
|
|
744
|
+
const owner = leaseContext.getStore().get(key);
|
|
745
|
+
const stored = readStoredCodexAppServerBinding(state.lookup(key));
|
|
746
|
+
if (!stored || !ownsStoredSessionGeneration(identity, stored)) throw new Error("Codex binding generation changed before session deletion");
|
|
747
|
+
const { lease: _lease, ...expectedValue } = stored;
|
|
748
|
+
let deleted;
|
|
749
|
+
let active = true;
|
|
750
|
+
const assertActive = () => {
|
|
751
|
+
assertCurrent();
|
|
752
|
+
if (!active || owner.phase === "closed" || owner.failure) throw owner.failure ?? bindingLeaseLostError(key);
|
|
702
753
|
};
|
|
703
|
-
|
|
704
|
-
|
|
754
|
+
try {
|
|
755
|
+
return await run(stored.state === "active" ? stored.binding : void 0, {
|
|
756
|
+
commit() {
|
|
757
|
+
assertActive();
|
|
758
|
+
if (deleted) return;
|
|
759
|
+
const current = state.lookup(key);
|
|
760
|
+
const { lease, ...value } = readStoredCodexAppServerBinding(current) ?? {};
|
|
761
|
+
if (!current || lease?.token !== owner.token || lease.expiresAt <= Date.now() || !isDeepStrictEqual(value, expectedValue) || !deleteIf(key, (raw) => isDeepStrictEqual(raw, current))) throw new Error("Codex binding changed before session deletion");
|
|
762
|
+
deleted = current;
|
|
763
|
+
owner.phase = "deleted";
|
|
764
|
+
},
|
|
765
|
+
rollback() {
|
|
766
|
+
assertActive();
|
|
767
|
+
if (!deleted) return;
|
|
768
|
+
const restored = {
|
|
769
|
+
...deleted,
|
|
770
|
+
lease: {
|
|
771
|
+
token: owner.token,
|
|
772
|
+
expiresAt: Date.now() + BINDING_LEASE_STALE_MS
|
|
773
|
+
}
|
|
774
|
+
};
|
|
775
|
+
if (!state.registerIfAbsent(key, restored)) throw new Error("Codex binding changed before session deletion rollback");
|
|
776
|
+
deleted = void 0;
|
|
777
|
+
owner.phase = "held";
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
} finally {
|
|
781
|
+
active = false;
|
|
705
782
|
}
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
}
|
|
783
|
+
}, {
|
|
784
|
+
allowRetired: true,
|
|
785
|
+
assertCurrent
|
|
786
|
+
});
|
|
787
|
+
});
|
|
788
|
+
},
|
|
789
|
+
withLease: withBindingLease
|
|
714
790
|
};
|
|
715
791
|
}
|
|
716
792
|
function matchesPendingSupervisionBranch(binding, expected) {
|
|
@@ -724,11 +800,6 @@ function matchesPendingSupervisionBranch(binding, expected) {
|
|
|
724
800
|
function isSameSupervisionOwner(current, replacement) {
|
|
725
801
|
return replacement.connectionScope === "supervision" && replacement.threadId === current.threadId && replacement.supervisionSourceThreadId === current.supervisionSourceThreadId;
|
|
726
802
|
}
|
|
727
|
-
function matchesPendingSupervisionClear(binding, threadId, expected) {
|
|
728
|
-
if (!expected) return false;
|
|
729
|
-
const sourceThreadId = expected.sourceThreadId;
|
|
730
|
-
return threadId === sourceThreadId && binding.supervisionSourceThreadId === sourceThreadId && matchesPendingSupervisionBranch(binding, expected);
|
|
731
|
-
}
|
|
732
803
|
/** Stable plugin-state key for one current binding owner. */
|
|
733
804
|
function bindingStoreKey(identity) {
|
|
734
805
|
if (identity.kind === "session") {
|
|
@@ -736,7 +807,7 @@ function bindingStoreKey(identity) {
|
|
|
736
807
|
const sessionId = identity.sessionId.trim();
|
|
737
808
|
if (!rawAgentId) throw new Error("Codex app-server binding requires an agent id");
|
|
738
809
|
if (!sessionId) throw new Error("Codex app-server binding requires a session id");
|
|
739
|
-
const agentId =
|
|
810
|
+
const agentId = resolveSessionAgentIdsStrict({ agentId: rawAgentId }).sessionAgentId;
|
|
740
811
|
const sessionKey = identity.sessionKey?.trim();
|
|
741
812
|
if (sessionKey) return `session-key:${agentId}:${createHash("sha256").update(sessionKey).digest("base64url")}`;
|
|
742
813
|
return `session:${agentId}:${sessionId}`;
|
|
@@ -871,4 +942,4 @@ function normalizeCodexAppServerBindingModelProvider(params) {
|
|
|
871
942
|
return modelProvider;
|
|
872
943
|
}
|
|
873
944
|
//#endregion
|
|
874
|
-
export { hashCodexAppServerBindingFingerprint as a, reclaimCurrentCodexSessionGeneration as c, sessionBindingIdentity as d, session_binding_exports as f, createCodexSessionGenerationSupersededError as i, resolveCodexRunSessionBindingAuthority as l, assertCodexBindingMayBeReplaced as n, isCodexAppServerNativeAuthProfile as o, bindingStoreKey as r, normalizeCodexAppServerBindingModelProvider as s, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS as t, scopeCodexRunBindingStore as u };
|
|
945
|
+
export { hashCodexAppServerBindingFingerprint as a, reclaimCurrentCodexSessionGeneration as c, sessionBindingIdentity as d, session_binding_exports as f, createCodexSessionGenerationSupersededError as i, resolveCodexRunSessionBindingAuthority as l, assertCodexBindingMayBeReplaced as n, isCodexAppServerNativeAuthProfile as o, validateBindingForWrite as p, bindingStoreKey as r, normalizeCodexAppServerBindingModelProvider as s, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS as t, scopeCodexRunBindingStore as u };
|