@openclaw/codex 2026.9.1 → 2026.9.3

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 (109) hide show
  1. package/README.md +2 -0
  2. package/dist/api.js +18 -23
  3. package/dist/apply-B6el6hdO.js +357 -0
  4. package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-D6cR54TV.js} +113 -49
  5. package/dist/{attempt-context-DmQUNWwT.js → attempt-context-AO4DSjE0.js} +11 -9
  6. package/dist/{event-projector-usage-C5mcrGjp.js → attempt-notifications--H8zXR5-.js} +3 -89
  7. package/dist/auth-cache-key-Kq6oerr6.js +498 -0
  8. package/dist/auth-profile-CwzO4_RG.js +43 -0
  9. package/dist/auth-profile-selection-DFu9e167.js +45 -0
  10. package/dist/{binding-connection-E6uDsPlx.js → binding-connection-QqgcPCgk.js} +18 -3
  11. package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-lRpmZHFv.js} +54 -150
  12. package/dist/build-state-6RL6qohz.js +19 -0
  13. package/dist/{capabilities-dIjNVCYH.js → capabilities-BeqLPbtM.js} +2 -1
  14. package/dist/cli-metadata.js +1 -1
  15. package/dist/client-BEKu4yDx.js +3983 -0
  16. package/dist/command-dispatch-CisT9Jqq.js +21 -0
  17. package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DeTfrapr.js} +2 -2
  18. package/dist/{command-handlers-CTGb2csu.js → command-handlers-BfIsJEuA.js} +158 -76
  19. package/dist/command-rpc-BMqRQOFX.js +226 -0
  20. package/dist/{compact-_t0HQrUS.js → compact-CGJZ2rlb.js} +89 -49
  21. package/dist/config-JDfTI4VI.js +106 -0
  22. package/dist/{config-BhmfC1s6.js → config-options-jnIFvwxD.js} +208 -654
  23. package/dist/config-runtime-BWf6JLWG.js +11 -0
  24. package/dist/config-utils-C57JiJrU.js +69 -0
  25. package/dist/conversation-binding-CxOlHiix.js +889 -0
  26. package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → conversation-control-CUCrSIQI.js} +36 -155
  27. package/dist/doctor-contract-api.js +8 -9
  28. package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-D-JBoaLt.js} +734 -698
  29. package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-J_5Ep5Um.js} +4 -3
  30. package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
  31. package/dist/ephemeral-turn-DSwzP8YY.js +101 -0
  32. package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-BmBM4qBV.js} +23 -27
  33. package/dist/event-projector-usage-CIyrYYid.js +102 -0
  34. package/dist/{harness-DXVZ5II5.js → harness-FR6eQgyO.js} +47 -17
  35. package/dist/harness.js +1 -1
  36. package/dist/history-rejection-B4nOXNXF.js +13 -0
  37. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  38. package/dist/incognito-session-uhrBF6wJ.js +15 -0
  39. package/dist/index.js +413 -2893
  40. package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-DHBefrzg.js} +12 -21
  41. package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DrjjRRUD.js} +17 -84
  42. package/dist/managed-thread-store-D1t5jh3G.js +66 -0
  43. package/dist/media-understanding-provider.js +4 -1
  44. package/dist/{model-catalog-CUM68Hkl.js → model-catalog-B_6M04Wo.js} +6 -5
  45. package/dist/{models-sYnEc0gd.js → models-P9k2qAof.js} +4 -4
  46. package/dist/native-execution-policy-umd0tgh4.js +128 -0
  47. package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-BbCUKRwC.js} +76 -48
  48. package/dist/node-cli-sessions-rj0ysJwM.js +527 -0
  49. package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-BY_ctYnT.js} +54 -23
  50. package/dist/plan-BMJdMOEF.js +711 -0
  51. package/dist/plugin-activation-BQK-f5sV.js +133 -0
  52. package/dist/{thread-resume-C7pyVKeW.js → plugin-app-cache-key-CdSQzWyX.js} +5 -53
  53. package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-DeW95wB5.js} +1 -1
  54. package/dist/plugin-inventory-CoRCzWW4.js +325 -0
  55. package/dist/plugin-marketplace-discovery-3akBizzF.js +134 -0
  56. package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-DgNfRAGA.js} +13 -9
  57. package/dist/protocol-CAAcVIKF.js +275 -0
  58. package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-W4tfK5Y5.js} +2 -2
  59. package/dist/{rate-limits-CawQJfUS.js → rate-limits-Bqnx1N4z.js} +1 -1
  60. package/dist/request-CGvGOpeR.js +198 -0
  61. package/dist/{run-attempt-D1hJO4fX.js → run-attempt-DwKds3DN.js} +1498 -1028
  62. package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-T-NwqeSH.js} +28 -28
  63. package/dist/sandbox-guard-BcT66fWy.js +165 -0
  64. package/dist/{session-binding-BHuTCRZQ.js → session-binding-CKSepwIC.js} +118 -324
  65. package/dist/session-binding-record-CaZjYwNS.js +256 -0
  66. package/dist/session-catalog-HaDcp7Sv.js +1533 -0
  67. package/dist/session-catalog-adoption-BKLtSrwi.js +251 -0
  68. package/dist/session-catalog-archive-D0i2pGj2.js +56 -0
  69. package/dist/session-catalog-home-id-D7-aLiNt.js +190 -0
  70. package/dist/session-catalog-node-adoption-BUuDYY8R.js +182 -0
  71. package/dist/session-catalog-node-continue-CBtc4wkI.js +238 -0
  72. package/dist/session-catalog-parsing-CdD3JhdM.js +280 -0
  73. package/dist/session-catalog-provenance-DkJHo735.js +124 -0
  74. package/dist/{session-cli-CmFEXMAM.js → session-cli-CbgaHh0f.js} +3 -2
  75. package/dist/session-history-Cz-tOOYj.js +96 -0
  76. package/dist/{session-upstream-marker-C351-5Qw.js → session-history-import-DFN7sWRU.js} +5 -49
  77. package/dist/session-history-read-cxPUxyVV.js +50 -0
  78. package/dist/session-history-worker-runtime.js +60 -0
  79. package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-CNEvGaU5.js} +75 -69
  80. package/dist/session-history.worker.js +2 -0
  81. package/dist/{session-initialization-BeWzjGiR.js → session-initialization-Jo86C60I.js} +2 -1
  82. package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-B22InTp_.js} +4 -7
  83. package/dist/{session-retirement-BujDjXVF.js → session-retirement-BSNG_mhf.js} +8 -7
  84. package/dist/session-upstream-marker-D15C9NHp.js +46 -0
  85. package/dist/settled-turn-context-Du6gdUDd.js +45 -0
  86. package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BuLUrZl2.js} +54 -42
  87. package/dist/shared-client-CVhez2Uo.js +2911 -0
  88. package/dist/{side-question-BTZAII4l.js → side-question-DLbr2vUU.js} +135 -191
  89. package/dist/source-Da-h6f7e.js +518 -0
  90. package/dist/thread-archive-guard-D1bP04Tf.js +53 -0
  91. package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-D1pzRwHB.js} +467 -977
  92. package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-D6oASVRu.js} +15 -17
  93. package/dist/{thread-policy-g4KbJPzp.js → thread-policy-D8kI7yAO.js} +2 -2
  94. package/dist/thread-resume-T5cveyxA.js +52 -0
  95. package/dist/timeout-BVw8aaM1.js +33 -0
  96. package/dist/transcript-mirror-attestation-DibE0krH.js +89 -0
  97. package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-t5TOccct.js} +111 -379
  98. package/dist/{transport-stdio-CyPldczm.js → transport-stdio-BGjHoYLr.js} +80 -48
  99. package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-De-sLJ2r.js} +94 -166
  100. package/dist/{usage-Bj-rrzkR.js → usage-CPPTmBvZ.js} +4 -3
  101. package/dist/version-omm6IPI3.js +12 -0
  102. package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-CSVgQL0w.js} +3 -3
  103. package/openclaw.plugin.json +22 -1
  104. package/package.json +6 -6
  105. package/dist/request-DYAI5FQE.js +0 -475
  106. package/dist/session-catalog-yyvTWFOw.js +0 -3120
  107. package/dist/session-history-C5J1AKzG.js +0 -87
  108. package/dist/shared-client-DxcfF9KX.js +0 -7494
  109. package/dist/{auth-binding-Ds_QVm-X.js → auth-binding-Co2Vfcf_.js} +1 -1
