@openclaw/codex 2026.5.10-beta.2 → 2026.5.10-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 (25) hide show
  1. package/dist/{client-CTzy3Y6M.js → client-CpksBQ9l.js} +1 -1
  2. package/dist/{client-factory-BJL_efz4.js → client-factory-D2P0KD6r.js} +1 -1
  3. package/dist/{request-DC1Dz3iZ.js → command-formatters-Ttwc_kgX.js} +192 -57
  4. package/dist/{command-handlers-BLZCm3fD.js → command-handlers-iLF1EI-b.js} +306 -15
  5. package/dist/{compact-4FVe6NwI.js → compact-BJ1UYEyA.js} +3 -3
  6. package/dist/{rate-limit-cache-DbZvmrAD.js → computer-use-CVLaKaW3.js} +3 -26
  7. package/dist/{config-CT01BBDc.js → config-C7xdbzrp.js} +1 -1
  8. package/dist/{conversation-binding-FqeYliIk.js → conversation-binding-D4XZ-tvV.js} +5 -4
  9. package/dist/harness.js +8 -4
  10. package/dist/index.js +11 -6
  11. package/dist/media-understanding-provider.js +142 -41
  12. package/dist/{models-H-PTi3W0.js → models-Bg-Qf5s-.js} +2 -2
  13. package/dist/{plugin-activation-CweAZa7r.js → plugin-activation-C0soz2YD.js} +1 -1
  14. package/dist/{protocol-validators-CeCyJaWj.js → protocol-validators-CSY0BFBo.js} +4 -1
  15. package/dist/provider.js +2 -2
  16. package/dist/rate-limit-cache-dvhq-4pi.js +24 -0
  17. package/dist/request-BCAfJvSg.js +41 -0
  18. package/dist/{run-attempt-CefRS5_d.js → run-attempt-DZvighJE.js} +548 -1053
  19. package/dist/{session-binding-B44KIZM2.js → session-binding-UFKjHkKJ.js} +13 -4
  20. package/dist/{shared-client-p-TvEiNL.js → shared-client-K13b0L1X.js} +78 -13
  21. package/dist/side-question-Dh_g53P9.js +548 -0
  22. package/dist/test-api.js +2 -2
  23. package/dist/{thread-lifecycle-CGc-O_5d.js → thread-lifecycle-i42nWiSS.js} +18 -11
  24. package/dist/vision-tools-Bo0P6gwM.js +1008 -0
  25. package/package.json +7 -6
