@openclaw/codex 2026.7.2-beta.2 → 2026.7.2-beta.4

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 (39) hide show
  1. package/dist/{app-server-policy-Scc-Wevo.js → app-server-policy-BO3jYBkv.js} +1 -1
  2. package/dist/{attempt-notifications-BFmNhqFl.js → attempt-notifications-DdmnBMUp.js} +1 -1
  3. package/dist/{media-understanding-provider-D31dOJwb.js → bounded-turn-CaQL96kg.js} +43 -183
  4. package/dist/capabilities-CLICvTxf.js +36 -0
  5. package/dist/cli-metadata.js +1 -1
  6. package/dist/{command-formatters-Dq9InZUK.js → command-formatters-DgADqnHa.js} +4 -34
  7. package/dist/{command-handlers-IgqmL_kv.js → command-handlers-l_lVPNlB.js} +72 -13
  8. package/dist/{compact-DCTmg3id.js → compact-CC5KhBzX.js} +5 -4
  9. package/dist/{computer-use-CPcU8TjG.js → computer-use-Ip1-QGa-.js} +4 -4
  10. package/dist/{conversation-control-CGkBlfc5.js → conversation-control-sNPsbTCP.js} +6 -5
  11. package/dist/doctor-contract-api.js +1 -1
  12. package/dist/{dynamic-tools-C_1tEs34.js → dynamic-tools-CQI3UwqY.js} +117 -2543
  13. package/dist/event-projector-assistant-message-DTgnPPVF.js +101 -0
  14. package/dist/event-projector-usage-D6tE7_qD.js +69 -0
  15. package/dist/harness.js +27 -7
  16. package/dist/incognito-session-ET_ufDH-.js +2 -0
  17. package/dist/index.js +60 -26
  18. package/dist/media-understanding-provider.js +168 -1
  19. package/dist/{models-uh26C8QU.js → models-BNeMlHgg.js} +2 -2
  20. package/dist/{notification-correlation-KmfV4EkP.js → notification-correlation-BGLixv5_.js} +3 -3
  21. package/dist/{plugin-app-cache-key-Ceb-lm2c.js → plugin-app-cache-key-CvzvmBRz.js} +2 -2
  22. package/dist/{rate-limits-DyXaYAxU.js → rate-limits-D0IJT-a6.js} +3 -1
  23. package/dist/{request-B_oQsCXy.js → request-BTccUTD3.js} +1 -1
  24. package/dist/{run-attempt-MLzoMe_m.js → run-attempt--858NXDl.js} +2798 -172
  25. package/dist/{session-binding-h1mmCGnl.js → session-binding-ZSMX1omP.js} +9 -2
  26. package/dist/{session-catalog-CEvoXWHA.js → session-catalog-DsKaezgR.js} +119 -96
  27. package/dist/{session-cli-XsEuWb_C.js → session-cli-CYJTfRLG.js} +2 -2
  28. package/dist/session-upstream-marker-D7XlI9us.js +82 -0
  29. package/dist/settled-turn-finalizer-DHltNgtF.js +303 -0
  30. package/dist/{shared-client-JiAnW6pc.js → shared-client-wmgNFNYp.js} +82 -13
  31. package/dist/{side-question-DqDvIwSU.js → side-question-BfFZCsJ-.js} +21 -15
  32. package/dist/{thread-lifecycle-CN_pPtPh.js → thread-lifecycle-cqrOlJkq.js} +157 -32
  33. package/dist/{transcript-mirror-D9rTxx2P.js → transcript-mirror-2p7kl6e4.js} +433 -145
  34. package/dist/upstream-session-fork-vPjwkT1i.js +320 -0
  35. package/dist/{usage-D5Rohxoc.js → usage-DM_I3mPT.js} +3 -3
  36. package/dist/{web-search-provider.runtime-CKVBn3fP.js → web-search-provider.runtime-Bx6HAc_k.js} +3 -3
  37. package/npm-shrinkwrap.json +38 -38
  38. package/openclaw.plugin.json +11 -1
  39. package/package.json +7 -7