@@ -1,83 +1,58 @@
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-CaZjYwNS.js";
2
+ import { f as assertCodexModelBackedReviewerEffectiveConfig } from "./config-options-jnIFvwxD.js";
3
+ import { a as flattenCodexDynamicToolFunctions, o as isJsonObject, x as readCodexPluginConfig } from "./protocol-CAAcVIKF.js";
4
+ import { _ as assertCodexThreadAcceptsDirectInput, v as assertCodexThreadForkResponse } from "./client-BEKu4yDx.js";
5
+ import { n as withCodexAppServerThreadMutation } from "./incognito-session-uhrBF6wJ.js";
6
+ import { n as readCodexSessionMeta } from "./session-catalog-provenance-DkJHo735.js";
10
7
  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";
8
+ import { a as projectCodexUserItemText } from "./session-catalog-home-id-D7-aLiNt.js";
9
+ import { n as codexUpstreamBaseline, t as codexLastTerminalTurnId } from "./session-upstream-marker-D15C9NHp.js";
10
+ import { r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-CdSQzWyX.js";
11
+ import { t as CodexAppServerScopedRequestRejectedError } from "./request-CGvGOpeR.js";
12
+ import { n as resolveOpenClawExecPolicyForCodexAppServer } from "./config-JDfTI4VI.js";
13
+ import { r as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-runtime-BWf6JLWG.js";
14
+ import { a as fingerprintCodexMirrorSourceMessage, c as readCodexMirrorSourceFingerprint } from "./transcript-mirror-attestation-DibE0krH.js";
15
+ import { L as hasCodexAppServerLiveThread, N as claimCodexAppServerLiveThread, f as readCodexAppServerClientDesktopGenerationFingerprint } from "./shared-client-CVhez2Uo.js";
16
+ import { C as buildDeveloperInstructions, Dt as shouldBuildCodexPluginThreadConfig, F as assertCodexNativeHookRelayAllowed, I as buildCodexNativeHookRelayConfig, J as parseCodexNativeToolCatalog, Q as codexDynamicToolsFingerprint, R as buildCodexNativeHookRelayId, S as resolveCodexWebSearchPlan, Tt as mergeCodexThreadConfigs, V as resolveCodexNativeHookRelayEvents, W as checkCodexThreadAppAvailability, X as resolveCodexNativeSkillIsolation, Y as applyCodexNativeSkillIsolation, et as fingerprintJsonObject, tt as fingerprintUserMcpServersConfigPatch, xt as buildCodexPluginThreadConfig, y as buildCodexThreadConfiguration } from "./thread-lifecycle-D1pzRwHB.js";
17
+ import "./session-binding-CKSepwIC.js";
18
+ import { i as refreshCodexThreadPolicy, n as CodexThreadPolicyHandoffError } from "./thread-policy-D8kI7yAO.js";
19
+ import "./thread-ownership-D6oASVRu.js";
20
+ import { n as resolveCodexNativeExecutionPolicy } from "./native-execution-policy-umd0tgh4.js";
21
+ import { l as isCodexDynamicToolExcluded, n as resolveCodexProviderWebSearchSupportForClient } from "./provider-capabilities-W4tfK5Y5.js";
22
+ import { o as prepareCodexWorkspaceDeveloperInstructions } from "./attempt-context-AO4DSjE0.js";
23
+ import { n as prepareCodexSessionInitialization } from "./session-initialization-Jo86C60I.js";
24
+ import { createImportedCodexSession } from "./session-history-import-DFN7sWRU.js";
15
25
  import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
16
- import { lstat } from "node:fs/promises";
26
+ import { randomUUID } from "node:crypto";
17
27
  import path from "node:path";
18
- import { loadCodexBundleMcpThreadConfig } from "openclaw/plugin-sdk/agent-harness-runtime";
28
+ import { lstat } from "node:fs/promises";
19
29
  import { constants, createZstdDecompress } from "node:zlib";
20
30
  import { root } from "openclaw/plugin-sdk/file-access-runtime";
21
- import { randomUUID } from "node:crypto";
22
31
  import { isDeepStrictEqual } from "node:util";
23
32
  import { resolveAgentWorkspaceDir } from "openclaw/plugin-sdk/agent-runtime";
33
+ import { loadCodexBundleMcpThreadConfig } from "openclaw/plugin-sdk/agent-harness-runtime";
24
34
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
25
35
  import { resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
26
36
  import { buildCodexUserMcpServersThreadConfigPatchForRuntime, resolveCodexMcpToolOverridesForAgent } from "openclaw/plugin-sdk/codex-mcp-projection";
27
37
  import { buildNativeHookRelayCommandPlan } from "openclaw/plugin-sdk/native-hook-relay-runtime";
28
38
  import { appendSessionTranscriptMessagesByIdentity, readVisibleSessionTranscriptMessageEntries } from "openclaw/plugin-sdk/session-transcript-runtime";
29
- //#region extensions/codex/src/session-rollout-selection.ts
39
+ //#region extensions/codex/src/session-rollout-snapshot.ts
30
40
  const CHUNK_BYTES = 65536;
31
- const RECORD_BYTES = 1048576;
32
- const SCAN_BYTES = 8388608;
33
- const DECOMPRESSED_BYTES = 33554432;
41
+ const META_BYTES = 1048576;
42
+ const COMPRESSED_BYTES = 8388608;
34
43
  const DEADLINE_MS = 5e3;
35
44
  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");
45
+ function parseMetadata(line, threadId) {
42
46
  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
- };
48
- }
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;
47
+ 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");
48
+ return parsed.payload;
74
49
  }
75
- /** Latest durable selection at one verified local rollout snapshot, not live-memory state. */
76
- async function readCodexRolloutSelection(params) {
50
+ /** Read immutable metadata while pinning the entire rollout against concurrent writers. */
51
+ async function readCodexRolloutSnapshot(params) {
77
52
  const deadline = Date.now() + DEADLINE_MS;
78
53
  const check = () => {
79
54
  params.assertCurrent();
80
- if (Date.now() >= deadline) throw new Error("Codex rollout model observation timed out");
55
+ if (Date.now() >= deadline) throw new Error("Codex rollout metadata observation timed out");
81
56
  };
82
57
  check();
83
58
  const rootStat = await lstat(params.sessionsRoot);
@@ -100,94 +75,49 @@ async function readCodexRolloutSelection(params) {
100
75
  try {
101
76
  check();
102
77
  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()));
78
+ 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;
79
+ if (!snapshot.size) throw new Error("Codex rollout metadata is incomplete");
80
+ const compressed = selected.endsWith(".zst");
81
+ if (compressed && snapshot.size > COMPRESSED_BYTES) throw new Error("Compressed Codex rollout exceeds the observation limit");
82
+ const input = opened.handle.createReadStream({
83
+ autoClose: false,
84
+ highWaterMark: CHUNK_BYTES,
85
+ end: snapshot.size - 1
86
+ });
87
+ const decoder = compressed ? createZstdDecompress({
88
+ chunkSize: CHUNK_BYTES,
89
+ params: { [constants.ZSTD_d_windowLogMax]: 25 }
90
+ }) : void 0;
91
+ if (decoder) {
123
92
  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;) {
93
+ input.pipe(decoder);
94
+ }
95
+ const reader = decoder ?? input;
96
+ const timer = setTimeout(() => reader.destroy(/* @__PURE__ */ new Error("Codex rollout metadata observation timed out")), Math.max(1, deadline - Date.now()));
97
+ let metadata;
98
+ const chunks = [];
99
+ let total = 0;
100
+ try {
101
+ for await (const chunk of reader) {
154
102
  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);
103
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
104
+ const newline = bytes.indexOf(10);
105
+ const prefix = newline < 0 ? bytes : bytes.subarray(0, newline);
106
+ total += prefix.length;
107
+ if (total > META_BYTES) throw new Error("Codex rollout metadata exceeds the observation limit");
108
+ chunks.push(prefix);
159
109
  if (newline >= 0) {
160
- header(record(first.subarray(0, newline)));
110
+ metadata = parseMetadata(Buffer.concat(chunks), params.threadId);
111
+ if (!unchanged(await opened.handle.stat())) throw new Error("Codex rollout changed during metadata observation");
161
112
  break;
162
113
  }
163
114
  }
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
- }
115
+ } finally {
116
+ clearTimeout(timer);
117
+ reader.destroy();
118
+ input.destroy();
190
119
  }
120
+ if (!metadata) throw new Error("Codex rollout metadata is incomplete");
191
121
  const assertUnchanged = async () => {
192
122
  params.assertCurrent();
193
123
  if (selected !== plain) {
@@ -197,7 +127,7 @@ async function readCodexRolloutSelection(params) {
197
127
  if (!isRecord(error) || error.code !== "ENOENT") throw error;
198
128
  return await verifySelected();
199
129
  }
200
- throw new Error("Codex rollout selection changed during model observation");
130
+ throw new Error("Codex rollout selection changed during metadata observation");
201
131
  }
202
132
  await verifySelected();
203
133
  };
@@ -207,20 +137,15 @@ async function readCodexRolloutSelection(params) {
207
137
  const fresh = await safeRoot.open(path.relative(params.sessionsRoot, selected));
208
138
  try {
209
139
  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");
140
+ if (!unchanged(stat) || currentRoot.isSymbolicLink() || currentRoot.ino !== rootStat.ino || currentRoot.dev !== rootStat.dev) throw new Error("Codex rollout changed during metadata observation");
211
141
  } finally {
212
142
  await fresh.handle.close();
213
143
  }
214
144
  params.assertCurrent();
215
145
  };
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
146
  await assertUnchanged();
219
147
  check();
220
- if (!model || !provider || !metadata) throw new Error("Codex rollout has no complete durable model selection");
221
148
  return {
222
- model,
223
- modelProvider: provider,
224
149
  metadata,
225
150
  assertUnchanged
226
151
  };
@@ -552,7 +477,7 @@ async function resolveCodexUpstreamForkBoundary(params) {
552
477
  if (index < 0 || !isDeepStrictEqual(current.slice(0, index + 1), frozen)) throw new Error("The local Codex fork prefix changed during initialization");
553
478
  const currentThread = await params.control.readThread(threadId, false);
554
479
  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");
480
+ 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
481
  const currentTurns = await listCodexUpstreamTurns(params.control, threadId);
557
482
  const cut = turns.findIndex((turn) => turn.id === resolved.boundary.beforeTurnId);
558
483
  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 +504,15 @@ async function forkCanonicalCodexSession(params) {
579
504
  const { fork, resolved, control, bindingStore, sourceBinding, config } = params;
580
505
  const context = control.forkContext;
581
506
  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.");
507
+ const model = normalizeOptionalString(resolved.canonical.thread.model);
508
+ const modelProvider = normalizeOptionalString(resolved.canonical.thread.modelProvider);
509
+ 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
510
  const sourceIdentity = sessionBindingIdentity({
583
511
  ...fork.source,
584
512
  config
585
513
  });
586
514
  return bindingStore.withLease(sourceIdentity, async () => {
587
- if (!isDeepStrictEqual(await bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex canonical source binding changed before initialization");
515
+ if (!isDeepStrictEqual(bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex canonical source binding changed before initialization");
588
516
  let freshThreadId;
589
517
  let ownership;
590
518
  let subscriptionReleased = false;
@@ -641,7 +569,7 @@ async function forkCanonicalCodexSession(params) {
641
569
  initialization.assertCurrent();
642
570
  if (ownership && !subscriptionReleased) ownership.assertCurrent();
643
571
  };
644
- const selection = await readCodexRolloutSelection({
572
+ const snapshot = await readCodexRolloutSnapshot({
645
573
  sessionsRoot: context.localSessionsRoot,
646
574
  rolloutPath: resolved.canonical.thread.path,
647
575
  threadId: sourceBinding.threadId,
@@ -649,23 +577,23 @@ async function forkCanonicalCodexSession(params) {
649
577
  });
650
578
  assertCurrent();
651
579
  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);
580
+ const sourceCatalog = parseCodexNativeToolCatalog(snapshot.metadata, sourceBinding.threadId, sourceBinding.dynamicToolsFingerprint);
653
581
  const prepared = await prepareCanonicalCodexFork({
654
582
  created,
655
583
  initialization: host,
656
584
  config,
657
585
  context,
658
- model: selection.model,
659
- modelProvider: selection.modelProvider,
586
+ model,
587
+ modelProvider,
660
588
  sandbox: fork.sandbox,
661
589
  dynamicTools: sourceCatalog
662
590
  });
663
591
  assertCurrent();
664
- await selection.assertUnchanged();
592
+ await snapshot.assertUnchanged();
665
593
  assertCurrent();
666
594
  await resolved.canonical.assertUnchanged();
667
595
  assertCurrent();
668
- if (!isDeepStrictEqual(await bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex canonical source binding changed during preparation");
596
+ if (!isDeepStrictEqual(bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex canonical source binding changed during preparation");
669
597
  assertCurrent();
670
598
  let raw;
671
599
  try {
@@ -673,8 +601,8 @@ async function forkCanonicalCodexSession(params) {
673
601
  ...prepared.request,
674
602
  threadId: sourceBinding.threadId,
675
603
  beforeTurnId: resolved.boundary.beforeTurnId,
676
- model: selection.model,
677
- modelProvider: selection.modelProvider,
604
+ model,
605
+ modelProvider,
678
606
  threadSource: "appServer",
679
607
  excludeTurns: true
680
608
  }, assertCurrent);
@@ -700,19 +628,19 @@ async function forkCanonicalCodexSession(params) {
700
628
  throw new Error("Codex fork subscription ownership could not be acquired");
701
629
  }
702
630
  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");
631
+ 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
632
  const turns = await listCodexUpstreamTurns(control, freshThreadId);
705
633
  assertCurrent();
706
634
  const cut = resolved.canonical.turns.findIndex((turn) => turn.id === resolved.boundary.beforeTurnId);
707
635
  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
636
  const metadata = response.thread.path ? await readCodexSessionMeta(context.localSessionsRoot, response.thread.path, freshThreadId) : void 0;
709
637
  assertCurrent();
710
- if (!metadata || metadata.model_provider !== selection.modelProvider) throw new Error("The fresh Codex fork metadata could not be verified");
638
+ if (!metadata || metadata.model_provider !== modelProvider) throw new Error("The fresh Codex fork metadata could not be verified");
711
639
  const childCatalog = parseCodexNativeToolCatalog(metadata, freshThreadId);
712
640
  if (!isDeepStrictEqual(sourceCatalog, childCatalog)) throw new Error("Codex fork did not preserve the actual native tool catalog");
713
- await selection.assertUnchanged();
641
+ await snapshot.assertUnchanged();
714
642
  assertCurrent();
715
- await attestCodexPluginThreadApps({
643
+ await checkCodexThreadAppAvailability({
716
644
  client: context.client,
717
645
  threadId: freshThreadId,
718
646
  appIds: prepared.provisionalAppIds
@@ -769,8 +697,8 @@ async function forkCanonicalCodexSession(params) {
769
697
  conversationSourceTransferComplete: true,
770
698
  cwd: prepared.request.cwd ?? "",
771
699
  rolloutPath: response.thread.path ?? void 0,
772
- model: selection.model,
773
- modelProvider: selection.modelProvider,
700
+ model,
701
+ modelProvider,
774
702
  appServerRuntimeFingerprint: control.connectionFingerprint,
775
703
  dynamicToolsFingerprint: codexDynamicToolsFingerprint(childCatalog),
776
704
  dynamicToolsContainDeferred: flattenCodexDynamicToolFunctions(childCatalog).some((tool) => tool.deferLoading === true),
@@ -783,7 +711,7 @@ async function forkCanonicalCodexSession(params) {
783
711
  initialization.assertCurrent();
784
712
  await resolved.canonical.assertUnchanged();
785
713
  initialization.assertCurrent();
786
- if (!isDeepStrictEqual(await bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex source binding changed before fork readiness");
714
+ if (!isDeepStrictEqual(bindingStore.read(sourceIdentity), sourceBinding)) throw new Error("Codex source binding changed before fork readiness");
787
715
  initialization.assertCurrent();
788
716
  return { pluginExtensions: created.entry.pluginExtensions };
789
717
  }
@@ -810,7 +738,7 @@ async function forkCodexUpstreamSession(params, options) {
810
738
  message: "This Codex thread is not available on the current connection. Reconnect to its host and try again."
811
739
  };
812
740
  return await requestControl.withPinnedConnection(async (control) => {
813
- const sourceBinding = await options.bindingStore.read(sessionBindingIdentity({
741
+ const sourceBinding = options.bindingStore.read(sessionBindingIdentity({
814
742
  ...params.source,
815
743
  config: options.resolveConfig?.()
816
744
  }));
@@ -1,6 +1,7 @@
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 { t as buildCodexAppServerUsageSnapshot } from "./rate-limits-Bqnx1N4z.js";
2
+ import { n as readCodexAppServerUsage } from "./request-CGvGOpeR.js";
3
+ import "./config-JDfTI4VI.js";
4
+ import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-BWf6JLWG.js";
4
5
  import { CODEX_APP_SERVER_AUTH_MARKER } from "openclaw/plugin-sdk/agent-runtime";
5
6
  //#region extensions/codex/src/app-server/usage.ts
6
7
  /** Handles the synthetic usage credential for a Codex-backed OpenAI route. */
@@ -0,0 +1,12 @@
1
+ //#region extensions/codex/src/app-server/version.ts
2
+ /**
3
+ * Version and package pins for the managed Codex app-server runtime.
4
+ */
5
+ /** Exact Codex app-server version shipped by the OpenClaw Codex bridge. */
6
+ const CODEX_APP_SERVER_VERSION = "0.153.4";
7
+ /** Inclusive runtime compatibility floor for external app-server binaries. */
8
+ const MIN_SUPPORTED_CODEX_APP_SERVER_VERSION = "0.149.0";
9
+ /** npm package name for the managed Codex app-server binary. */
10
+ const MANAGED_CODEX_APP_SERVER_PACKAGE = "@openai/codex";
11
+ //#endregion
12
+ export { MANAGED_CODEX_APP_SERVER_PACKAGE as n, MIN_SUPPORTED_CODEX_APP_SERVER_VERSION as r, CODEX_APP_SERVER_VERSION as t };
@@ -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 { o as isJsonObject } from "./protocol-CAAcVIKF.js";
2
+ import { x as buildCodexNativeWebSearchThreadConfig } from "./thread-lifecycle-D1pzRwHB.js";
3
+ import { runBoundedCodexAppServerTurn } from "./bounded-turn-lRpmZHFv.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
@@ -19,7 +19,14 @@
19
19
  ],
20
20
  "doctorContract": {
21
21
  "configRepair": true,
22
- "stateMigrations": true
22
+ "stateMigrations": [
23
+ { "id": "codex-app-server-sidecars-to-plugin-state" },
24
+ {
25
+ "id": "codex-app-server-orphaned-session-bindings",
26
+ "doctorOnly": true,
27
+ "phase": "after-session-repair"
28
+ }
29
+ ]
23
30
  },
24
31
  "doctorHealthChecks": true,
25
32
  "sessionRouteStateOwners": [
@@ -81,6 +88,20 @@
81
88
  "cliCommand": "plugins"
82
89
  }
83
90
  ],
91
+ "setup": {
92
+ "nativeSessionCatalog": {
93
+ "label": "Codex",
94
+ "legacyDefaultEnabled": true,
95
+ "description": "Existing native Codex conversations on this Gateway and eligible paired nodes.",
96
+ "nodeCommands": [
97
+ "codex.appServer.threads.list.v1",
98
+ "codex.appServer.thread.turns.list.v1",
99
+ "codex.sessionCatalog.transcript.read.v1",
100
+ "codex.terminal.resume.v1",
101
+ "codex.cli.sessions.list"
102
+ ]
103
+ }
104
+ },
84
105
  "configSchema": {
85
106
  "type": "object",
86
107
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/codex",
3
- "version": "2026.9.1",
3
+ "version": "2026.9.3",
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.3"
40
40
  },
41
41
  "build": {
42
- "openclawVersion": "2026.9.1"
42
+ "openclawVersion": "2026.9.3"
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.3"
63
63
  },
64
64
  "peerDependenciesMeta": {
65
65
  "openclaw": {