@openclaw/codex 2026.5.3 → 2026.5.4-beta.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.
@@ -1,10 +1,11 @@
1
- import { i as resolveCodexAppServerRuntimeOptions, n as codexSandboxPolicyForTurn } from "./config-CkkoMeqF.js";
1
+ import { i as resolveCodexAppServerRuntimeOptions, n as codexSandboxPolicyForTurn } from "./config-ByrA30No.js";
2
2
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
3
- import { n as getSharedCodexAppServerClient, s as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-0El8eRIE.js";
4
- import { t as CODEX_CONTROL_METHODS } from "./capabilities-BmhO5h8O.js";
3
+ import { d as CODEX_CONTROL_METHODS, r as formatCodexDisplayText } from "./command-formatters-PiJcdUbu.js";
4
+ import { n as getSharedCodexAppServerClient, s as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-Dfk3Enm-.js";
5
5
  import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, r as normalizeCodexAppServerBindingModelProvider, t as clearCodexAppServerBinding } from "./session-binding-DuJYTJQy.js";
6
6
  import { formatErrorMessage } from "openclaw/plugin-sdk/agent-harness-runtime";
7
7
  import path from "node:path";
8
+ import { fileURLToPath } from "node:url";
8
9
  import process from "node:process";
9
10
  //#region extensions/codex/src/conversation-binding-data.ts
10
11
  const BINDING_DATA_VERSION = 1;
@@ -130,7 +131,7 @@ async function setCodexConversationModel(params) {
130
131
  sandbox: binding.sandbox,
131
132
  serviceTier: binding.serviceTier ?? runtime.serviceTier
132
133
  });
133
- return `Codex model set to ${response.model ?? model}.`;
134
+ return `Codex model set to ${formatCodexDisplayText(response.model ?? model)}.`;
134
135
  }