@@ -1,11 +1,294 @@
1
- import { i as isCodexFastServiceTier, s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
2
- import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-H-PTi3W0.js";
1
+ import { i as isCodexFastServiceTier, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
+ import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-Bg-Qf5s-.js";
3
3
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
4
- import { a as formatCodexStatus, c as formatModels, f as CODEX_CONTROL_METHODS, i as formatCodexDisplayText, l as formatThreads, n as buildHelp, o as formatComputerUseStatus, p as describeControlFailure, r as formatAccount, s as formatList, t as requestCodexAppServerJson, u as readString } from "./request-DC1Dz3iZ.js";
5
- import { i as readCodexAppServerBinding, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-B44KIZM2.js";
6
- import { a as parseCodexFastModeArg, c as setCodexConversationFastMode, d as steerCodexConversationTurn, f as stopCodexConversationTurn, i as formatPermissionsMode, l as setCodexConversationModel, m as resolveCodexDefaultWorkspaceDir, o as parseCodexPermissionsModeArg, p as readCodexConversationBindingData, r as startCodexConversationThread, s as readCodexConversationActiveTurn, u as setCodexConversationPermissions } from "./conversation-binding-FqeYliIk.js";
7
- import { a as readCodexComputerUseStatus, i as installCodexComputerUse, n as rememberCodexRateLimits } from "./rate-limit-cache-DbZvmrAD.js";
4
+ import { n as CODEX_CONTROL_METHODS, r as describeControlFailure, t as requestCodexAppServerJson } from "./request-BCAfJvSg.js";
5
+ import { a as formatComputerUseStatus, c as formatThreads, i as formatCodexStatus, l as readString$1, n as formatAccount, o as formatList, p as summarizeCodexAccountUsage, r as formatCodexDisplayText, s as formatModels, t as buildHelp } from "./command-formatters-Ttwc_kgX.js";
6
+ import { i as readCodexAppServerBinding, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-UFKjHkKJ.js";
7
+ import { a as parseCodexFastModeArg, c as setCodexConversationFastMode, d as steerCodexConversationTurn, f as stopCodexConversationTurn, i as formatPermissionsMode, l as setCodexConversationModel, m as resolveCodexDefaultWorkspaceDir, o as parseCodexPermissionsModeArg, p as readCodexConversationBindingData, r as startCodexConversationThread, s as readCodexConversationActiveTurn, u as setCodexConversationPermissions } from "./conversation-binding-D4XZ-tvV.js";
8
+ import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-CVLaKaW3.js";
9
+ import { n as rememberCodexRateLimits } from "./rate-limit-cache-dvhq-4pi.js";
8
10
  import crypto from "node:crypto";
11
+ import { ensureAuthProfileStore, findNormalizedProviderValue, resolveAuthProfileEligibility, resolveAuthProfileOrder, resolveDefaultAgentDir, resolveProfileUnusableUntilForDisplay } from "openclaw/plugin-sdk/agent-runtime";
12
+ //#region extensions/codex/src/command-account.ts
13
+ const OPENAI_PROVIDER_ID = "openai";
14
+ const OPENAI_CODEX_PROVIDER_ID = "openai-codex";
15
+ async function readCodexAccountAuthOverview(params) {
16
+ const config = params.ctx.config;
17
+ const store = ensureAuthProfileStore(resolveDefaultAgentDir(config), {
18
+ allowKeychainPrompt: false,
19
+ config
20
+ });
21
+ const order = resolveDisplayAuthOrder({
22
+ config,
23
+ store
24
+ });
25
+ if (order.length === 0) return;
26
+ const now = Date.now();
27
+ const activeProfileId = resolveActiveProfileId({
28
+ store,
29
+ order,
30
+ config,
31
+ account: params.account,
32
+ limits: params.limits,
33
+ now
34
+ });
35
+ const subscriptionProfileId = order.find((profileId) => isChatGptSubscriptionProfile(store.profiles[profileId]));
36
+ const activeIsSubscription = activeProfileId !== void 0 && isChatGptSubscriptionProfile(store.profiles[activeProfileId]);
37
+ const activeUsage = activeIsSubscription && params.limits.ok ? summarizeCodexAccountUsage(params.limits.value, now) : void 0;
38
+ const subscriptionUsage = subscriptionProfileId && (!activeIsSubscription || subscriptionProfileId !== activeProfileId) ? await readSubscriptionUsage({
39
+ ...params,
40
+ config,
41
+ subscriptionProfileId,
42
+ now
43
+ }) : activeUsage;
44
+ if (!params.account.ok && !params.limits.ok && !subscriptionUsage) return;
45
+ const rows = order.map((profileId, index) => buildProfileRow({
46
+ store,
47
+ config,
48
+ profileId,
49
+ activeProfileId,
50
+ activeIndex: activeProfileId ? order.indexOf(activeProfileId) : -1,
51
+ index,
52
+ now,
53
+ usage: profileId === subscriptionProfileId ? subscriptionUsage : void 0
54
+ }));
55
+ const activeRow = rows.find((row) => row.active);
56
+ if (!activeRow) return {
57
+ currentLine: "OpenAI credentials: no working credential",
58
+ orderTitle: "Auth order",
59
+ rows
60
+ };
61
+ const activeIsApiKey = store.profiles[activeRow.profileId]?.type === "api_key";
62
+ const subscriptionLabel = subscriptionProfileId ? formatProfileLabel(subscriptionProfileId, store.profiles[subscriptionProfileId]) : activeIsSubscription ? activeRow.label : void 0;
63
+ const subscriptionUsageLine = formatSubscriptionUsageLine(subscriptionUsage);
64
+ return {
65
+ ...activeIsApiKey ? { currentLine: buildApiKeyActiveLine(activeRow, subscriptionUsage) } : {},
66
+ ...subscriptionLabel ? { subscriptionLabel } : {},
67
+ ...subscriptionUsageLine ? { subscriptionUsage: subscriptionUsageLine } : {},
68
+ orderTitle: "Auth order",
69
+ rows
70
+ };
71
+ }
72
+ function resolveDisplayAuthOrder(params) {
73
+ const codexOrder = resolveOrder(params.store.order, OPENAI_CODEX_PROVIDER_ID) ?? resolveOrder(params.config?.auth?.order, OPENAI_CODEX_PROVIDER_ID);
74
+ if (codexOrder && codexOrder.length > 0) return dedupe(codexOrder);
75
+ return resolveAuthProfileOrder({
76
+ cfg: params.config,
77
+ store: params.store,
78
+ provider: OPENAI_CODEX_PROVIDER_ID
79
+ });
80
+ }
81
+ function resolveOrder(order, provider) {
82
+ return findNormalizedProviderValue(order, provider);
83
+ }
84
+ function resolveActiveProfileId(params) {
85
+ const liveProfileId = resolveLiveAccountProfileId({
86
+ account: params.account,
87
+ store: params.store,
88
+ order: params.order
89
+ });
90
+ if (liveProfileId) return liveProfileId;
91
+ const lastGood = [params.store.lastGood?.[OPENAI_PROVIDER_ID], params.store.lastGood?.[OPENAI_CODEX_PROVIDER_ID]].find((profileId) => !!profileId && params.order.includes(profileId) && isActiveProfileCandidate(params, profileId));
92
+ if (lastGood) return lastGood;
93
+ const mostRecent = params.order.map((profileId) => ({
94
+ profileId,
95
+ lastUsed: params.store.usageStats?.[profileId]?.lastUsed ?? 0
96
+ })).filter((entry) => entry.lastUsed > 0 && isActiveProfileCandidate(params, entry.profileId)).toSorted((left, right) => right.lastUsed - left.lastUsed)[0]?.profileId;
97
+ if (mostRecent) return mostRecent;
98
+ if (shouldInferApiKeyActiveFromRateLimitProbe(params.limits)) {
99
+ const apiKeyProfile = params.order.find((profileId) => params.store.profiles[profileId]?.type === "api_key");
100
+ if (apiKeyProfile) return apiKeyProfile;
101
+ }
102
+ return resolveAuthProfileOrder({
103
+ cfg: params.config,
104
+ store: params.store,
105
+ provider: OPENAI_CODEX_PROVIDER_ID
106
+ })[0];
107
+ }
108
+ function isActiveProfileCandidate(params, profileId) {
109
+ return !isActiveUntil(resolveProfileUnusableUntilForDisplay(params.store, profileId) ?? void 0, params.now);
110
+ }
111
+ function resolveLiveAccountProfileId(params) {
112
+ if (!params.account.ok || !isJsonObject(params.account.value)) return;
113
+ const account = isJsonObject(params.account.value.account) ? params.account.value.account : params.account.value;
114
+ const type = readString(account, "type")?.toLowerCase();
115
+ if (type === "chatgpt") {
116
+ const email = readString(account, "email")?.toLowerCase();
117
+ const firstSubscription = params.order.find((profileId) => isChatGptSubscriptionProfile(params.store.profiles[profileId]));
118
+ if (!email) return firstSubscription;
119
+ return params.order.find((profileId) => {
120
+ const credential = params.store.profiles[profileId];
121
+ if (!isChatGptSubscriptionProfile(credential)) return false;
122
+ return (credential.email?.trim().toLowerCase() ?? extractEmailFromProfileId(profileId))?.toLowerCase() === email;
123
+ }) ?? firstSubscription;
124
+ }
125
+ if (type === "apikey" || type === "api_key") return params.order.find((profileId) => params.store.profiles[profileId]?.type === "api_key");
126
+ }
127
+ function shouldInferApiKeyActiveFromRateLimitProbe(limits) {
128
+ return !limits.ok && limits.error.toLowerCase().includes("chatgpt authentication required");
129
+ }
130
+ async function readSubscriptionUsage(params) {
131
+ const limits = await params.safeCodexControlRequest(params.pluginConfig, CODEX_CONTROL_METHODS.rateLimits, void 0, {
132
+ config: params.config,
133
+ authProfileId: params.subscriptionProfileId,
134
+ isolated: true
135
+ });
136
+ if (!limits.ok) return;
137
+ rememberCodexRateLimits(limits.value);
138
+ return summarizeCodexAccountUsage(limits.value, params.now);
139
+ }
140
+ function buildProfileRow(params) {
141
+ const credential = params.store.profiles[params.profileId];
142
+ const label = formatProfileLabel(params.profileId, credential);
143
+ const kind = formatProfileKind(credential);
144
+ const active = params.profileId === params.activeProfileId;
145
+ const status = active ? "active now" : params.usage?.blocked ? formatUsageBlockedStatus(params.usage) : describeInactiveProfileStatus({
146
+ store: params.store,
147
+ config: params.config,
148
+ profileId: params.profileId,
149
+ credential,
150
+ now: params.now,
151
+ afterActive: params.activeIndex >= 0 && params.index > params.activeIndex
152
+ });
153
+ return {
154
+ profileId: params.profileId,
155
+ label,
156
+ kind,
157
+ status,
158
+ active,
159
+ ...credential?.type === "api_key" && active ? { billingNote: "billed per token" } : {},
160
+ ...params.usage?.usageLine ? { usage: params.usage.usageLine } : {}
161
+ };
162
+ }
163
+ function formatUsageBlockedStatus(usage) {
164
+ return usage.blocked ? "rate-limited" : "available if needed";
165
+ }
166
+ function describeInactiveProfileStatus(params) {
167
+ const stats = params.store.usageStats?.[params.profileId];
168
+ const blockedUntil = stats?.blockedUntil;
169
+ if (isActiveUntil(blockedUntil, params.now)) return `rate-limited - resets ${formatRelativeReset(blockedUntil, params.now)}`;
170
+ if (isActiveUntil(resolveProfileUnusableUntilForDisplay(params.store, params.profileId) ?? void 0, params.now)) return describeFailureStatus(stats?.disabledReason ?? stats?.cooldownReason, params.credential);
171
+ const eligibility = resolveAuthProfileEligibility({
172
+ cfg: params.config,
173
+ store: params.store,
174
+ provider: OPENAI_CODEX_PROVIDER_ID,
175
+ profileId: params.profileId,
176
+ now: params.now
177
+ });
178
+ if (!eligibility.eligible) return describeEligibilityStatus(eligibility.reasonCode, params.credential);
179
+ return "available if needed";
180
+ }
181
+ function buildApiKeyActiveLine(activeRow, subscriptionUsage) {
182
+ if (subscriptionUsage?.blocked) {
183
+ const switchBack = subscriptionUsage.blockedResetRelative ? ` · switches back ${subscriptionUsage.blockedResetRelative}` : " · switches back automatically";
184
+ return `Now using: ${activeRow.label} - subscription rate-limited${switchBack}`;
185
+ }
186
+ return `Now using: ${activeRow.label} - subscription unavailable · switches back automatically`;
187
+ }
188
+ function formatSubscriptionUsageLine(usage) {
189
+ if (!usage) return;
190
+ const parts = usage.usageLine ? [formatUsageLineForDisplay(usage.usageLine)] : [];
191
+ if (usage.blockedResetRelative) parts.push(`Resets ${usage.blockedResetRelative}`);
192
+ return parts.length > 0 ? parts.join(" · ") : void 0;
193
+ }
194
+ function formatUsageLineForDisplay(value) {
195
+ return value.replace(/^weekly\b/u, "Weekly").replace(/\bshort-term\b/u, "Short-term");
196
+ }
197
+ function readString(record, key) {
198
+ const value = record[key];
199
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
200
+ }
201
+ function isChatGptSubscriptionProfile(credential) {
202
+ return credential?.type === "oauth" || credential?.type === "token";
203
+ }
204
+ function formatProfileKind(credential) {
205
+ if (!credential) return "credential";
206
+ if (isChatGptSubscriptionProfile(credential)) return "ChatGPT subscription";
207
+ if (credential.type === "api_key") return "API key";
208
+ return "credential";
209
+ }
210
+ function formatProfileLabel(profileId, credential) {
211
+ const tail = profileId.includes(":") ? profileId.slice(profileId.indexOf(":") + 1) : profileId;
212
+ const displayName = credential?.displayName?.trim();
213
+ if (displayName) return credential?.type === "api_key" ? simplifyApiKeyDisplayName(displayName, tail) : displayName;
214
+ const email = credential?.email?.trim() ?? extractEmailFromProfileId(profileId);
215
+ if (email) return email;
216
+ if (credential?.type === "api_key") return tail || "API key";
217
+ return humanizeProfileTail(tail);
218
+ }
219
+ function simplifyApiKeyDisplayName(value, tail) {
220
+ const stripped = value.replace(/^OpenAI\s+/iu, "").trim();
221
+ if (tail && stripped.toLowerCase() === humanizeApiKeyProfileTail(tail).toLowerCase()) return tail;
222
+ return stripped || value;
223
+ }
224
+ function humanizeApiKeyProfileTail(tail) {
225
+ const words = splitProfileTail(tail);
226
+ const hasBackup = words.includes("backup");
227
+ return [
228
+ words.filter((word) => word !== "api" && word !== "key" && word !== "backup").map(titleCase).join(" "),
229
+ "API key",
230
+ hasBackup ? "backup" : ""
231
+ ].filter(Boolean).join(" ");
232
+ }
233
+ function humanizeProfileTail(tail) {
234
+ const words = splitProfileTail(tail);
235
+ return words.length > 0 ? words.map(titleCase).join(" ") : tail;
236
+ }
237
+ function splitProfileTail(tail) {
238
+ return tail.replace(/[_\s]+/gu, "-").split("-").map((word) => word.trim().toLowerCase()).filter(Boolean);
239
+ }
240
+ function titleCase(value) {
241
+ return value ? `${value[0]?.toUpperCase() ?? ""}${value.slice(1)}` : value;
242
+ }
243
+ function extractEmailFromProfileId(profileId) {
244
+ const tail = profileId.includes(":") ? profileId.slice(profileId.indexOf(":") + 1) : profileId;
245
+ return /^[^\s@<>()[\]`]+@[^\s@<>()[\]`]+\.[^\s@<>()[\]`]+$/.test(tail) ? tail : void 0;
246
+ }
247
+ function describeFailureStatus(reason, credential) {
248
+ if (reason === "auth" || reason === "auth_permanent" || reason === "session_expired") return credential?.type === "api_key" ? "auth failed - check key" : "sign-in expired";
249
+ if (reason === "billing") return "billing unavailable";
250
+ if (reason === "rate_limit") return "rate-limited";
251
+ return "temporarily unavailable";
252
+ }
253
+ function describeEligibilityStatus(reason, credential) {
254
+ if (reason === "profile_missing" || reason === "missing_credential") return credential?.type === "api_key" ? "not configured" : "sign-in required";
255
+ if (reason === "expired" || reason === "invalid_expires") return "sign-in expired";
256
+ if (reason === "unresolved_ref") return "credential unavailable";
257
+ if (reason === "provider_mismatch") return "wrong provider";
258
+ if (reason === "mode_mismatch") return "wrong credential type";
259
+ return "unavailable";
260
+ }
261
+ function isActiveUntil(value, now) {
262
+ return typeof value === "number" && Number.isFinite(value) && value > now;
263
+ }
264
+ function formatRelativeReset(untilMs, nowMs) {
265
+ const durationMs = Math.max(1e3, untilMs - nowMs);
266
+ const minuteMs = 6e4;
267
+ const hourMs = 60 * minuteMs;
268
+ const dayMs = 24 * hourMs;
269
+ if (durationMs < hourMs) {
270
+ const minutes = Math.ceil(durationMs / minuteMs);
271
+ return `in ${minutes} ${minutes === 1 ? "minute" : "minutes"}`;
272
+ }
273
+ if (durationMs < dayMs) {
274
+ const hours = Math.ceil(durationMs / hourMs);
275
+ return `in ${hours} ${hours === 1 ? "hour" : "hours"}`;
276
+ }
277
+ const days = Math.ceil(durationMs / dayMs);
278
+ return `in ${days} ${days === 1 ? "day" : "days"}`;
279
+ }
280
+ function dedupe(values) {
281
+ const seen = /* @__PURE__ */ new Set();
282
+ const result = [];
283
+ for (const value of values) {
284
+ const trimmed = value.trim();
285
+ if (!trimmed || seen.has(trimmed)) continue;
286
+ seen.add(trimmed);
287
+ result.push(trimmed);
288
+ }
289
+ return result;
290
+ }
291
+ //#endregion
9
292
  //#region extensions/codex/src/command-rpc.ts
10
293
  function requestOptions(pluginConfig, limit, config) {
11
294
  const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig });
@@ -23,7 +306,9 @@ async function codexControlRequest(pluginConfig, method, requestParams, options
23
306
  requestParams,
24
307
  timeoutMs: runtime.requestTimeoutMs,
25
308
  startOptions: runtime.start,
26
- config: options.config
309
+ config: options.config,
310
+ authProfileId: options.authProfileId,
311
+ isolated: options.isolated
27
312
  });
28
313
  }
29
314
  async function safeCodexControlRequest(pluginConfig, method, requestParams, options = {}) {
@@ -149,7 +434,13 @@ async function handleCodexSubcommand(ctx, options) {
149
434
  if (rest.length > 0) return { text: "Usage: /codex account" };
150
435
  const [account, limits] = await Promise.all([deps.safeCodexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.account, { refreshToken: false }), deps.safeCodexControlRequest(options.pluginConfig, CODEX_CONTROL_METHODS.rateLimits, void 0)]);
151
436
  if (limits.ok) rememberCodexRateLimits(limits.value);
152
- return { text: formatAccount(account, limits) };
437
+ return { text: formatAccount(account, limits, await readCodexAccountAuthOverview({
438
+ ctx,
439
+ pluginConfig: options.pluginConfig,
440
+ safeCodexControlRequest: deps.safeCodexControlRequest,
441
+ account,
442
+ limits
443
+ })) };
153
444
  }
154
445
  return { text: `Unknown Codex command: ${formatCodexDisplayText(subcommand)}\n\n${buildHelp()}` };
155
446
  }
@@ -239,12 +530,12 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
239
530
  persistExtendedHistory: true
240
531
  });
241
532
  const thread = isJsonObject(response) && isJsonObject(response.thread) ? response.thread : {};
242
- const effectiveThreadId = readString(thread, "id") ?? normalizedThreadId;
533
+ const effectiveThreadId = readString$1(thread, "id") ?? normalizedThreadId;
243
534
  await deps.writeCodexAppServerBinding(ctx.sessionFile, {
244
535
  threadId: effectiveThreadId,
245
- cwd: readString(thread, "cwd") ?? "",
246
- model: isJsonObject(response) ? readString(response, "model") : void 0,
247
- modelProvider: isJsonObject(response) ? readString(response, "modelProvider") : void 0
536
+ cwd: readString$1(thread, "cwd") ?? "",
537
+ model: isJsonObject(response) ? readString$1(response, "model") : void 0,
538
+ modelProvider: isJsonObject(response) ? readString$1(response, "modelProvider") : void 0
248
539
  });
249
540
  return `Attached this OpenClaw session to Codex thread ${formatCodexDisplayText(effectiveThreadId)}.`;
250
541
  }
@@ -318,9 +609,9 @@ async function handleCodexDiagnosticsFeedback(deps, ctx, pluginConfig, args, com
318
609
  if (parsed.action === "cancel") return { text: cancelCodexDiagnosticsFeedback(ctx, parsed.token) };
319
610
  if (ctx.diagnosticsUploadApproved === true) return { text: await sendCodexDiagnosticsFeedbackForContext(deps, ctx, pluginConfig, parsed.note) };
320
611
  if (ctx.diagnosticsPreviewOnly === true) return { text: await previewCodexDiagnosticsFeedbackApproval(deps, ctx, parsed.note) };
321
- return await requestCodexDiagnosticsFeedbackApproval(deps, ctx, pluginConfig, parsed.note, commandPrefix);
612
+ return await requestCodexDiagnosticsFeedbackApproval(deps, ctx, parsed.note, commandPrefix);
322
613
  }
323
- async function requestCodexDiagnosticsFeedbackApproval(deps, ctx, pluginConfig, note, commandPrefix) {
614
+ async function requestCodexDiagnosticsFeedbackApproval(deps, ctx, note, commandPrefix) {
324
615
  if (!await hasAnyCodexDiagnosticsSessionFile(ctx)) return { text: "Cannot send Codex diagnostics because this command did not include an OpenClaw session file." };
325
616
  const targets = await resolveCodexDiagnosticsTargets(deps, ctx);
326
617
  if (targets.length === 0) return { text: ["No Codex thread is attached to this OpenClaw session yet.", "Use /codex threads to find a thread, then /codex resume <thread-id> before sending diagnostics."].join("\n") };
@@ -442,7 +733,7 @@ async function sendCodexDiagnosticsFeedbackForTargets(deps, ctx, pluginConfig, n
442
733
  });
443
734
  continue;
444
735
  }
445
- const responseThreadId = isJsonObject(response.value) ? readString(response.value, "threadId") : void 0;
736
+ const responseThreadId = isJsonObject(response.value) ? readString$1(response.value, "threadId") : void 0;
446
737
  sent.push({
447
738
  ...target,
448
739
  threadId: responseThreadId ?? target.threadId
@@ -1,7 +1,7 @@
1
- import { s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
1
+ import { s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
2
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
3
- import { i as readCodexAppServerBinding } from "./session-binding-B44KIZM2.js";
4
- import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory-BJL_efz4.js";
3
+ import { i as readCodexAppServerBinding } from "./session-binding-UFKjHkKJ.js";
4
+ import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory-D2P0KD6r.js";
5
5
  import { embeddedAgentLog, formatErrorMessage, isActiveHarnessContextEngine, runHarnessContextEngineMaintenance } from "openclaw/plugin-sdk/agent-harness-runtime";
6
6
  //#region extensions/codex/src/app-server/compact.ts
7
7
  const DEFAULT_CODEX_COMPACTION_WAIT_TIMEOUT_MS = 300 * 1e3;
@@ -1,5 +1,5 @@
1
- import { c as resolveCodexComputerUseConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
2
- import { p as describeControlFailure, t as requestCodexAppServerJson } from "./request-DC1Dz3iZ.js";
1
+ import { c as resolveCodexComputerUseConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
+ import { r as describeControlFailure, t as requestCodexAppServerJson } from "./request-BCAfJvSg.js";
3
3
  import { existsSync } from "node:fs";
4
4
  //#region extensions/codex/src/app-server/computer-use.ts
5
5
  var CodexComputerUseSetupError = class extends Error {
@@ -364,27 +364,4 @@ function resolveComputerUseConfig(params) {
364
364
  });
365
365
  }
366
366
  //#endregion
367
- //#region extensions/codex/src/app-server/rate-limit-cache.ts
368
- const DEFAULT_CODEX_RATE_LIMIT_CACHE_MAX_AGE_MS = 10 * 6e4;
369
- const CODEX_RATE_LIMIT_CACHE_STATE = Symbol.for("openclaw.codexRateLimitCacheState");
370
- function getCodexRateLimitCacheState() {
371
- const globalState = globalThis;
372
- globalState[CODEX_RATE_LIMIT_CACHE_STATE] ??= {};
373
- return globalState[CODEX_RATE_LIMIT_CACHE_STATE];
374
- }
375
- function rememberCodexRateLimits(value, nowMs = Date.now()) {
376
- if (value === void 0) return;
377
- const state = getCodexRateLimitCacheState();
378
- state.value = value;
379
- state.updatedAtMs = nowMs;
380
- }
381
- function readRecentCodexRateLimits(options) {
382
- const state = getCodexRateLimitCacheState();
383
- if (state.value === void 0 || state.updatedAtMs === void 0) return;
384
- const nowMs = options?.nowMs ?? Date.now();
385
- const maxAgeMs = options?.maxAgeMs ?? DEFAULT_CODEX_RATE_LIMIT_CACHE_MAX_AGE_MS;
386
- if (maxAgeMs >= 0 && nowMs - state.updatedAtMs > maxAgeMs) return;
387
- return state.value;
388
- }
389
- //#endregion
390
- export { readCodexComputerUseStatus as a, installCodexComputerUse as i, rememberCodexRateLimits as n, ensureCodexComputerUse as r, readRecentCodexRateLimits as t };
367
+ export { installCodexComputerUse as n, readCodexComputerUseStatus as r, ensureCodexComputerUse as t };
@@ -1,7 +1,7 @@
1
1
  import { createHmac, randomBytes } from "node:crypto";
2
2
  import { readFileSync } from "node:fs";
3
3
  import { hostname } from "node:os";
4
- import { z } from "openclaw/plugin-sdk/zod";
4
+ import { z } from "zod";
5
5
  //#region extensions/codex/src/app-server/config.ts
6
6
  const START_OPTIONS_KEY_SECRET = randomBytes(32);
7
7
  const UNIX_CODEX_REQUIREMENTS_PATH = "/etc/codex/requirements.toml";
@@ -1,8 +1,9 @@
1
- import { i as isCodexFastServiceTier, r as codexSandboxPolicyForTurn, s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
1
+ import { i as isCodexFastServiceTier, r as codexSandboxPolicyForTurn, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
2
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
3
- import { f as CODEX_CONTROL_METHODS, i as formatCodexDisplayText } from "./request-DC1Dz3iZ.js";
4
- import { c as resolveCodexAppServerAuthProfileIdForAgent, n as getSharedCodexAppServerClient } from "./shared-client-p-TvEiNL.js";
5
- import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, r as normalizeCodexAppServerBindingModelProvider, t as clearCodexAppServerBinding } from "./session-binding-B44KIZM2.js";
3
+ import { n as CODEX_CONTROL_METHODS } from "./request-BCAfJvSg.js";
4
+ import { r as formatCodexDisplayText } from "./command-formatters-Ttwc_kgX.js";
5
+ import { l as resolveCodexAppServerAuthProfileIdForAgent, r as getSharedCodexAppServerClient } from "./shared-client-K13b0L1X.js";
6
+ import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, r as normalizeCodexAppServerBindingModelProvider, t as clearCodexAppServerBinding } from "./session-binding-UFKjHkKJ.js";
6
7
  import { formatErrorMessage } from "openclaw/plugin-sdk/agent-harness-runtime";
7
8
  import path from "node:path";
8
9
  import { fileURLToPath } from "node:url";
package/dist/harness.js CHANGED
@@ -18,21 +18,25 @@ function createCodexAppServerAgentHarness(options) {
18
18
  };
19
19
  },
20
20
  runAttempt: async (params) => {
21
- const { runCodexAppServerAttempt } = await import("./run-attempt-CefRS5_d.js");
21
+ const { runCodexAppServerAttempt } = await import("./run-attempt-DZvighJE.js");
22
22
  return runCodexAppServerAttempt(params, { pluginConfig: options?.pluginConfig });
23
23
  },
24
+ runSideQuestion: async (params) => {
25
+ const { runCodexAppServerSideQuestion } = await import("./side-question-Dh_g53P9.js");
26
+ return runCodexAppServerSideQuestion(params, { pluginConfig: options?.pluginConfig });
27
+ },
24
28
  compact: async (params) => {
25
- const { maybeCompactCodexAppServerSession } = await import("./compact-4FVe6NwI.js");
29
+ const { maybeCompactCodexAppServerSession } = await import("./compact-BJ1UYEyA.js");
26
30
  return maybeCompactCodexAppServerSession(params, { pluginConfig: options?.pluginConfig });
27
31
  },
28
32
  reset: async (params) => {
29
33
  if (params.sessionFile) {
30
- const { clearCodexAppServerBinding } = await import("./session-binding-B44KIZM2.js").then((n) => n.a);
34
+ const { clearCodexAppServerBinding } = await import("./session-binding-UFKjHkKJ.js").then((n) => n.a);
31
35
  await clearCodexAppServerBinding(params.sessionFile);
32
36
  }
33
37
  },
34
38
  dispose: async () => {
35
- const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-p-TvEiNL.js").then((n) => n.r);
39
+ const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-K13b0L1X.js").then((n) => n.i);
36
40
  await clearSharedCodexAppServerClientAndWait();
37
41
  }
38
42
  };
package/dist/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { createCodexAppServerAgentHarness } from "./harness.js";
2
- import { t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-CT01BBDc.js";
2
+ import { t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-C7xdbzrp.js";
3
3
  import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
4
4
  import { buildCodexProvider } from "./provider.js";
5
- import { i as formatCodexDisplayText, p as describeControlFailure, t as requestCodexAppServerJson } from "./request-DC1Dz3iZ.js";
6
- import { n as handleCodexConversationInboundClaim, t as handleCodexConversationBindingResolved } from "./conversation-binding-FqeYliIk.js";
7
- import { i as defaultCodexAppInventoryCache, t as ensureCodexPluginActivation } from "./plugin-activation-CweAZa7r.js";
5
+ import { r as describeControlFailure, t as requestCodexAppServerJson } from "./request-BCAfJvSg.js";
6
+ import { r as formatCodexDisplayText } from "./command-formatters-Ttwc_kgX.js";
7
+ import { n as handleCodexConversationInboundClaim, t as handleCodexConversationBindingResolved } from "./conversation-binding-D4XZ-tvV.js";
8
+ import { i as defaultCodexAppInventoryCache, t as ensureCodexPluginActivation } from "./plugin-activation-C0soz2YD.js";
8
9
  import { resolveLivePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
9
10
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
10
11
  import os from "node:os";
@@ -28,13 +29,17 @@ function createCodexCommand(options) {
28
29
  };
29
30
  }
30
31
  async function handleCodexCommand(ctx, options = {}) {
31
- const { handleCodexSubcommand } = await import("./command-handlers-BLZCm3fD.js");
32
+ const { loadSubcommandHandler, ...subcommandOptions } = options;
32
33
  try {
33
- return await handleCodexSubcommand(ctx, options);
34
+ return await (loadSubcommandHandler ? await loadSubcommandHandler() : await loadDefaultCodexSubcommandHandler())(ctx, subcommandOptions);
34
35
  } catch (error) {
35
36
  return { text: `Codex command failed: ${formatCodexDisplayText(describeControlFailure(error))}` };
36
37
  }
37
38
  }
39
+ async function loadDefaultCodexSubcommandHandler() {
40
+ const { handleCodexSubcommand } = await import("./command-handlers-iLF1EI-b.js");
41
+ return handleCodexSubcommand;
42
+ }
38
43
  //#endregion
39
44
  //#region extensions/codex/src/migration/helpers.ts
40
45
  async function exists(filePath) {