@@ -0,0 +1,320 @@
1
+ import { l as sessionBindingIdentity } from "./session-binding-ZSMX1omP.js";
2
+ import { h as assertCodexThreadForkResponse } from "./transcript-mirror-2p7kl6e4.js";
3
+ import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
4
+ import { i as createImportedCodexSession, n as codexUpstreamBaseline, t as codexLastTerminalTurnId } from "./session-upstream-marker-D7XlI9us.js";
5
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
6
+ import { readVisibleSessionTranscriptMessageEntries } from "openclaw/plugin-sdk/session-transcript-runtime";
7
+ import { deleteSessionUpstreamLink, upsertSessionUpstreamLink } from "openclaw/plugin-sdk/session-catalog";
8
+ //#region extensions/codex/src/app-server/upstream-fork-boundary.ts
9
+ const TURN_PAGE_LIMIT = 100;
10
+ function failure(code, message) {
11
+ return {
12
+ ok: false,
13
+ code,
14
+ message
15
+ };
16
+ }
17
+ function asInputs(item) {
18
+ return Array.isArray(item.content) ? item.content : [];
19
+ }
20
+ function userMessageDisplay(item) {
21
+ let text = "";
22
+ let hasTextElement = false;
23
+ let hasImage = false;
24
+ let hasUnverifiableInput = false;
25
+ for (const input of asInputs(item)) if (input.type === "text") {
26
+ if (typeof input.text === "string") text += input.text;
27
+ hasTextElement ||= Array.isArray(input.textElements) && input.textElements.length > 0;
28
+ } else {
29
+ hasUnverifiableInput = true;
30
+ hasImage ||= input.type === "image" || input.type === "localImage";
31
+ }
32
+ return {
33
+ text,
34
+ visible: Boolean(text.trim()) || hasTextElement || hasImage,
35
+ hasUnverifiableInput
36
+ };
37
+ }
38
+ function isHiddenNestedReviewTurn(previous, turn) {
39
+ if (previous?.status !== "completed" || turn.status !== "interrupted" || turn.completedAt != null || !previous.items.some((item) => item.type === "enteredReviewMode") || !previous.items.some((item) => item.type === "exitedReviewMode")) return false;
40
+ const userMessages = turn.items.filter((item) => item.type === "userMessage");
41
+ const [firstUserMessage, secondUserMessage] = userMessages;
42
+ if (!firstUserMessage || !secondUserMessage || userMessages.length !== 2) return false;
43
+ return JSON.stringify(asInputs(firstUserMessage)) === JSON.stringify(asInputs(secondUserMessage));
44
+ }
45
+ function localMessageText(content) {
46
+ if (typeof content === "string") return content;
47
+ if (!Array.isArray(content)) return;
48
+ const texts = [];
49
+ for (const block of content) {
50
+ if (!block || typeof block !== "object" || Array.isArray(block)) return;
51
+ const typed = block;
52
+ if (typed.type !== "text" || typeof typed.text !== "string") return;
53
+ texts.push(typed.text);
54
+ }
55
+ return texts.join("");
56
+ }
57
+ function resolveCodexUpstreamForkBoundaryFromTurns(params) {
58
+ let visibleUserMessagesSeen = 0;
59
+ let reviewMode = false;
60
+ for (const [turnIndex, turn] of params.turns.entries()) {
61
+ const hiddenNestedReviewTurn = isHiddenNestedReviewTurn(params.turns[turnIndex - 1], turn);
62
+ let userMessagesInTurn = 0;
63
+ for (const item of turn.items) {
64
+ if (item.type === "enteredReviewMode") {
65
+ reviewMode = true;
66
+ continue;
67
+ }
68
+ if (item.type === "exitedReviewMode") {
69
+ reviewMode = false;
70
+ continue;
71
+ }
72
+ if (item.type !== "userMessage") continue;
73
+ const isSteer = userMessagesInTurn > 0;
74
+ userMessagesInTurn += 1;
75
+ if (reviewMode || hiddenNestedReviewTurn) continue;
76
+ const display = userMessageDisplay(item);
77
+ if (display.hasUnverifiableInput) return failure("drift-mismatch", "A message before the fork point contains images or attachments that cannot be verified across OpenClaw and Codex. Fork from a text-only span instead.");
78
+ if (!display.visible) continue;
79
+ const ordinal = visibleUserMessagesSeen;
80
+ if (ordinal > params.userMessageOrdinal) break;
81
+ const localText = params.localPrefixTexts[ordinal];
82
+ if (localText === void 0) return failure("drift-mismatch", "A message before the fork point contains images or attachments that cannot be verified across OpenClaw and Codex. Fork from a text-only span instead.");
83
+ if (display.text !== localText) return failure("drift-mismatch", "The local conversation no longer matches the Codex thread. Refresh the session and try again.");
84
+ if (ordinal !== params.userMessageOrdinal) {
85
+ visibleUserMessagesSeen += 1;
86
+ continue;
87
+ }
88
+ if (isSteer) return failure("steer-message", "This message steered an existing Codex turn and cannot be forked independently. Fork from the turn's first message instead.");
89
+ if (turn.status === "inProgress") return failure("in-progress-turn", "This Codex turn is still in progress. Wait for it to finish, then try forking again.");
90
+ const retained = turnIndex > 0 ? params.turns[turnIndex - 1] : void 0;
91
+ return {
92
+ ok: true,
93
+ boundary: {
94
+ beforeTurnId: turn.id,
95
+ targetTurnId: turn.id,
96
+ retainedMarker: retained ? {
97
+ turnId: retained.id,
98
+ userMessageCount: retained.items.filter((retainedItem) => retainedItem.type === "userMessage").length
99
+ } : {
100
+ turnId: null,
101
+ userMessageCount: 0
102
+ }
103
+ }
104
+ };
105
+ }
106
+ }
107
+ return failure("drift-mismatch", "The message could not be matched to the Codex thread. Refresh the session and try again.");
108
+ }
109
+ async function listCodexUpstreamTurns(control, threadId) {
110
+ const turns = [];
111
+ const seenCursors = /* @__PURE__ */ new Set();
112
+ let cursor;
113
+ for (;;) {
114
+ const page = await control.listTurnPage({
115
+ threadId,
116
+ limit: TURN_PAGE_LIMIT,
117
+ sortDirection: "asc",
118
+ itemsView: "full",
119
+ ...cursor ? { cursor } : {}
120
+ });
121
+ turns.push(...page.data);
122
+ const nextCursor = page.nextCursor?.trim() || void 0;
123
+ if (!nextCursor) return turns;
124
+ if (seenCursors.has(nextCursor)) throw new Error("Codex returned a repeated thread/turns/list cursor");
125
+ seenCursors.add(nextCursor);
126
+ cursor = nextCursor;
127
+ }
128
+ }
129
+ async function resolveCodexUpstreamForkBoundary(params) {
130
+ try {
131
+ if ((await params.control.readThread(params.threadId, false)).historyMode === "paginated") return failure("upstream-unavailable", "This Codex thread uses paginated history, which cannot be forked from OpenClaw yet.");
132
+ const visibleUserEntries = (await readVisibleSessionTranscriptMessageEntries({
133
+ agentId: params.agentId,
134
+ sessionId: params.sessionId,
135
+ sessionKey: params.sessionKey,
136
+ storePath: params.storePath
137
+ })).filter((entry) => entry.role === "user");
138
+ const userMessageOrdinal = visibleUserEntries.findIndex((entry) => entry.entryId === params.entryId);
139
+ if (userMessageOrdinal < 0) return failure("drift-mismatch", "The local message could not be mapped to the Codex thread. Refresh the session and try again.");
140
+ const localPrefixTexts = visibleUserEntries.slice(0, userMessageOrdinal + 1).map((entry) => localMessageText("content" in entry.message ? entry.message.content : void 0));
141
+ const resolved = resolveCodexUpstreamForkBoundaryFromTurns({
142
+ turns: await listCodexUpstreamTurns(params.control, params.threadId),
143
+ userMessageOrdinal,
144
+ localPrefixTexts
145
+ });
146
+ return resolved.ok ? {
147
+ ...resolved,
148
+ editorText: localPrefixTexts[userMessageOrdinal]
149
+ } : resolved;
150
+ } catch {
151
+ return failure("upstream-unavailable", "The Codex thread could not be read. Check that Codex is available, then try again.");
152
+ }
153
+ }
154
+ function precheckCodexUpstreamForkBoundary(params) {
155
+ const target = params.turns.find((turn) => turn.id === params.boundary.targetTurnId);
156
+ if (!target) return failure("upstream-unavailable", "The Codex thread changed before it could be forked. Refresh the session and try again.");
157
+ if (target.status === "inProgress") return failure("in-progress-turn", "This Codex turn is still in progress. Wait for it to finish, then try forking again.");
158
+ return {
159
+ ok: true,
160
+ boundary: params.boundary
161
+ };
162
+ }
163
+ //#endregion
164
+ //#region extensions/codex/src/app-server/upstream-session-fork.ts
165
+ function readConnectionFingerprint(ref) {
166
+ if (!isRecord(ref)) return;
167
+ return typeof ref.connectionFingerprint === "string" && ref.connectionFingerprint.trim() ? ref.connectionFingerprint : void 0;
168
+ }
169
+ function normalizeTurnId(value) {
170
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
171
+ }
172
+ async function forkCodexUpstreamSession(params, options) {
173
+ try {
174
+ return await options.control.withPinnedConnection(async (control) => {
175
+ const incognito = isIncognitoSessionKey(params.targetKey);
176
+ const clientId = control.clientId?.trim();
177
+ if (incognito && !clientId) throw new Error("Incognito Codex forks require the live pinned app-server client");
178
+ let linked = false;
179
+ let bindingIdentity;
180
+ const compensateFork = async (forkedThreadId) => {
181
+ if (bindingIdentity) await options.bindingStore.mutate(bindingIdentity, {
182
+ kind: "clear",
183
+ threadId: forkedThreadId
184
+ }).catch(() => void 0);
185
+ if (linked) deleteSessionUpstreamLink(params.targetKey, params.source.agentId);
186
+ await control.archiveThread(forkedThreadId).catch(() => void 0);
187
+ };
188
+ const sourceFingerprint = readConnectionFingerprint(params.upstream.ref);
189
+ if (params.upstream.kind !== "codex-app-server" || !sourceFingerprint || sourceFingerprint !== control.connectionFingerprint) return {
190
+ status: "failed",
191
+ code: "upstream-unavailable",
192
+ message: "This Codex thread is not available on the current connection. Reconnect to its host and try again."
193
+ };
194
+ const resolved = await resolveCodexUpstreamForkBoundary({
195
+ ...params.source,
196
+ threadId: params.upstream.threadId,
197
+ control
198
+ });
199
+ if (!resolved.ok) return {
200
+ status: "failed",
201
+ code: resolved.code,
202
+ message: resolved.message
203
+ };
204
+ const liveTurns = await listCodexUpstreamTurns(control, params.upstream.threadId);
205
+ const precheck = precheckCodexUpstreamForkBoundary({
206
+ boundary: resolved.boundary,
207
+ turns: liveTurns
208
+ });
209
+ if (!precheck.ok) return {
210
+ status: "failed",
211
+ code: precheck.code,
212
+ message: precheck.message
213
+ };
214
+ const rawResponse = await control.forkThread({
215
+ threadId: params.upstream.threadId,
216
+ beforeTurnId: resolved.boundary.beforeTurnId,
217
+ ...incognito ? { ephemeral: true } : {},
218
+ excludeTurns: !incognito
219
+ });
220
+ let response;
221
+ try {
222
+ response = assertCodexThreadForkResponse(rawResponse);
223
+ } catch (error) {
224
+ const orphanThreadId = isRecord(rawResponse.thread) && typeof rawResponse.thread.id === "string" ? rawResponse.thread.id.trim() : "";
225
+ if (orphanThreadId && orphanThreadId !== params.upstream.threadId) await control.archiveThread(orphanThreadId).catch(() => void 0);
226
+ throw error;
227
+ }
228
+ const threadId = response.thread.id.trim();
229
+ if (!threadId) throw new Error("Codex thread/fork response did not include a thread id");
230
+ if (threadId === params.upstream.threadId) throw new Error("Codex thread/fork response reused the source thread id");
231
+ const forkedThreadId = threadId;
232
+ try {
233
+ const connectionFingerprint = control.connectionFingerprint;
234
+ if (!connectionFingerprint) throw new Error("Codex fork connection did not include a fingerprint");
235
+ const forkedTurns = incognito ? response.thread.turns ?? [] : await listCodexUpstreamTurns(control, threadId);
236
+ const expectedLastTurnId = resolved.boundary.retainedMarker.turnId;
237
+ if ((forkedTurns.at(-1)?.id ?? null) !== expectedLastTurnId) {
238
+ await compensateFork(forkedThreadId);
239
+ return {
240
+ status: "failed",
241
+ code: "upstream-unavailable",
242
+ message: "This Codex version does not support message-level forks. Update Codex, reconnect, and try again."
243
+ };
244
+ }
245
+ const forkedThread = {
246
+ ...response.thread,
247
+ turns: forkedTurns
248
+ };
249
+ const throughTurnId = codexLastTerminalTurnId(forkedThread, normalizeTurnId) ?? null;
250
+ const marker = codexUpstreamBaseline(forkedThread, normalizeTurnId);
251
+ const config = options.resolveConfig?.() ?? {};
252
+ return {
253
+ status: "created",
254
+ key: (await createImportedCodexSession({
255
+ runtime: options.runtime,
256
+ config,
257
+ key: params.targetKey,
258
+ agentId: params.source.agentId,
259
+ thread: forkedThread,
260
+ throughTurnId,
261
+ initialEntry: {
262
+ agentHarnessId: options.harnessRuntimeId,
263
+ modelSelectionLocked: true
264
+ },
265
+ afterImport: async (entry) => {
266
+ bindingIdentity = sessionBindingIdentity({
267
+ agentId: entry.agentId,
268
+ sessionId: entry.sessionId,
269
+ sessionKey: entry.key,
270
+ config
271
+ });
272
+ linked = upsertSessionUpstreamLink({
273
+ sessionKey: entry.key,
274
+ agentId: entry.agentId,
275
+ catalogId: params.upstream.catalogId,
276
+ hostId: params.upstream.hostId,
277
+ threadId,
278
+ upstreamKind: params.upstream.kind,
279
+ upstreamRef: {
280
+ connectionFingerprint,
281
+ threadId
282
+ },
283
+ marker
284
+ });
285
+ if (!linked) throw new Error("Codex fork link could not be persisted");
286
+ if (!await options.bindingStore.mutate(bindingIdentity, {
287
+ kind: "set",
288
+ binding: {
289
+ threadId,
290
+ ...incognito && clientId ? { clientId } : {},
291
+ cwd: forkedThread.cwd ?? "",
292
+ model: response.model,
293
+ modelProvider: response.modelProvider ?? void 0,
294
+ historyCoveredThrough: (/* @__PURE__ */ new Date()).toISOString()
295
+ }
296
+ })) throw new Error("Codex session binding changed before the fork could be attached");
297
+ return { pluginExtensions: entry.entry.pluginExtensions };
298
+ }
299
+ })).key,
300
+ ...resolved.editorText !== void 0 ? { editorText: resolved.editorText } : {}
301
+ };
302
+ } catch {
303
+ await compensateFork(forkedThreadId);
304
+ return {
305
+ status: "failed",
306
+ code: "upstream-unavailable",
307
+ message: "The Codex fork could not be verified or imported into a new session. Refresh sessions and try again."
308
+ };
309
+ }
310
+ });
311
+ } catch {
312
+ return {
313
+ status: "failed",
314
+ code: "upstream-unavailable",
315
+ message: "The Codex thread could not be forked. Check that Codex is available, then try again."
316
+ };
317
+ }
318
+ }
319
+ //#endregion
320
+ export { forkCodexUpstreamSession };
@@ -1,6 +1,6 @@
1
- import { b as resolveCodexAppServerRuntimeOptions } from "./session-binding-h1mmCGnl.js";
2
- import { t as buildCodexAppServerUsageSnapshot } from "./rate-limits-DyXaYAxU.js";
3
- import { t as readCodexAppServerUsage } from "./request-B_oQsCXy.js";
1
+ import { x as resolveCodexAppServerRuntimeOptions } from "./session-binding-ZSMX1omP.js";
2
+ import { t as buildCodexAppServerUsageSnapshot } from "./rate-limits-D0IJT-a6.js";
3
+ import { t as readCodexAppServerUsage } from "./request-BTccUTD3.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 { Z as isJsonObject } from "./shared-client-JiAnW6pc.js";
2
- import { u as buildCodexNativeWebSearchThreadConfig } from "./thread-lifecycle-CN_pPtPh.js";
3
- import { n as runBoundedCodexAppServerTurn } from "./media-understanding-provider-D31dOJwb.js";
1
+ import { Q as isJsonObject } from "./shared-client-wmgNFNYp.js";
2
+ import { m as buildCodexNativeWebSearchThreadConfig } from "./thread-lifecycle-cqrOlJkq.js";
3
+ import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-CaQL96kg.js";
4
4
  import { readStringParam, resolveSearchTimeoutSeconds, wrapWebContent } from "openclaw/plugin-sdk/provider-web-search";