135
136
  async function setCodexConversationFastMode(params) {
136
137
  const binding = await requireThreadBinding(params.sessionFile);
@@ -200,6 +201,7 @@ function permissionsForMode(mode) {
200
201
  }
201
202
  //#endregion
202
203
  //#region extensions/codex/src/conversation-turn-collector.ts
204
+ const MAX_PENDING_NOTIFICATIONS_PER_TURN = 100;
203
205
  function createCodexConversationTurnCollector(threadId) {
204
206
  let turnId;
205
207
  let completed = false;
@@ -207,6 +209,7 @@ function createCodexConversationTurnCollector(threadId) {
207
209
  let timeout;
208
210
  const assistantTextByItem = /* @__PURE__ */ new Map();
209
211
  const assistantOrder = [];
212
+ const pendingNotificationsByTurnId = /* @__PURE__ */ new Map();
210
213
  let resolveCompletion;
211
214
  let rejectCompletion;
212
215
  const rememberItem = (itemId) => {
@@ -230,49 +233,65 @@ function createCodexConversationTurnCollector(threadId) {
230
233
  else resolveCompletion?.({ replyText: collectReplyText() });
231
234
  clearWaitState();
232
235
  };
233
- return {
234
- setTurnId(nextTurnId) {
235
- turnId = nextTurnId;
236
- },
237
- handleNotification(notification) {
238
- const params = isJsonObject(notification.params) ? notification.params : void 0;
239
- if (!params || !isNotificationForTurn(params, threadId, turnId)) return;
240
- if (notification.method === "item/agentMessage/delta") {
241
- const itemId = readString(params, "itemId") ?? readString(params, "id") ?? "assistant";
242
- const delta = readTextString(params, "delta");
243
- if (!delta) return;
244
- rememberItem(itemId);
245
- assistantTextByItem.set(itemId, `${assistantTextByItem.get(itemId) ?? ""}${delta}`);
246
- return;
236
+ const handleNotification = (notification) => {
237
+ const params = isJsonObject(notification.params) ? notification.params : void 0;
238
+ if (!params || readString(params, "threadId") !== threadId) return;
239
+ if (!turnId) {
240
+ const pendingTurnId = readNotificationTurnId(params);
241
+ if (pendingTurnId) {
242
+ const pending = pendingNotificationsByTurnId.get(pendingTurnId) ?? [];
243
+ if (pending.length < MAX_PENDING_NOTIFICATIONS_PER_TURN) {
244
+ pending.push(notification);
245
+ pendingNotificationsByTurnId.set(pendingTurnId, pending);
246
+ }
247
247
  }
248
- if (notification.method === "item/completed") {
249
- const item = isJsonObject(params.item) ? params.item : void 0;
250
- if (item?.type === "agentMessage") {
251
- const itemId = readString(item, "id") ?? readString(params, "itemId") ?? "assistant";
252
- const text = readTextString(item, "text");
253
- if (text) {
254
- rememberItem(itemId);
255
- assistantTextByItem.set(itemId, text);
256
- }
248
+ return;
249
+ }
250
+ if (!isNotificationForTurn(params, threadId, turnId)) return;
251
+ if (notification.method === "item/agentMessage/delta") {
252
+ const itemId = readString(params, "itemId") ?? readString(params, "id") ?? "assistant";
253
+ const delta = readTextString(params, "delta");
254
+ if (!delta) return;
255
+ rememberItem(itemId);
256
+ assistantTextByItem.set(itemId, `${assistantTextByItem.get(itemId) ?? ""}${delta}`);
257
+ return;
258
+ }
259
+ if (notification.method === "item/completed") {
260
+ const item = isJsonObject(params.item) ? params.item : void 0;
261
+ if (item?.type === "agentMessage") {
262
+ const itemId = readString(item, "id") ?? readString(params, "itemId") ?? "assistant";
263
+ const text = readTextString(item, "text");
264
+ if (text) {
265
+ rememberItem(itemId);
266
+ assistantTextByItem.set(itemId, text);
257
267
  }
258
- return;
259
268
  }
260
- if (notification.method === "turn/completed") {
261
- const turn = isJsonObject(params.turn) ? params.turn : void 0;
262
- if (readString(turn, "status") === "failed") failedError = readString(readRecord(turn?.error), "message") ?? "codex app-server turn failed";
263
- const items = Array.isArray(turn?.items) ? turn.items : [];
264
- for (const item of items) {
265
- if (!isJsonObject(item) || item.type !== "agentMessage") continue;
266
- const itemId = readString(item, "id") ?? `assistant-${assistantOrder.length + 1}`;
267
- const text = readTextString(item, "text");
268
- if (text) {
269
- rememberItem(itemId);
270
- assistantTextByItem.set(itemId, text);
271
- }
269
+ return;
270
+ }
271
+ if (notification.method === "turn/completed") {
272
+ const turn = isJsonObject(params.turn) ? params.turn : void 0;
273
+ if (readString(turn, "status") === "failed") failedError = readString(readRecord(turn?.error), "message") ?? "codex app-server turn failed";
274
+ const items = Array.isArray(turn?.items) ? turn.items : [];
275
+ for (const item of items) {
276
+ if (!isJsonObject(item) || item.type !== "agentMessage") continue;
277
+ const itemId = readString(item, "id") ?? `assistant-${assistantOrder.length + 1}`;
278
+ const text = readTextString(item, "text");
279
+ if (text) {
280
+ rememberItem(itemId);
281
+ assistantTextByItem.set(itemId, text);
272
282
  }
273
- finish();
274
283
  }
284
+ finish();
285
+ }
286
+ };
287
+ return {
288
+ setTurnId(nextTurnId) {
289
+ turnId = nextTurnId;
290
+ const pending = pendingNotificationsByTurnId.get(nextTurnId) ?? [];
291
+ pendingNotificationsByTurnId.clear();
292
+ for (const notification of pending) handleNotification(notification);
275
293
  },
294
+ handleNotification,
276
295
  wait(params) {
277
296
  if (completed) return failedError ? Promise.reject(new Error(failedError)) : Promise.resolve({ replyText: collectReplyText() });
278
297
  return new Promise((resolve, reject) => {
@@ -295,6 +314,9 @@ function isNotificationForTurn(params, threadId, turnId) {
295
314
  if (directTurnId) return directTurnId === turnId;
296
315
  return readString(isJsonObject(params.turn) ? params.turn : void 0, "id") === turnId;
297
316
  }
317
+ function readNotificationTurnId(params) {
318
+ return readString(params, "turnId") ?? readString(readRecord(params.turn), "id");
319
+ }
298
320
  function readRecord(value) {
299
321
  return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
300
322
  }
@@ -339,10 +361,14 @@ function extractInboundMedia(event) {
339
361
  }
340
362
  function toCodexImageInput(media) {
341
363
  if (!isImageMedia(media)) return;
342
- if (media.path) return {
343
- type: "localImage",
344
- path: normalizeFileUrl(media.path)
345
- };
364
+ const localPath = media.path ?? readLocalMediaPath(media.url);
365
+ if (localPath) {
366
+ const normalized = normalizeFileUrl(localPath);
367
+ return normalized ? {
368
+ type: "localImage",
369
+ path: normalized
370
+ } : void 0;
371
+ }
346
372
  return media.url ? {
347
373
  type: "image",
348
374
  url: media.url
@@ -355,7 +381,19 @@ function isImageMedia(media) {
355
381
  return IMAGE_EXTENSIONS.has(path.extname(candidate.split(/[?#]/, 1)[0] ?? "").toLowerCase());
356
382
  }
357
383
  function normalizeFileUrl(value) {
358
- return value.startsWith("file://") ? new URL(value).pathname : value;
384
+ if (!value.startsWith("file://")) return value;
385
+ try {
386
+ return fileURLToPath(value);
387
+ } catch {
388
+ return;
389
+ }
390
+ }
391
+ function readLocalMediaPath(value) {
392
+ if (!value) return;
393
+ if (value.startsWith("file://")) return value;
394
+ if (value.startsWith("//")) return;
395
+ if (path.isAbsolute(value) || path.win32.isAbsolute(value)) return value;
396
+ return /^[a-z][a-z0-9+.-]*:/i.test(value) ? void 0 : value;
359
397
  }
360
398
  function readStringArray(value) {
361
399
  if (typeof value === "string" && value.trim()) return [value.trim()];
@@ -406,7 +444,7 @@ async function handleCodexConversationInboundClaim(event, ctx, options = {}) {
406
444
  const data = readCodexConversationBindingData(ctx.pluginBinding);
407
445
  if (!data) return;
408
446
  if (event.commandAuthorized !== true) return { handled: true };
409
- const prompt = (event.bodyForAgent ?? event.content ?? "").trim();
447
+ const prompt = event.bodyForAgent?.trim() || event.content?.trim() || "";
410
448
  if (!prompt) return { handled: true };
411
449
  try {
412
450
  return {
@@ -422,7 +460,7 @@ async function handleCodexConversationInboundClaim(event, ctx, options = {}) {
422
460
  } catch (error) {
423
461
  return {
424
462
  handled: true,
425
- reply: { text: `Codex app-server turn failed: ${formatErrorMessage(error)}` }
463
+ reply: { text: `Codex app-server turn failed: ${formatCodexDisplayText(formatErrorMessage(error))}` }
426
464
  };
427
465
  }
428
466
  }
@@ -0,0 +1,19 @@
1
+ //#region extensions/codex/doctor-contract-api.ts
2
+ const sessionRouteStateOwners = [{
3
+ id: "codex",
4
+ label: "Codex",
5
+ providerIds: [
6
+ "codex",
7
+ "codex-cli",
8
+ "openai-codex"
9
+ ],
10
+ runtimeIds: ["codex", "codex-cli"],
11
+ cliSessionKeys: ["codex-cli"],
12
+ authProfilePrefixes: [
13
+ "codex:",
14
+ "codex-cli:",
15
+ "openai-codex:"
16
+ ]
17
+ }];
18
+ //#endregion
19
+ export { sessionRouteStateOwners };
package/dist/harness.js CHANGED
@@ -18,11 +18,11 @@ function createCodexAppServerAgentHarness(options) {
18
18
  };
19
19
  },
20
20
  runAttempt: async (params) => {
21
- const { runCodexAppServerAttempt } = await import("./run-attempt-BNbVe-IG.js");
21
+ const { runCodexAppServerAttempt } = await import("./run-attempt-CFL1BFBl.js");
22
22
  return runCodexAppServerAttempt(params, { pluginConfig: options?.pluginConfig });
23
23
  },
24
24
  compact: async (params) => {
25
- const { maybeCompactCodexAppServerSession } = await import("./compact-C0_rGlHZ.js");
25
+ const { maybeCompactCodexAppServerSession } = await import("./compact-DcR5aTxd.js");
26
26
  return maybeCompactCodexAppServerSession(params, { pluginConfig: options?.pluginConfig });
27
27
  },
28
28
  reset: async (params) => {
@@ -32,7 +32,7 @@ function createCodexAppServerAgentHarness(options) {
32
32
  }
33
33
  },
34
34
  dispose: async () => {
35
- const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-0El8eRIE.js").then((n) => n.r);
35
+ const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-Dfk3Enm-.js").then((n) => n.r);
36
36
  await clearSharedCodexAppServerClientAndWait();
37
37
  }
38
38
  };
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { createCodexAppServerAgentHarness } from "./harness.js";
2
2
  import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
3
3
  import { buildCodexProvider } from "./provider.js";
4
- import { n as handleCodexConversationInboundClaim, t as handleCodexConversationBindingResolved } from "./conversation-binding-DjptpT9W.js";
4
+ import { f as describeControlFailure, r as formatCodexDisplayText } from "./command-formatters-PiJcdUbu.js";
5
+ import { n as handleCodexConversationInboundClaim, t as handleCodexConversationBindingResolved } from "./conversation-binding-IhbXJcXQ.js";
5
6
  import { resolveLivePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
6
7
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
7
8
  import fs from "node:fs/promises";
@@ -23,8 +24,12 @@ function createCodexCommand(options) {
23
24
  };
24
25
  }
25
26
  async function handleCodexCommand(ctx, options = {}) {
26
- const { handleCodexSubcommand } = await import("./command-handlers-CeaXhO5y.js");
27
- return await handleCodexSubcommand(ctx, options);
27
+ const { handleCodexSubcommand } = await import("./command-handlers-Bbr7RAUs.js");
28
+ try {
29
+ return await handleCodexSubcommand(ctx, options);
30
+ } catch (error) {
31
+ return { text: `Codex command failed: ${formatCodexDisplayText(describeControlFailure(error))}` };
32
+ }
28
33
  }
29
34
  //#endregion
30
35
  //#region extensions/codex/src/migration/helpers.ts
@@ -1,7 +1,7 @@
1
1
  import { CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS } from "./provider-catalog.js";
2
- import { i as resolveCodexAppServerRuntimeOptions } from "./config-CkkoMeqF.js";
3
- import { a as readCodexErrorNotification, c as readCodexTurnCompletedNotification, n as assertCodexThreadStartResponse, r as assertCodexTurnStartResponse } from "./protocol-validators-Cpopom3_.js";
4
- import { i as readModelListResult } from "./models-Ds7g6191.js";
2
+ import { i as resolveCodexAppServerRuntimeOptions } from "./config-ByrA30No.js";
3
+ import { a as readCodexErrorNotification, c as readCodexTurnCompletedNotification, n as assertCodexThreadStartResponse, r as assertCodexTurnStartResponse } from "./protocol-validators-Dky2yV4W.js";
4
+ import { i as readModelListResult } from "./models-CkowdYbm.js";
5
5
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
6
6
  //#region extensions/codex/media-understanding-provider.ts
7
7
  const DEFAULT_CODEX_IMAGE_MODEL = FALLBACK_CODEX_MODELS.find((model) => model.inputModalities.includes("image"))?.id ?? FALLBACK_CODEX_MODELS[0]?.id;
@@ -37,7 +37,7 @@ async function describeCodexImages(req, options) {
37
37
  const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: options.pluginConfig });
38
38
  const timeoutMs = Math.max(100, req.timeoutMs);
39
39
  const ownsClient = !options.clientFactory;
40
- const client = options.clientFactory ? await options.clientFactory(appServer.start, req.profile) : await import("./shared-client-0El8eRIE.js").then((n) => n.r).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
40
+ const client = options.clientFactory ? await options.clientFactory(appServer.start, req.profile) : await import("./shared-client-Dfk3Enm-.js").then((n) => n.r).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
41
41
  startOptions: appServer.start,
42
42
  timeoutMs,
43
43
  authProfileId: req.profile
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-DUslC3ob.js";
2
- import { o as readCodexModelListResponse } from "./protocol-validators-Cpopom3_.js";
2
+ import { o as readCodexModelListResponse } from "./protocol-validators-Dky2yV4W.js";
3
3
  //#region extensions/codex/src/app-server/models.ts
4
4
  var models_exports = /* @__PURE__ */ __exportAll({
5
5
  listAllCodexAppServerModels: () => listAllCodexAppServerModels,
@@ -39,17 +39,19 @@ async function listAllCodexAppServerModels(options = {}) {
39
39
  async function withCodexAppServerModelClient(options, run) {
40
40
  const timeoutMs = options.timeoutMs ?? 2500;
41
41
  const useSharedClient = options.sharedClient !== false;
42
- const { createIsolatedCodexAppServerClient, getSharedCodexAppServerClient } = await import("./shared-client-0El8eRIE.js").then((n) => n.r);
42
+ const { createIsolatedCodexAppServerClient, getSharedCodexAppServerClient } = await import("./shared-client-Dfk3Enm-.js").then((n) => n.r);
43
43
  const client = useSharedClient ? await getSharedCodexAppServerClient({
44
44
  startOptions: options.startOptions,
45
45
  timeoutMs,
46
46
  authProfileId: options.authProfileId,
47
- agentDir: options.agentDir
47
+ agentDir: options.agentDir,
48
+ config: options.config
48
49
  }) : await createIsolatedCodexAppServerClient({
49
50
  startOptions: options.startOptions,
50
51
  timeoutMs,
51
52
  authProfileId: options.authProfileId,
52
- agentDir: options.agentDir
53
+ agentDir: options.agentDir,
54
+ config: options.config
53
55
  });
54
56
  try {
55
57
  return await run({