@openclaw/codex 2026.9.1 → 2026.9.2

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.
Files changed (67) hide show
  1. package/dist/api.js +6 -6
  2. package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-Bp1ZOnk2.js} +76 -32
  3. package/dist/{attempt-context-DmQUNWwT.js → attempt-context-CSazkWns.js} +6 -6
  4. package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-DxGJRYbY.js} +46 -45
  5. package/dist/{capabilities-dIjNVCYH.js → capabilities-B1mgvpP8.js} +2 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DSbGMXA0.js} +2 -2
  8. package/dist/{command-handlers-CTGb2csu.js → command-handlers-DOJvGv6-.js} +146 -74
  9. package/dist/{compact-_t0HQrUS.js → compact-Y_xBqrHN.js} +83 -48
  10. package/dist/{config-BhmfC1s6.js → config-CyapYSji.js} +47 -105
  11. package/dist/config-utils-C57JiJrU.js +69 -0
  12. package/dist/doctor-contract-api.js +4 -5
  13. package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-BwpvTxaX.js} +678 -638
  14. package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-CY9Jn4bA.js} +4 -3
  15. package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-B9kp6iGC.js} +11 -2
  16. package/dist/{event-projector-usage-C5mcrGjp.js → event-projector-usage-ZqEVbAEY.js} +30 -13
  17. package/dist/{harness-DXVZ5II5.js → harness-Czh2Sdoc.js} +36 -13
  18. package/dist/harness.js +1 -1
  19. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  20. package/dist/index.js +68 -84
  21. package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-CRh-51AK.js} +9 -21
  22. package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DcpnJF9x.js} +105 -73
  23. package/dist/media-understanding-provider.js +1 -1
  24. package/dist/{model-catalog-CUM68Hkl.js → model-catalog-DT5vo6qo.js} +5 -5
  25. package/dist/{models-sYnEc0gd.js → models-CcrgSMQR.js} +4 -4
  26. package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-B3bvQGcg.js} +12 -11
  27. package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-nfbUOtUB.js} +3 -3
  28. package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-aQVdyL5g.js} +1 -1
  29. package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → plugin-marketplace-discovery-B7gHXJ3d.js} +35 -22
  30. package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-BwCLTY_U.js} +5 -5
  31. package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-BpG9Ltc5.js} +2 -2
  32. package/dist/{rate-limits-CawQJfUS.js → rate-limits-Fx_l4eNa.js} +1 -1
  33. package/dist/{request-DYAI5FQE.js → request-C8H22rPi.js} +2 -2
  34. package/dist/{run-attempt-D1hJO4fX.js → run-attempt-BzthFQSM.js} +977 -723
  35. package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-Bh_gf6-t.js} +3 -3
  36. package/dist/{session-binding-BHuTCRZQ.js → session-binding-4Ki04sW-.js} +94 -282
  37. package/dist/session-binding-record-CyaXZvTe.js +270 -0
  38. package/dist/{session-catalog-yyvTWFOw.js → session-catalog-B47uwekb.js} +266 -114
  39. package/dist/{session-cli-CmFEXMAM.js → session-cli-BjLhpmS1.js} +1 -1
  40. package/dist/session-history-DWmMqiqW.js +93 -0
  41. package/dist/session-history-read-LHldwvyh.js +36 -0
  42. package/dist/session-history-worker-runtime.js +48 -0
  43. package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-zZVcx0ME.js} +30 -31
  44. package/dist/session-history.worker.js +2 -0
  45. package/dist/{session-initialization-BeWzjGiR.js → session-initialization-BCFVnLL4.js} +2 -1
  46. package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-BaueHmSj.js} +1 -1
  47. package/dist/{session-retirement-BujDjXVF.js → session-retirement-DNdmYdFc.js} +7 -7
  48. package/dist/{session-upstream-marker-C351-5Qw.js → session-upstream-marker-DReTpGz6.js} +4 -3
  49. package/dist/settled-turn-context-BOM3Y1pl.js +45 -0
  50. package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BI-b1sry.js} +53 -42
  51. package/dist/{shared-client-DxcfF9KX.js → shared-client-CKhX2kFt.js} +279 -268
  52. package/dist/{side-question-BTZAII4l.js → side-question-B6DWAw1A.js} +85 -36
  53. package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-DPK30jad.js} +382 -388
  54. package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-CbucAmmp.js} +5 -5
  55. package/dist/thread-policy-CTalhWFy.js +105 -0
  56. package/dist/{thread-resume-C7pyVKeW.js → thread-resume-BLgqkUc1.js} +7 -7
  57. package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-_njEB84z.js} +67 -125
  58. package/dist/transcript-mirror-attestation-Byl34PC-.js +76 -0
  59. package/dist/{transport-stdio-CyPldczm.js → transport-stdio-CzTngV0j.js} +10 -8
  60. package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-1fwbNKzQ.js} +85 -165
  61. package/dist/{usage-Bj-rrzkR.js → usage-i9fv5-4m.js} +3 -3
  62. package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-DKQn67A7.js} +3 -3
  63. package/package.json +6 -6
  64. package/dist/binding-connection-E6uDsPlx.js +0 -45
  65. package/dist/launch-args-RXQwn8zV.js +0 -90
  66. package/dist/session-history-C5J1AKzG.js +0 -87
  67. package/dist/thread-policy-g4KbJPzp.js +0 -54