5
5
  //#region extensions/codex/src/web-search-provider.runtime.ts
6
6
  async function executeCodexWebSearchProviderTool(ctx, args, executionContext, options) {
@@ -1,25 +1,25 @@
1
1
  {
2
2
  "name": "@openclaw/codex",
3
- "version": "2026.7.2-beta.2",
3
+ "version": "2026.7.2-beta.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/codex",
9
- "version": "2026.7.2-beta.2",
9
+ "version": "2026.7.2-beta.4",
10
10
  "dependencies": {
11
- "@openai/codex": "0.144.5",
11
+ "@openai/codex": "0.145.0",
12
12
  "semver": "7.8.5",
13
13
  "smol-toml": "1.7.0",
14
- "typebox": "1.3.3",
15
- "ws": "8.21.0",
14
+ "typebox": "1.3.6",
15
+ "ws": "8.21.1",
16
16
  "zod": "4.4.3"
17
17
  }
18
18
  },
19
19
  "node_modules/@openai/codex": {
20
- "version": "0.144.5",
21
- "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.5.tgz",
22
- "integrity": "sha512-jjB+K+OMv572mKhS+2QuLxWXDJNdpwbPenf+V+8bdq7wg4Scqt3cn6WEekD8wPqDVZqck0HSX17K9rD9kbDJQA==",
20
+ "version": "0.145.0",
21
+ "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.145.0.tgz",
22
+ "integrity": "sha512-/PSPSFujjjmiyVFvG2yu/grOFhsWdokTH8t2KGWhXSo/M5n/dIDsnbsnO82/7bLtIoDuzQf7ATBUMWqPWQINlQ==",
23
23
  "license": "Apache-2.0",
24
24
  "bin": {
25
25
  "codex": "bin/codex.js"
@@ -28,19 +28,19 @@
28
28
  "node": ">=16"
29
29
  },
30
30
  "optionalDependencies": {
31
- "@openai/codex-darwin-arm64": "npm:@openai/codex@0.144.5-darwin-arm64",
32
- "@openai/codex-darwin-x64": "npm:@openai/codex@0.144.5-darwin-x64",
33
- "@openai/codex-linux-arm64": "npm:@openai/codex@0.144.5-linux-arm64",
34
- "@openai/codex-linux-x64": "npm:@openai/codex@0.144.5-linux-x64",
35
- "@openai/codex-win32-arm64": "npm:@openai/codex@0.144.5-win32-arm64",
36
- "@openai/codex-win32-x64": "npm:@openai/codex@0.144.5-win32-x64"
31
+ "@openai/codex-darwin-arm64": "npm:@openai/codex@0.145.0-darwin-arm64",
32
+ "@openai/codex-darwin-x64": "npm:@openai/codex@0.145.0-darwin-x64",
33
+ "@openai/codex-linux-arm64": "npm:@openai/codex@0.145.0-linux-arm64",
34
+ "@openai/codex-linux-x64": "npm:@openai/codex@0.145.0-linux-x64",
35
+ "@openai/codex-win32-arm64": "npm:@openai/codex@0.145.0-win32-arm64",
36
+ "@openai/codex-win32-x64": "npm:@openai/codex@0.145.0-win32-x64"
37
37
  }
38
38
  },
39
39
  "node_modules/@openai/codex-darwin-arm64": {
40
40
  "name": "@openai/codex",
41
- "version": "0.144.5-darwin-arm64",
42
- "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.5-darwin-arm64.tgz",
43
- "integrity": "sha512-zcT6NfBCqLFt+BReNSETTZW6v6PdbH0dzNtm9j7l7mDGqwPbKZDGJdnpkBao2389I0ZacyIKgSZoI0vez1d4Dw==",
41
+ "version": "0.145.0-darwin-arm64",
42
+ "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.145.0-darwin-arm64.tgz",
43
+ "integrity": "sha512-h6aQ0UxnaP8mIM/9/qPAH9MNkRliJo88toq1T36IxNM2L5JSU0TFamu+MZn7YkFgDsrp0RfiI+97Tm8AVVxqtA==",
44
44
  "cpu": [
45
45
  "arm64"
46
46
  ],
@@ -55,9 +55,9 @@
55
55
  },
56
56
  "node_modules/@openai/codex-darwin-x64": {
57
57
  "name": "@openai/codex",
58
- "version": "0.144.5-darwin-x64",
59
- "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.5-darwin-x64.tgz",
60
- "integrity": "sha512-//Mo0m1MwaoT6psu5xsmofXpKx4/0irIkeq10xJvk59+886EG355ibjA+ZmlRcKhE3bLjsKD7p81nTbAdRL/bw==",
58
+ "version": "0.145.0-darwin-x64",
59
+ "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.145.0-darwin-x64.tgz",
60
+ "integrity": "sha512-FCYzVKCa9VoLtg9gVyzKpqylonfgZrfcWZN6HsXAZPeuo8CukdMqdgTUOhDn2V6h3MbqS0z6VqQVKUllN/yKhA==",
61
61
  "cpu": [
62
62
  "x64"
63
63
  ],
@@ -72,9 +72,9 @@
72
72
  },
73
73
  "node_modules/@openai/codex-linux-arm64": {
74
74
  "name": "@openai/codex",
75
- "version": "0.144.5-linux-arm64",
76
- "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.5-linux-arm64.tgz",
77
- "integrity": "sha512-zAHggxVwR2TBxKmybXY7ZMiB0G8DMonY2YPdwNNjwXcf+LOIqNGgswwNCDMbP/HEe6r8j+R9ZX/yYoo8f+n/RQ==",
75
+ "version": "0.145.0-linux-arm64",
76
+ "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.145.0-linux-arm64.tgz",
77
+ "integrity": "sha512-8OLcPXaAol/FOrRoDxWhIiHIFa73KRsM41EKocjRZOwiT4TcelzJWn3dHyiuSb7teWF25rrslvSPyvhULYRRCQ==",
78
78
  "cpu": [
79
79
  "arm64"
80
80
  ],
@@ -89,9 +89,9 @@
89
89
  },
90
90
  "node_modules/@openai/codex-linux-x64": {
91
91
  "name": "@openai/codex",
92
- "version": "0.144.5-linux-x64",
93
- "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.5-linux-x64.tgz",
94
- "integrity": "sha512-FalLJlBQGFdK8Gc3kj9sa/ekNdgkHhUawLaKkvy5CtB18JaP2YxtTP/Pe1pD2iBiq8mMUliRnafpF6AdBdQMbg==",
92
+ "version": "0.145.0-linux-x64",
93
+ "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.145.0-linux-x64.tgz",
94
+ "integrity": "sha512-u8w8LLv3DvsfrDCoswLIemZ0SoNEXyi511WsfFsSiYUazk9qMsB/NtU8N9vhAfN7mZAxLFoMex4v66JjHuZWwA==",
95
95
  "cpu": [
96
96
  "x64"
97
97
  ],
@@ -106,9 +106,9 @@
106
106
  },
107
107
  "node_modules/@openai/codex-win32-arm64": {
108
108
  "name": "@openai/codex",
109
- "version": "0.144.5-win32-arm64",
110
- "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.5-win32-arm64.tgz",
111
- "integrity": "sha512-0Pj7iqjEOEvPQPO3kFfCy9vGX4BTu76ChFFZHr2eNNIfVc3FOENAv/X98u4L+iIUtDOK9DbqmfUudW3DPapshg==",
109
+ "version": "0.145.0-win32-arm64",
110
+ "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.145.0-win32-arm64.tgz",
111
+ "integrity": "sha512-sub61rjEFevi1i3Zx7nAd4JM5XxoNFqMqFc5LfTo2xSI8ixHjFvEYDFDXwXOftT04n3Ht1Wh271ioUZpDiEjEg==",
112
112
  "cpu": [
113
113
  "arm64"
114
114
  ],
@@ -123,9 +123,9 @@
123
123
  },
124
124
  "node_modules/@openai/codex-win32-x64": {
125
125
  "name": "@openai/codex",
126
- "version": "0.144.5-win32-x64",
127
- "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.5-win32-x64.tgz",
128
- "integrity": "sha512-DnsSTlnnzleTxvLwIGnBitKInscxn2I7qASqosS8Fv+qysBygd+ZiBn/SQsRCgQ28PAlsNzmd3Gf3ZTecolAmg==",
126
+ "version": "0.145.0-win32-x64",
127
+ "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.145.0-win32-x64.tgz",
128
+ "integrity": "sha512-u0h9lk094CaXRSqE34SBW2dRaQTPa6fASXqehczWH9QdsU62mBsiAgAdp6tCG4i+YzPmmhjD8FdXNnYGNmwuMg==",
129
129
  "cpu": [
130
130
  "x64"
131
131
  ],
@@ -163,15 +163,15 @@
163
163
  }
164
164
  },