@@ -1,83 +1,50 @@
1
- import { $t as isJsonObject, Jt as readCodexSessionMeta, Q as assertCodexThreadForkResponse, Qt as flattenCodexDynamicToolFunctions, X as assertCodexThreadAcceptsDirectInput, f as readCodexAppServerClientDesktopGenerationFingerprint, wt as hasCodexAppServerLiveThread, xt as claimCodexAppServerLiveThread } from "./shared-client-DxcfF9KX.js";
2
- import { E as readCodexPluginConfig, O as resolveOpenClawExecPolicyForCodexAppServer, p as assertCodexModelBackedReviewerEffectiveConfig, s as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-BhmfC1s6.js";
3
- import { d as sessionBindingIdentity } from "./session-binding-BHuTCRZQ.js";
4
- import { i as buildCodexPluginAppCacheKey } from "./thread-resume-C7pyVKeW.js";
5
- import { $ as resolveCodexNativeSkillIsolation, C as buildDeveloperInstructions, Ct as buildCodexPluginThreadConfig, Dt as mergeCodexThreadConfigs, F as assertCodexNativeHookRelayAllowed, I as buildCodexNativeHookRelayConfig, Ot as shouldBuildCodexPluginThreadConfig, Q as applyCodexNativeSkillIsolation, R as buildCodexNativeHookRelayId, S as resolveCodexWebSearchPlan, V as resolveCodexNativeHookRelayEvents, W as attestCodexPluginThreadApps, Z as parseCodexNativeToolCatalog, it as fingerprintUserMcpServersConfigPatch, rt as fingerprintJsonObject, tt as codexDynamicToolsFingerprint, y as buildCodexThreadConfiguration } from "./thread-lifecycle-DAcEJ_Om.js";
6
- import { o as withCodexAppServerThreadMutation } from "./thread-ownership-zGokd8i1.js";
7
- import { c as fingerprintCodexMirrorSourceMessage, m as projectCodexUserItemText, u as readCodexMirrorSourceFingerprint } from "./transcript-mirror-DTUxFWa_.js";
8
- import { l as resolveCodexNativeExecutionPolicy, t as CodexAppServerScopedRequestRejectedError } from "./request-DYAI5FQE.js";
9
- import { i as refreshCodexThreadPolicy, n as CodexThreadPolicyHandoffError } from "./thread-policy-g4KbJPzp.js";
1
+ import { l as sessionBindingIdentity } from "./session-binding-record-CyaXZvTe.js";
2
+ import { A as resolveOpenClawExecPolicyForCodexAppServer, B as isJsonObject, O as readCodexPluginConfig, p as assertCodexModelBackedReviewerEffectiveConfig, s as resolveCodexSupervisionAppServerRuntimeOptions, z as flattenCodexDynamicToolFunctions } from "./config-CyapYSji.js";
3
+ import { Ct as claimCodexAppServerLiveThread, Et as hasCodexAppServerLiveThread, Q as assertCodexThreadAcceptsDirectInput, Xt as readCodexSessionMeta, et as assertCodexThreadForkResponse, f as readCodexAppServerClientDesktopGenerationFingerprint } from "./shared-client-CKhX2kFt.js";
4
+ import "./session-binding-4Ki04sW-.js";
5
+ import { i as buildCodexPluginAppCacheKey } from "./thread-resume-BLgqkUc1.js";
6
+ import { $ as resolveCodexNativeSkillIsolation, C as buildDeveloperInstructions, Et as mergeCodexThreadConfigs, F as assertCodexNativeHookRelayAllowed, I as buildCodexNativeHookRelayConfig, Ot as shouldBuildCodexPluginThreadConfig, Q as applyCodexNativeSkillIsolation, R as buildCodexNativeHookRelayId, S as resolveCodexWebSearchPlan, St as buildCodexPluginThreadConfig, V as resolveCodexNativeHookRelayEvents, W as checkCodexThreadAppAvailability, Z as parseCodexNativeToolCatalog, it as fingerprintUserMcpServersConfigPatch, rt as fingerprintJsonObject, tt as codexDynamicToolsFingerprint, y as buildCodexThreadConfiguration } from "./thread-lifecycle-DPK30jad.js";
7
+ import { o as withCodexAppServerThreadMutation } from "./thread-ownership-CbucAmmp.js";
8
+ import { i as refreshCodexThreadPolicy, n as CodexThreadPolicyHandoffError } from "./thread-policy-CTalhWFy.js";
9
+ import { l as projectCodexUserItemText } from "./transcript-mirror-_njEB84z.js";
10
+ import { l as resolveCodexNativeExecutionPolicy, t as CodexAppServerScopedRequestRejectedError } from "./request-C8H22rPi.js";
10
11
  import { i as readUpstreamUserText, r as readMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.js";
11
- import { n as prepareCodexSessionInitialization } from "./session-initialization-BeWzjGiR.js";
12
- import { i as createImportedCodexSession, n as codexUpstreamBaseline, t as codexLastTerminalTurnId } from "./session-upstream-marker-C351-5Qw.js";
13
- import { l as isCodexDynamicToolExcluded, n as resolveCodexProviderWebSearchSupportForClient } from "./provider-capabilities-DW5p4k9w.js";
14
- import { o as prepareCodexWorkspaceDeveloperInstructions } from "./attempt-context-DmQUNWwT.js";
12
+ import { i as fingerprintCodexMirrorSourceMessage, o as readCodexMirrorSourceFingerprint } from "./transcript-mirror-attestation-Byl34PC-.js";
13
+ import { n as prepareCodexSessionInitialization } from "./session-initialization-BCFVnLL4.js";
14
+ import { i as createImportedCodexSession, n as codexUpstreamBaseline, t as codexLastTerminalTurnId } from "./session-upstream-marker-DReTpGz6.js";
15
+ import { l as isCodexDynamicToolExcluded, n as resolveCodexProviderWebSearchSupportForClient } from "./provider-capabilities-BpG9Ltc5.js";
16
+ import { o as prepareCodexWorkspaceDeveloperInstructions } from "./attempt-context-CSazkWns.js";
15
17
  import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
18
+ import { randomUUID } from "node:crypto";
19
+ import { resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
16
20
  import { lstat } from "node:fs/promises";
17
21
  import path from "node:path";
18
22
  import { loadCodexBundleMcpThreadConfig } from "openclaw/plugin-sdk/agent-harness-runtime";
19
23
  import { constants, createZstdDecompress } from "node:zlib";
20
24
  import { root } from "openclaw/plugin-sdk/file-access-runtime";
21
- import { randomUUID } from "node:crypto";
22
25
  import { isDeepStrictEqual } from "node:util";
23
26
  import { resolveAgentWorkspaceDir } from "openclaw/plugin-sdk/agent-runtime";
24
27
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
25
- import { resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
26
28
  import { buildCodexUserMcpServersThreadConfigPatchForRuntime, resolveCodexMcpToolOverridesForAgent } from "openclaw/plugin-sdk/codex-mcp-projection";
27
29
  import { buildNativeHookRelayCommandPlan } from "openclaw/plugin-sdk/native-hook-relay-runtime";
28
30
  import { appendSessionTranscriptMessagesByIdentity, readVisibleSessionTranscriptMessageEntries } from "openclaw/plugin-sdk/session-transcript-runtime";
29
- //#region extensions/codex/src/session-rollout-selection.ts
31
+ //#region extensions/codex/src/session-rollout-snapshot.ts
30
32
  const CHUNK_BYTES = 65536;
31
- const RECORD_BYTES = 1048576;
32
- const SCAN_BYTES = 8388608;
33
- const DECOMPRESSED_BYTES = 33554432;
33
+ const META_BYTES = 1048576;
34
+ const COMPRESSED_BYTES = 8388608;
34
35
  const DEADLINE_MS = 5e3;
35
36
  const utf8Decoder = new TextDecoder("utf-8", { fatal: true });
36
- function scalar(value) {
37
- if (typeof value !== "string" || !value.trim() || Buffer.byteLength(value) > 256) throw new Error("Codex rollout has an invalid model or provider selection");
38
- return value;
39
- }
40
- function record(line) {
41
- if (!line.length || line.length > RECORD_BYTES) throw new Error("Codex rollout record exceeds the observation limit");
37
+ function parseMetadata(line, threadId) {
42
38
  const parsed = JSON.parse(utf8Decoder.decode(line));
43
- if (!isRecord(parsed) || typeof parsed.type !== "string" || !isRecord(parsed.payload)) throw new Error("Codex rollout contains an incomplete record");
44
- return {
45
- type: parsed.type,
46
- payload: parsed.payload
47
- };
39
+ if (!isRecord(parsed) || parsed.type !== "session_meta" || !isRecord(parsed.payload) || parsed.payload.id !== threadId) throw new Error("Codex rollout does not belong to the bound thread");
40
+ return parsed.payload;
48
41
  }
49
- /** Observe settings only; rollback changes history, never the native scalar selection. */
50
- function observation(parsed, threadId) {
51
- const payload = parsed.payload;
52
- if (parsed.type === "session_meta") {
53
- if (typeof payload.id !== "string") throw new Error("Codex rollout metadata is missing its thread identity");
54
- return payload.id === threadId ? { provider: scalar(payload.model_provider) } : {};
55
- }
56
- if (parsed.type === "turn_context") return { model: scalar(payload.model) };
57
- if (parsed.type === "event_msg" && payload.type === "thread_settings_applied") {
58
- if (!isRecord(payload.thread_settings)) throw new Error("Codex rollout settings are incomplete");
59
- return {
60
- model: scalar(payload.thread_settings.model),
61
- provider: scalar(payload.thread_settings.model_provider_id)
62
- };
63
- }
64
- return {};
65
- }
66
- async function readExtent(handle, start, length) {
67
- const buffer = Buffer.alloc(length);
68
- for (let offset = 0; offset < length;) {
69
- const { bytesRead } = await handle.read(buffer, offset, length - offset, start + offset);
70
- if (!bytesRead) throw new Error("Codex rollout changed during model observation");
71
- offset += bytesRead;
72
- }
73
- return buffer;
74
- }
75
- /** Latest durable selection at one verified local rollout snapshot, not live-memory state. */
76
- async function readCodexRolloutSelection(params) {
42
+ /** Read immutable metadata while pinning the entire rollout against concurrent writers. */
43
+ async function readCodexRolloutSnapshot(params) {
77
44
  const deadline = Date.now() + DEADLINE_MS;
78
45
  const check = () => {
79
46
  params.assertCurrent();
80
- if (Date.now() >= deadline) throw new Error("Codex rollout model observation timed out");
47
+ if (Date.now() >= deadline) throw new Error("Codex rollout metadata observation timed out");
81
48
  };
82
49
  check();
83
50
  const rootStat = await lstat(params.sessionsRoot);
@@ -100,94 +67,49 @@ async function readCodexRolloutSelection(params) {
100
67
  try {
101
68
  check();
102
69
  const snapshot = opened.stat;
103
- let metadata;
104
- let model;
105
- let provider;
106
- const header = (parsed) => {
107
- if (parsed.type !== "session_meta" || parsed.payload.id !== params.threadId) throw new Error("Codex rollout does not belong to the bound thread");
108
- scalar(parsed.payload.model_provider);
109
- metadata = parsed.payload;
110
- };
111
- if (selected.endsWith(".zst")) {
112
- if (snapshot.size === 0 || snapshot.size > SCAN_BYTES) throw new Error("Compressed Codex rollout exceeds the observation limit");
113
- const input = opened.handle.createReadStream({
114
- autoClose: false,
115
- highWaterMark: CHUNK_BYTES,
116
- end: snapshot.size - 1
117
- });
118
- const decoder = createZstdDecompress({
119
- chunkSize: CHUNK_BYTES,
120
- params: { [constants.ZSTD_d_windowLogMax]: 25 }
121
- });
122
- const timer = setTimeout(() => decoder.destroy(/* @__PURE__ */ new Error("Codex rollout observation timed out")), Math.max(1, deadline - Date.now()));
70
+ const unchanged = (stat) => stat.dev === snapshot.dev && stat.ino === snapshot.ino && stat.size === snapshot.size && stat.mtimeMs === snapshot.mtimeMs && stat.ctimeMs === snapshot.ctimeMs && stat.nlink === 1;
71
+ if (!snapshot.size) throw new Error("Codex rollout metadata is incomplete");
72
+ const compressed = selected.endsWith(".zst");
73
+ if (compressed && snapshot.size > COMPRESSED_BYTES) throw new Error("Compressed Codex rollout exceeds the observation limit");
74
+ const input = opened.handle.createReadStream({
75
+ autoClose: false,
76
+ highWaterMark: CHUNK_BYTES,
77
+ end: snapshot.size - 1
78
+ });
79
+ const decoder = compressed ? createZstdDecompress({
80
+ chunkSize: CHUNK_BYTES,
81
+ params: { [constants.ZSTD_d_windowLogMax]: 25 }
82
+ }) : void 0;
83
+ if (decoder) {
123
84
  input.on("error", (error) => decoder.destroy(error));
124
- const forward = input.pipe(decoder);
125
- let tail = Buffer.alloc(0);
126
- let total = 0;
127
- try {
128
- for await (const chunk of forward) {
129
- check();
130
- const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
131
- total += bytes.length;
132
- if (total > DECOMPRESSED_BYTES) throw new Error("Decompressed Codex rollout exceeds the observation limit");
133
- tail = Buffer.concat([tail, bytes]);
134
- let newline;
135
- while ((newline = tail.indexOf(10)) >= 0) {
136
- const parsed = record(tail.subarray(0, newline));
137
- if (!metadata) header(parsed);
138
- const value = observation(parsed, params.threadId);
139
- model = value.model ?? model;
140
- provider = value.provider ?? provider;
141
- tail = tail.subarray(newline + 1);
142
- }
143
- if (tail.length > RECORD_BYTES) throw new Error("Codex rollout record exceeds the observation limit");
144
- }
145
- if (tail.length) throw new Error("Codex rollout has an incomplete trailing record");
146
- } finally {
147
- clearTimeout(timer);
148
- if (!input.readableEnded) input.destroy();
149
- decoder.destroy();
150
- }
151
- } else {
152
- let first = Buffer.alloc(0);
153
- for (let offset = 0; offset < snapshot.size && first.length <= RECORD_BYTES;) {
85
+ input.pipe(decoder);
86
+ }
87
+ const reader = decoder ?? input;
88
+ const timer = setTimeout(() => reader.destroy(/* @__PURE__ */ new Error("Codex rollout metadata observation timed out")), Math.max(1, deadline - Date.now()));
89
+ let metadata;
90
+ const chunks = [];
91
+ let total = 0;
92
+ try {
93
+ for await (const chunk of reader) {
154
94
  check();
155
- const bytes = await readExtent(opened.handle, offset, Math.min(CHUNK_BYTES, snapshot.size - offset));
156
- offset += bytes.length;
157
- first = Buffer.concat([first, bytes]);
158
- const newline = first.indexOf(10);
95
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
96
+ const newline = bytes.indexOf(10);
97
+ const prefix = newline < 0 ? bytes : bytes.subarray(0, newline);
98
+ total += prefix.length;
99
+ if (total > META_BYTES) throw new Error("Codex rollout metadata exceeds the observation limit");
100
+ chunks.push(prefix);
159
101
  if (newline >= 0) {
160
- header(record(first.subarray(0, newline)));
102
+ metadata = parseMetadata(Buffer.concat(chunks), params.threadId);
103
+ if (!unchanged(await opened.handle.stat())) throw new Error("Codex rollout changed during metadata observation");
161
104
  break;
162
105
  }
163
106
  }
164
- if (!metadata) throw new Error("Codex rollout metadata is incomplete or oversized");
165
- let end = snapshot.size;
166
- let scanned = 0;
167
- let tail = Buffer.alloc(0);
168
- while (end > 0 && (!model || !provider)) {
169
- check();
170
- const length = Math.min(CHUNK_BYTES, end, SCAN_BYTES - scanned);
171
- if (!length) throw new Error("Codex rollout model observation exhausted its scan budget");
172
- end -= length;
173
- const bytes = await readExtent(opened.handle, end, length);
174
- if (!scanned) {
175
- if (bytes.at(-1) !== 10) throw new Error("Codex rollout has an incomplete trailing record");
176
- tail = bytes.subarray(0, -1);
177
- } else tail = Buffer.concat([bytes, tail]);
178
- scanned += length;
179
- for (;;) {
180
- const newline = tail.lastIndexOf(10);
181
- if (newline < 0 && (end !== 0 || tail.length === 0)) break;
182
- const value = observation(record(tail.subarray(newline + 1)), params.threadId);
183
- model ??= value.model;
184
- provider ??= value.provider;
185
- tail = newline < 0 ? Buffer.alloc(0) : tail.subarray(0, newline);
186
- if (model && provider) break;
187
- }
188
- if (tail.length > RECORD_BYTES) throw new Error("Codex rollout record exceeds the observation limit");
189
- }
107
+ } finally {
108
+ clearTimeout(timer);
109
+ reader.destroy();
110
+ input.destroy();
190
111
  }
112
+ if (!metadata) throw new Error("Codex rollout metadata is incomplete");
191
113
  const assertUnchanged = async () => {
192
114
  params.assertCurrent();
193
115
  if (selected !== plain) {
@@ -197,7 +119,7 @@ async function readCodexRolloutSelection(params) {
197
119
  if (!isRecord(error) || error.code !== "ENOENT") throw error;
198
120
  return await verifySelected();
199
121
  }
200
- throw new Error("Codex rollout selection changed during model observation");
122
+ throw new Error("Codex rollout selection changed during metadata observation");
201
123
  }
202
124
  await verifySelected();
203
125
  };
@@ -207,20 +129,15 @@ async function readCodexRolloutSelection(params) {
207
129
  const fresh = await safeRoot.open(path.relative(params.sessionsRoot, selected));
208
130
  try {
209
131
  const stat = fresh.stat;
210
- if (stat.dev !== snapshot.dev || stat.ino !== snapshot.ino || stat.size !== snapshot.size || stat.mtimeMs !== snapshot.mtimeMs || stat.ctimeMs !== snapshot.ctimeMs || stat.nlink !== 1 || currentRoot.isSymbolicLink() || currentRoot.ino !== rootStat.ino || currentRoot.dev !== rootStat.dev) throw new Error("Codex rollout changed during model observation");
132
+ if (!unchanged(stat) || currentRoot.isSymbolicLink() || currentRoot.ino !== rootStat.ino || currentRoot.dev !== rootStat.dev) throw new Error("Codex rollout changed during metadata observation");
211
133
  } finally {
212
134
  await fresh.handle.close();
213
135
  }
214
136
  params.assertCurrent();
215
137
  };
216
- const descriptor = await opened.handle.stat();
217
- if (descriptor.dev !== snapshot.dev || descriptor.ino !== snapshot.ino || descriptor.size !== snapshot.size || descriptor.mtimeMs !== snapshot.mtimeMs || descriptor.ctimeMs !== snapshot.ctimeMs || descriptor.nlink !== 1) throw new Error("Codex rollout changed during model observation");
218
138
  await assertUnchanged();
219
139
  check();
220
- if (!model || !provider || !metadata) throw new Error("Codex rollout has no complete durable model selection");
221
140
  return {
222
- model,
223
- modelProvider: provider,
224
141
  metadata,
225
142
  assertUnchanged
226
143
  };
@@ -552,7 +469,7 @@ async function resolveCodexUpstreamForkBoundary(params) {
552
469
  if (index < 0 || !isDeepStrictEqual(current.slice(0, index + 1), frozen)) throw new Error("The local Codex fork prefix changed during initialization");
553
470
  const currentThread = await params.control.readThread(threadId, false);
554
471
  assertCodexThreadAcceptsDirectInput(currentThread);
555
- if (currentThread.id !== thread.id || currentThread.path !== thread.path || currentThread.cwd !== thread.cwd || currentThread.historyMode !== thread.historyMode || currentThread.status?.type === "active") throw new Error("The canonical Codex source changed during initialization");
472
+ if (currentThread.id !== thread.id || currentThread.path !== thread.path || currentThread.cwd !== thread.cwd || currentThread.historyMode !== thread.historyMode || currentThread.model !== thread.model || currentThread.modelProvider !== thread.modelProvider || currentThread.status?.type === "active") throw new Error("The canonical Codex source changed during initialization");
556
473
  const currentTurns = await listCodexUpstreamTurns(params.control, threadId);
557
474
  const cut = turns.findIndex((turn) => turn.id === resolved.boundary.beforeTurnId);
558
475
  if (!isDeepStrictEqual(currentTurns.slice(0, cut + 1), turns.slice(0, cut + 1))) throw new Error("The canonical Codex fork boundary changed during initialization");
@@ -579,12 +496,15 @@ async function forkCanonicalCodexSession(params) {
579
496
  const { fork, resolved, control, bindingStore, sourceBinding, config } = params;
580
497
  const context = control.forkContext;
581
498
  if (!context?.localSessionsRoot || !resolved.canonical.thread.path) throw new Error("Canonical Codex forks require the verified local rollout on its selected connection. Fork an original imported message instead.");
499
+ const model = normalizeOptionalString(resolved.canonical.thread.model);
500
+ const modelProvider = normalizeOptionalString(resolved.canonical.thread.modelProvider);
501
+ if (!model || !modelProvider) throw new Error("Codex did not report the canonical thread's model selection. Use Codex 0.153.0 or newer, or fork an original imported message instead.");
582
502
  const sourceIdentity = sessionBindingIdentity({
583
503
  ...fork.source,
584
504
  config
585
505
  });
586
506
  return bindingStore.withLease(sourceIdentity, async () => {
587
- if (!isDeepStrictEqual(await bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex canonical source binding changed before initialization");
507
+ if (!isDeepStrictEqual(bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex canonical source binding changed before initialization");
588
508
  let freshThreadId;
589
509
  let ownership;
590
510
  let subscriptionReleased = false;
@@ -641,7 +561,7 @@ async function forkCanonicalCodexSession(params) {
641
561
  initialization.assertCurrent();
642
562
  if (ownership && !subscriptionReleased) ownership.assertCurrent();
643
563
  };
644
- const selection = await readCodexRolloutSelection({
564
+ const snapshot = await readCodexRolloutSnapshot({
645
565
  sessionsRoot: context.localSessionsRoot,
646
566
  rolloutPath: resolved.canonical.thread.path,
647
567
  threadId: sourceBinding.threadId,
@@ -649,23 +569,23 @@ async function forkCanonicalCodexSession(params) {
649
569
  });
650
570
  assertCurrent();
651
571
  if (!sourceBinding.dynamicToolsFingerprint) throw new Error("The canonical source has no verified native catalog binding");
652
- const sourceCatalog = parseCodexNativeToolCatalog(selection.metadata, sourceBinding.threadId, sourceBinding.dynamicToolsFingerprint);
572
+ const sourceCatalog = parseCodexNativeToolCatalog(snapshot.metadata, sourceBinding.threadId, sourceBinding.dynamicToolsFingerprint);
653
573
  const prepared = await prepareCanonicalCodexFork({
654
574
  created,
655
575
  initialization: host,
656
576
  config,
657
577
  context,
658
- model: selection.model,
659
- modelProvider: selection.modelProvider,
578
+ model,
579
+ modelProvider,
660
580
  sandbox: fork.sandbox,
661
581
  dynamicTools: sourceCatalog
662
582
  });
663
583
  assertCurrent();
664
- await selection.assertUnchanged();
584
+ await snapshot.assertUnchanged();
665
585
  assertCurrent();
666
586
  await resolved.canonical.assertUnchanged();
667
587
  assertCurrent();
668
- if (!isDeepStrictEqual(await bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex canonical source binding changed during preparation");
588
+ if (!isDeepStrictEqual(bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex canonical source binding changed during preparation");
669
589
  assertCurrent();
670
590
  let raw;
671
591
  try {
@@ -673,8 +593,8 @@ async function forkCanonicalCodexSession(params) {
673
593
  ...prepared.request,
674
594
  threadId: sourceBinding.threadId,
675
595
  beforeTurnId: resolved.boundary.beforeTurnId,
676
- model: selection.model,
677
- modelProvider: selection.modelProvider,
596
+ model,
597
+ modelProvider,
678
598
  threadSource: "appServer",
679
599
  excludeTurns: true
680
600
  }, assertCurrent);
@@ -700,19 +620,19 @@ async function forkCanonicalCodexSession(params) {
700
620
  throw new Error("Codex fork subscription ownership could not be acquired");
701
621
  }
702
622
  assertCurrent();
703
- if (response.model !== selection.model || response.modelProvider !== selection.modelProvider || response.thread.modelProvider !== selection.modelProvider) throw new Error("Codex fork did not preserve the exact canonical source and selected native model");
623
+ if (response.model !== model || response.thread.model !== model || response.modelProvider !== modelProvider || response.thread.modelProvider !== modelProvider) throw new Error("Codex fork did not preserve the exact canonical source and selected native model");
704
624
  const turns = await listCodexUpstreamTurns(control, freshThreadId);
705
625
  assertCurrent();
706
626
  const cut = resolved.canonical.turns.findIndex((turn) => turn.id === resolved.boundary.beforeTurnId);
707
627
  if (cut < 0 || !isDeepStrictEqual(turns, resolved.canonical.turns.slice(0, cut))) throw new Error("Codex did not apply the exact beforeTurnId cut. Reconnect to a compatible server and retry.");
708
628
  const metadata = response.thread.path ? await readCodexSessionMeta(context.localSessionsRoot, response.thread.path, freshThreadId) : void 0;
709
629
  assertCurrent();
710
- if (!metadata || metadata.model_provider !== selection.modelProvider) throw new Error("The fresh Codex fork metadata could not be verified");
630
+ if (!metadata || metadata.model_provider !== modelProvider) throw new Error("The fresh Codex fork metadata could not be verified");
711
631
  const childCatalog = parseCodexNativeToolCatalog(metadata, freshThreadId);
712
632
  if (!isDeepStrictEqual(sourceCatalog, childCatalog)) throw new Error("Codex fork did not preserve the actual native tool catalog");
713
- await selection.assertUnchanged();
633
+ await snapshot.assertUnchanged();
714
634
  assertCurrent();
715
- await attestCodexPluginThreadApps({
635
+ await checkCodexThreadAppAvailability({
716
636
  client: context.client,
717
637
  threadId: freshThreadId,
718
638
  appIds: prepared.provisionalAppIds
@@ -769,8 +689,8 @@ async function forkCanonicalCodexSession(params) {
769
689
  conversationSourceTransferComplete: true,
770
690
  cwd: prepared.request.cwd ?? "",
771
691
  rolloutPath: response.thread.path ?? void 0,
772
- model: selection.model,
773
- modelProvider: selection.modelProvider,
692
+ model,
693
+ modelProvider,
774
694
  appServerRuntimeFingerprint: control.connectionFingerprint,
775
695
  dynamicToolsFingerprint: codexDynamicToolsFingerprint(childCatalog),
776
696
  dynamicToolsContainDeferred: flattenCodexDynamicToolFunctions(childCatalog).some((tool) => tool.deferLoading === true),
@@ -783,7 +703,7 @@ async function forkCanonicalCodexSession(params) {
783
703
  initialization.assertCurrent();
784
704
  await resolved.canonical.assertUnchanged();
785
705
  initialization.assertCurrent();
786
- if (!isDeepStrictEqual(await bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex source binding changed before fork readiness");
706
+ if (!isDeepStrictEqual(bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex source binding changed before fork readiness");
787
707
  initialization.assertCurrent();
788
708
  return { pluginExtensions: created.entry.pluginExtensions };
789
709
  }
@@ -810,7 +730,7 @@ async function forkCodexUpstreamSession(params, options) {
810
730
  message: "This Codex thread is not available on the current connection. Reconnect to its host and try again."
811
731
  };
812
732
  return await requestControl.withPinnedConnection(async (control) => {
813
- const sourceBinding = await options.bindingStore.read(sessionBindingIdentity({
733
+ const sourceBinding = options.bindingStore.read(sessionBindingIdentity({
814
734
  ...params.source,
815
735
  config: options.resolveConfig?.()
816
736
  }));
@@ -1,6 +1,6 @@
1
- import { i as resolveCodexAppServerRuntimeOptions } from "./config-BhmfC1s6.js";
2
- import { n as readCodexAppServerUsage } from "./request-DYAI5FQE.js";
3
- import { t as buildCodexAppServerUsageSnapshot } from "./rate-limits-CawQJfUS.js";
1
+ import { i as resolveCodexAppServerRuntimeOptions } from "./config-CyapYSji.js";
2
+ import { n as readCodexAppServerUsage } from "./request-C8H22rPi.js";
3
+ import { t as buildCodexAppServerUsageSnapshot } from "./rate-limits-Fx_l4eNa.js";
4
4
  import { CODEX_APP_SERVER_AUTH_MARKER } from "openclaw/plugin-sdk/agent-runtime";
5
5
  //#region extensions/codex/src/app-server/usage.ts
6
6
  /** Handles the synthetic usage credential for a Codex-backed OpenAI route. */
@@ -1,6 +1,6 @@
1
- import { $t as isJsonObject } from "./shared-client-DxcfF9KX.js";
2
- import { x as buildCodexNativeWebSearchThreadConfig } from "./thread-lifecycle-DAcEJ_Om.js";
3
- import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-wzJrwKKe.js";
1
+ import { B as isJsonObject } from "./config-CyapYSji.js";
2
+ import { x as buildCodexNativeWebSearchThreadConfig } from "./thread-lifecycle-DPK30jad.js";
3
+ import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-DxGJRYbY.js";
4
4
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { readStringParam, resolveSearchTimeoutSeconds, wrapWebContent } from "openclaw/plugin-sdk/provider-web-search";
6
6
  //#region extensions/codex/src/web-search-provider.runtime.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/codex",
3
- "version": "2026.9.1",
3
+ "version": "2026.9.2",
4
4
  "description": "OpenClaw Codex app-server harness and native session supervision plugin.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,10 +8,10 @@
8
8
  },
9
9
  "type": "module",
10
10
  "dependencies": {
11
- "@openai/codex": "0.152.1",
11
+ "@openai/codex": "0.153.4",
12
12
  "semver": "7.8.5",
13
13
  "smol-toml": "1.8.0",
14
- "typebox": "1.3.17",
14
+ "typebox": "1.3.18",
15
15
  "ws": "8.21.3",
16
16
  "zod": "4.4.3"
17
17
  },
@@ -36,10 +36,10 @@
36
36
  ]
37
37
  },
38
38
  "compat": {
39
- "pluginApi": ">=2026.9.1"
39
+ "pluginApi": ">=2026.9.2"
40
40
  },
41
41
  "build": {
42
- "openclawVersion": "2026.9.1"
42
+ "openclawVersion": "2026.9.2"
43
43
  },
44
44
  "release": {
45
45
  "publishToClawHub": true,
@@ -59,7 +59,7 @@
59
59
  "README.md"
60
60
  ],
61
61
  "peerDependencies": {
62
- "openclaw": ">=2026.9.1"
62
+ "openclaw": ">=2026.9.2"
63
63
  },
64
64
  "peerDependenciesMeta": {
65
65
  "openclaw": {
@@ -1,45 +0,0 @@
1
- import { E as readCodexPluginConfig, i as resolveCodexAppServerRuntimeOptions, s as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-BhmfC1s6.js";
2
- import { n as buildCodexAppServerConnectionFingerprint, o as resolveCodexCatalogConnectionHome } from "./thread-resume-C7pyVKeW.js";
3
- //#region extensions/codex/src/app-server/binding-connection.ts
4
- /** Requires the native model pair after a supervised pending branch has materialized. */
5
- function requireCodexSupervisionModelSelection(binding) {
6
- const model = binding.model?.trim();
7
- const modelProvider = binding.modelProvider?.trim();
8
- if (binding.connectionScope !== "supervision" || !model || !modelProvider) throw new Error("Codex supervised binding is missing its native model and provider; refusing request selection");
9
- return {
10
- model,
11
- modelProvider
12
- };
13
- }
14
- /** Resolves connection and auth ownership exclusively from the private thread binding. */
15
- function resolveCodexBindingAppServerConnection(params) {
16
- const { binding, authProfileId, ...runtimeParams } = params;
17
- const usesSupervisionConnection = binding?.connectionScope === "supervision";
18
- if (usesSupervisionConnection && readCodexPluginConfig(runtimeParams.pluginConfig).supervision?.enabled !== true) throw new Error("Codex supervision is disabled; refusing to open a native user-home supervised session");
19
- let appServer = (usesSupervisionConnection ? resolveCodexSupervisionAppServerRuntimeOptions : resolveCodexAppServerRuntimeOptions)(runtimeParams);
20
- if (usesSupervisionConnection) {
21
- const persistedFingerprint = binding.pendingSupervisionBranch?.connectionFingerprint ?? binding.appServerRuntimeFingerprint;
22
- const catalogHome = persistedFingerprint ? resolveCodexCatalogConnectionHome(persistedFingerprint, runtimeParams.agentDir) : void 0;
23
- if (catalogHome) appServer = {
24
- ...appServer,
25
- start: {
26
- ...appServer.start,
27
- homeScope: "user",
28
- env: {
29
- ...appServer.start.env,
30
- CODEX_HOME: catalogHome
31
- }
32
- }
33
- };
34
- const currentFingerprint = buildCodexAppServerConnectionFingerprint(appServer, runtimeParams.agentDir);
35
- if (!persistedFingerprint || persistedFingerprint !== currentFingerprint) throw new Error("Codex supervision connection changed; refusing to operate on its bound native thread");
36
- }
37
- return {
38
- appServer,
39
- usesSupervisionConnection,
40
- requestAuthProfileId: usesSupervisionConnection ? void 0 : authProfileId,
41
- clientAuthProfileId: usesSupervisionConnection ? null : authProfileId
42
- };
43
- }
44
- //#endregion
45
- export { resolveCodexBindingAppServerConnection as n, requireCodexSupervisionModelSelection as t };
@@ -1,90 +0,0 @@
1
- //#region extensions/codex/src/app-server/launch-args.ts
2
- const CODEX_VALUE_OPTIONS = /* @__PURE__ */ new Set([
3
- "-m",
4
- "--model",
5
- "--local-provider",
6
- "-p",
7
- "--profile",
8
- "-s",
9
- "--sandbox",
10
- "-a",
11
- "--ask-for-approval",
12
- "-C",
13
- "--cd",
14
- "--add-dir",
15
- "--remote",
16
- "--remote-auth-token-env",
17
- "-c",
18
- "--config",
19
- "--enable",
20
- "--disable",
21
- "--listen",
22
- "--code-mode-host",
23
- "--ws-auth",
24
- "--ws-token-file",
25
- "--ws-token-sha256",
26
- "--ws-shared-secret-file",
27
- "--ws-issuer",
28
- "--ws-audience",
29
- "--ws-max-clock-skew-seconds"
30
- ]);
31
- /** One tokenization owner for launch, turn policy, reviewer trust, and private turns. */
32
- function readCodexArgs(args) {
33
- const tokens = [];
34
- let nativeSubcommand = false;
35
- let end = 0;
36
- for (const [index, arg] of args.entries()) {
37
- if (index < end) continue;
38
- end = index + 1;
39
- const attached = /^(--[^=]+)=([\s\S]*)$/u.exec(arg) ?? /^(-[cmpisaC])=?([\s\S]+)$/u.exec(arg);
40
- const name = attached?.[1] ?? arg;
41
- let value = attached?.[2];
42
- if (name === "-i" || name === "--image") while (args[end]?.startsWith("-") === false) end += 1;
43
- else if (!attached && CODEX_VALUE_OPTIONS.has(name)) {
44
- value = args[end];
45
- if (value !== void 0) end += 1;
46
- }
47
- tokens.push({
48
- index,
49
- end,
50
- name,
51
- value
52
- });
53
- if (name === "app-server") nativeSubcommand = true;
54
- if (name === "--" && nativeSubcommand) break;
55
- }
56
- return tokens;
57
- }
58
- function readCodexAppServerConfigOptions(args) {
59
- return readCodexArgs(args).filter(({ name }) => name === "-c" || name === "--config" || name === "-p" || name === "--profile");
60
- }
61
- /** The stdio proxy forwards to an external server; it does not own that runtime. */
62
- function isCodexAppServerProxyLaunch(args) {
63
- const tokens = readCodexArgs(args);
64
- const server = tokens.findLastIndex(({ name }) => name === "app-server");
65
- return server >= 0 && tokens.slice(server + 1).find(({ name }) => !name.startsWith("-"))?.name === "proxy";
66
- }
67
- /** Keeps Codex overrides in one CLI scope without rewriting raw TOML or wrapper prefixes. */
68
- function normalizeCodexAppServerArgs(rawArgs, enforcedOverride) {
69
- const tokens = readCodexArgs(rawArgs);
70
- const subcommandIndex = tokens.findLast(({ name }) => name === "app-server")?.index ?? -1;
71
- const prefix = subcommandIndex < 0 ? [...rawArgs] : rawArgs.slice(0, subcommandIndex);
72
- const suffix = [];
73
- if (subcommandIndex >= 0) for (const token of tokens) {
74
- if (token.index <= subcommandIndex) continue;
75
- if (token.name === "--") {
76
- suffix.push(...rawArgs.slice(token.index));
77
- break;
78
- }
79
- (token.name === "-c" || token.name === "--config" ? prefix : suffix).push(...rawArgs.slice(token.index, token.end));
80
- }
81
- if (enforcedOverride && !(prefix.at(-2) === "-c" && prefix.at(-1) === enforcedOverride)) prefix.push("-c", enforcedOverride);
82
- const normalized = subcommandIndex < 0 ? prefix : [
83
- ...prefix,
84
- "app-server",
85
- ...suffix
86
- ];
87
- return normalized.length === rawArgs.length && normalized.every((arg, index) => arg === rawArgs[index]) ? rawArgs : normalized;
88
- }
89
- //#endregion
90
- export { normalizeCodexAppServerArgs as n, readCodexAppServerConfigOptions as r, isCodexAppServerProxyLaunch as t };