165
165
  "node_modules/typebox": {
166
- "version": "1.3.3",
167
- "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.3.3.tgz",
168
- "integrity": "sha512-URXGUE31PJDQC+PtRMJeLdF4kmmOdFoVPikPCtV2oOIhUpNpppEdIz7W8bH8cFYPYHdDpaRvqwdegMTmHliudg==",
166
+ "version": "1.3.6",
167
+ "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.3.6.tgz",
168
+ "integrity": "sha512-Sc8RA0NCMEFmApHNU9ZMzqcpQj46She44J8ffpLM/bdhLNUZKq7DJumcLcsFx1gRmDfQPgCgOmFFJ7rcnfWNyA==",
169
169
  "license": "MIT"
170
170
  },
171
171
  "node_modules/ws": {
172
- "version": "8.21.0",
173
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
174
- "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
172
+ "version": "8.21.1",
173
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
174
+ "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==",
175
175
  "license": "MIT",
176
176
  "engines": {
177
177
  "node": ">=10.0.0"
@@ -279,6 +279,11 @@
279
279
  "minimum": 1,
280
280
  "default": 60000
281
281
  },
282
+ "turnAssistantCompletionIdleTimeoutMs": {
283
+ "type": "number",
284
+ "minimum": 1,
285
+ "default": 10000
286
+ },
282
287
  "postToolRawAssistantCompletionIdleTimeoutMs": {
283
288
  "type": "number",
284
289
  "minimum": 1,
@@ -536,7 +541,7 @@
536
541
  },
537
542
  "appServer.transport": {
538
543
  "label": "Transport",
539
- "help": "Use stdio to spawn Codex locally, unix for the shared local control socket, or websocket for a remote app-server.",
544
+ "help": "Use stdio to spawn Codex locally or unix for the shared local control socket. Remote websocket transport is experimental and unsupported by Codex.",
540
545
  "advanced": true
541
546
  },
542
547
  "appServer.homeScope": {
@@ -601,6 +606,11 @@
601
606
  "help": "Maximum quiet time after Codex accepts a turn or after a turn-scoped app-server request before OpenClaw interrupts the turn while waiting for turn/completed.",
602
607
  "advanced": true
603
608
  },
609
+ "appServer.turnAssistantCompletionIdleTimeoutMs": {
610
+ "label": "Assistant Completion Idle Timeout",
611
+ "help": "Short quiet-time guard after Codex reports a completed assistant message before OpenClaw releases the turn.",
612
+ "advanced": true
613
+ },
604
614
  "appServer.postToolRawAssistantCompletionIdleTimeoutMs": {
605
615
  "label": "Post-Tool Continuation Idle Timeout",
606
616
  "help": "Completion-idle and progress guard after a tool handoff, native tool completion, or post-tool raw assistant progress while waiting for turn/completed. Defaults to 300000 ms when unset.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/codex",
3
- "version": "2026.7.2-beta.2",
3
+ "version": "2026.7.2-beta.4",
4
4
  "description": "OpenClaw Codex app-server harness and native session supervision plugin.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,11 +8,11 @@
8
8
  },
9
9
  "type": "module",
10
10
  "dependencies": {
11
- "@openai/codex": "0.144.5",
11
+ "@openai/codex": "0.145.0",
12
12
  "semver": "7.8.5",
13
13
  "smol-toml": "1.7.0",
14
- "typebox": "1.3.3",
15
- "ws": "8.21.0",
14
+ "typebox": "1.3.6",
15
+ "ws": "8.21.1",
16
16
  "zod": "4.4.3"
17
17
  },
18
18
  "devDependencies": {
@@ -36,10 +36,10 @@
36
36
  ]
37
37
  },
38
38
  "compat": {
39
- "pluginApi": ">=2026.7.2-beta.2"
39
+ "pluginApi": ">=2026.7.2-beta.4"
40
40
  },
41
41
  "build": {
42
- "openclawVersion": "2026.7.2-beta.2"
42
+ "openclawVersion": "2026.7.2-beta.4"
43
43
  },
44
44
  "release": {
45
45
  "publishToClawHub": true,
@@ -60,7 +60,7 @@
60
60
  "README.md"
61
61
  ],
62
62
  "peerDependencies": {
63
- "openclaw": ">=2026.7.2-beta.2"
63
+ "openclaw": ">=2026.7.2-beta.4"
64
64
  },
65
65
  "peerDependenciesMeta": {
66
66
  "openclaw": {