@openclaw/codex 2026.5.10-beta.3 → 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.
- package/dist/{client-factory-BHbKz0nI.js → client-factory-D2P0KD6r.js} +1 -1
- package/dist/{request-Bj4IRDU9.js → command-formatters-Ttwc_kgX.js} +87 -51
- package/dist/{command-handlers-BPaLMsgL.js → command-handlers-iLF1EI-b.js} +303 -12
- package/dist/{compact-CMIpm-H_.js → compact-BJ1UYEyA.js} +2 -2
- package/dist/{rate-limit-cache-BFTJlMhx.js → computer-use-CVLaKaW3.js} +2 -25
- package/dist/{conversation-binding-zeuTIuN2.js → conversation-binding-D4XZ-tvV.js} +4 -3
- package/dist/harness.js +8 -4
- package/dist/index.js +5 -4
- package/dist/media-understanding-provider.js +3 -3
- package/dist/{models-lvthKXfT.js → models-Bg-Qf5s-.js} +2 -2
- package/dist/{protocol-validators-CeCyJaWj.js → protocol-validators-CSY0BFBo.js} +4 -1
- package/dist/provider.js +1 -1
- package/dist/rate-limit-cache-dvhq-4pi.js +24 -0
- package/dist/request-BCAfJvSg.js +41 -0
- package/dist/{run-attempt-COMElKgN.js → run-attempt-DZvighJE.js} +297 -1039
- package/dist/{session-binding-BAaJ-7s-.js → session-binding-UFKjHkKJ.js} +12 -3
- package/dist/{shared-client-BRX9tReb.js → shared-client-K13b0L1X.js} +76 -11
- package/dist/side-question-Dh_g53P9.js +548 -0
- package/dist/test-api.js +1 -1
- package/dist/{thread-lifecycle-DRyCVHhL.js → thread-lifecycle-i42nWiSS.js} +5 -5
- package/dist/vision-tools-Bo0P6gwM.js +1008 -0
- package/package.json +5 -5
- /package/dist/{plugin-activation-Dn14PX1W.js → plugin-activation-C0soz2YD.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region extensions/codex/src/app-server/client-factory.ts
|
|
2
|
-
const defaultCodexAppServerClientFactory = (startOptions, authProfileId, agentDir, config) => import("./shared-client-
|
|
2
|
+
const defaultCodexAppServerClientFactory = (startOptions, authProfileId, agentDir, config) => import("./shared-client-K13b0L1X.js").then((n) => n.i).then(({ getSharedCodexAppServerClient }) => getSharedCodexAppServerClient({
|
|
3
3
|
startOptions,
|
|
4
4
|
authProfileId,
|
|
5
5
|
agentDir,
|
|
@@ -1,26 +1,4 @@
|
|
|
1
1
|
import { t as isJsonObject } from "./protocol-C9UWI98H.js";
|
|
2
|
-
import { n as CodexAppServerRpcError } from "./client-CpksBQ9l.js";
|
|
3
|
-
import { i as withTimeout, n as getSharedCodexAppServerClient } from "./shared-client-BRX9tReb.js";
|
|
4
|
-
//#region extensions/codex/src/app-server/capabilities.ts
|
|
5
|
-
const CODEX_CONTROL_METHODS = {
|
|
6
|
-
account: "account/read",
|
|
7
|
-
compact: "thread/compact/start",
|
|
8
|
-
feedback: "feedback/upload",
|
|
9
|
-
listMcpServers: "mcpServerStatus/list",
|
|
10
|
-
listSkills: "skills/list",
|
|
11
|
-
listThreads: "thread/list",
|
|
12
|
-
rateLimits: "account/rateLimits/read",
|
|
13
|
-
resumeThread: "thread/resume",
|
|
14
|
-
review: "review/start"
|
|
15
|
-
};
|
|
16
|
-
function describeControlFailure(error) {
|
|
17
|
-
if (isUnsupportedControlError(error)) return "unsupported by this Codex app-server";
|
|
18
|
-
return error instanceof Error ? error.message : String(error);
|
|
19
|
-
}
|
|
20
|
-
function isUnsupportedControlError(error) {
|
|
21
|
-
return error instanceof CodexAppServerRpcError && error.code === -32601;
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
2
|
//#region extensions/codex/src/app-server/rate-limits.ts
|
|
25
3
|
const CODEX_LIMIT_ID = "codex";
|
|
26
4
|
const LIMIT_WINDOW_KEYS = ["primary", "secondary"];
|
|
@@ -52,13 +30,34 @@ function summarizeCodexRateLimits(value, nowMs = Date.now()) {
|
|
|
52
30
|
return snapshots.slice(0, 4).map((snapshot) => summarizeRateLimitSnapshot(snapshot, nowMs)).join("; ");
|
|
53
31
|
}
|
|
54
32
|
function summarizeCodexAccountRateLimits(value, nowMs = Date.now()) {
|
|
33
|
+
const summary = summarizeCodexAccountUsage(value, nowMs);
|
|
34
|
+
if (!summary) return;
|
|
35
|
+
if (!summary.blocked) return ["Codex is available."];
|
|
36
|
+
return [summary.blockedUntilText ? `Codex is paused until ${summary.blockedUntilText}.` : "Codex is paused by a usage limit.", summary.blockingReason ? `Your ${summary.blockingReason}.` : "Your Codex usage limit is reached."];
|
|
37
|
+
}
|
|
38
|
+
function resolveCodexUsageLimitResetAtMs(value, nowMs = Date.now()) {
|
|
39
|
+
return selectBlockingRateLimitReset(value, nowMs)?.resetsAtMs;
|
|
40
|
+
}
|
|
41
|
+
function summarizeCodexAccountUsage(value, nowMs = Date.now()) {
|
|
55
42
|
const snapshots = collectCodexRateLimitSnapshots(value);
|
|
56
43
|
if (snapshots.length === 0) return;
|
|
44
|
+
const usageSnapshot = snapshots.find(isCodexLimitSnapshot) ?? snapshots[0];
|
|
57
45
|
const blockedSnapshots = snapshots.filter(snapshotHasLimitBlock);
|
|
58
46
|
const blockingSnapshot = blockedSnapshots.find(isCodexLimitSnapshot) ?? blockedSnapshots[0] ?? void 0;
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
47
|
+
const blockingReset = blockingSnapshot ? selectSnapshotBlockingReset(blockingSnapshot, nowMs) : void 0;
|
|
48
|
+
const blockingPeriod = formatBlockingLimitPeriod(blockingReset?.windowDurationMins);
|
|
49
|
+
const blockedUntilText = blockingReset ? formatAccountResetTime(blockingReset.resetsAtMs, nowMs) : void 0;
|
|
50
|
+
const blockedResetRelative = blockingReset ? `in ${formatRelativeDuration(blockingReset.resetsAtMs - nowMs)}` : void 0;
|
|
51
|
+
const blockingReason = blockingPeriod ? `${blockingPeriod} Codex usage limit is reached` : blockingSnapshot ? "Codex usage limit is reached" : void 0;
|
|
52
|
+
return {
|
|
53
|
+
usageLine: formatUsageLine(usageSnapshot),
|
|
54
|
+
blocked: Boolean(blockingSnapshot),
|
|
55
|
+
...blockingReset ? { blockedUntilMs: blockingReset.resetsAtMs } : {},
|
|
56
|
+
...blockedUntilText ? { blockedUntilText } : {},
|
|
57
|
+
...blockedResetRelative ? { blockedResetRelative } : {},
|
|
58
|
+
...blockingPeriod ? { blockingPeriod } : {},
|
|
59
|
+
...blockingReason ? { blockingReason } : {}
|
|
60
|
+
};
|
|
62
61
|
}
|
|
63
62
|
function isCodexUsageLimitError(codexErrorInfo, message) {
|
|
64
63
|
if (codexErrorInfo === "usageLimitExceeded") return true;
|
|
@@ -71,9 +70,12 @@ function selectNextRateLimitReset(value, nowMs) {
|
|
|
71
70
|
const futureWindows = collectCodexRateLimitSnapshots(value).flatMap((snapshot) => LIMIT_WINDOW_KEYS.flatMap((key) => readRateLimitWindow(snapshot, key) ?? [])).filter((window) => window.resetsAtMs > nowMs);
|
|
72
71
|
if (futureWindows.length === 0) return;
|
|
73
72
|
const exhaustedWindows = futureWindows.filter((window) => window.usedPercent !== void 0 && window.usedPercent >= 100);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
return (exhaustedWindows.length > 0 ? exhaustedWindows : futureWindows).toSorted((left, right) => left.resetsAtMs - right.resetsAtMs)[0];
|
|
74
|
+
}
|
|
75
|
+
function selectBlockingRateLimitReset(value, nowMs) {
|
|
76
|
+
const blockedSnapshots = collectCodexRateLimitSnapshots(value).filter(snapshotHasLimitBlock);
|
|
77
|
+
const blockingSnapshot = blockedSnapshots.find(isCodexLimitSnapshot) ?? blockedSnapshots[0] ?? void 0;
|
|
78
|
+
return blockingSnapshot ? selectSnapshotBlockingReset(blockingSnapshot, nowMs) : void 0;
|
|
77
79
|
}
|
|
78
80
|
function summarizeRateLimitSnapshot(snapshot, nowMs) {
|
|
79
81
|
const label = formatLimitLabel(snapshot);
|
|
@@ -176,8 +178,8 @@ function selectSnapshotBlockingReset(snapshot, nowMs) {
|
|
|
176
178
|
const futureWindows = readWindowEntries(snapshot).map((entry) => entry.window).filter((window) => window.resetsAtMs > nowMs);
|
|
177
179
|
const exhaustedWindows = futureWindows.filter((window) => window.usedPercent !== void 0 && window.usedPercent >= 100);
|
|
178
180
|
const candidates = exhaustedWindows.length > 0 ? exhaustedWindows : futureWindows;
|
|
179
|
-
|
|
180
|
-
return candidates[0];
|
|
181
|
+
const resetSort = exhaustedWindows.length > 0 ? (left, right) => right.resetsAtMs - left.resetsAtMs : (left, right) => left.resetsAtMs - right.resetsAtMs;
|
|
182
|
+
return candidates.toSorted(resetSort)[0];
|
|
181
183
|
}
|
|
182
184
|
function readWindowEntries(snapshot) {
|
|
183
185
|
return LIMIT_WINDOW_KEYS.flatMap((key) => {
|
|
@@ -188,15 +190,25 @@ function readWindowEntries(snapshot) {
|
|
|
188
190
|
}] : [];
|
|
189
191
|
});
|
|
190
192
|
}
|
|
191
|
-
function formatBlockingLimitReason(window) {
|
|
192
|
-
const period = formatBlockingLimitPeriod(window?.windowDurationMins);
|
|
193
|
-
return period ? `Your ${period} Codex usage limit is reached.` : "Your Codex usage limit is reached.";
|
|
194
|
-
}
|
|
195
193
|
function formatBlockingLimitPeriod(minutes) {
|
|
196
194
|
if (minutes === 10080) return "weekly";
|
|
197
195
|
if (minutes === 1440) return "daily";
|
|
198
196
|
if (minutes !== void 0 && minutes > 0 && minutes < 1440) return "short-term";
|
|
199
197
|
}
|
|
198
|
+
function formatUsageLine(snapshot) {
|
|
199
|
+
const windows = readWindowEntries(snapshot).filter((entry) => entry.window.usedPercent !== void 0).toSorted((left, right) => (right.window.windowDurationMins ?? 0) - (left.window.windowDurationMins ?? 0)).map((entry) => {
|
|
200
|
+
return `${formatUsageWindowLabel(entry.window.windowDurationMins)} ${Math.round(entry.window.usedPercent ?? 0)}%`;
|
|
201
|
+
});
|
|
202
|
+
return windows.length > 0 ? windows.join(" · ") : void 0;
|
|
203
|
+
}
|
|
204
|
+
function formatUsageWindowLabel(minutes) {
|
|
205
|
+
if (minutes === 10080) return "weekly";
|
|
206
|
+
if (minutes === 1440) return "daily";
|
|
207
|
+
if (minutes !== void 0 && minutes > 0 && minutes < 1440) return "short-term";
|
|
208
|
+
if (minutes !== void 0 && minutes > 0 && minutes % 1440 === 0) return `${minutes / 1440}-day`;
|
|
209
|
+
if (minutes !== void 0 && minutes > 0 && minutes % 60 === 0) return `${minutes / 60}-hour`;
|
|
210
|
+
return "usage";
|
|
211
|
+
}
|
|
200
212
|
function formatCalendarResetTime(resetsAtMs, nowMs) {
|
|
201
213
|
const resetDate = new Date(resetsAtMs);
|
|
202
214
|
const resetParts = new Intl.DateTimeFormat("en-US", {
|
|
@@ -295,11 +307,30 @@ function formatThreads(response) {
|
|
|
295
307
|
return `- ${formatCodexDisplayText(id)}${title ? ` - ${formatCodexDisplayText(title)}` : ""}${details.length > 0 ? ` (${details.map(formatCodexDisplayText).join(", ")})` : ""}\n Resume: ${formatCodexResumeHint(id)}`;
|
|
296
308
|
})].join("\n");
|
|
297
309
|
}
|
|
298
|
-
function formatAccount(account, limits) {
|
|
310
|
+
function formatAccount(account, limits, authOverview) {
|
|
311
|
+
if (authOverview) return formatAccountAuthOverview(authOverview);
|
|
299
312
|
const formattedLimits = limits.ok ? formatCodexRateLimitDetails(limits.value) : formatCodexDisplayText(limits.error);
|
|
300
313
|
const rateLimitBlock = formattedLimits.startsWith("Codex is ") ? formattedLimits : formattedLimits.includes("\n") ? `Rate limits:\n${formattedLimits}` : `Rate limits: ${formattedLimits}`;
|
|
301
314
|
return [`Account: ${account.ok ? formatCodexAccountSummary(account.value) : formatCodexDisplayText(account.error)}`, rateLimitBlock].join("\n\n");
|
|
302
315
|
}
|
|
316
|
+
function formatAccountAuthOverview(overview) {
|
|
317
|
+
const lines = [];
|
|
318
|
+
if (overview.currentLine) lines.push(overview.currentLine, "");
|
|
319
|
+
if (overview.subscriptionLabel) {
|
|
320
|
+
lines.push(`Subscription ${overview.subscriptionLabel}`);
|
|
321
|
+
if (overview.subscriptionUsage) lines.push(` ${overview.subscriptionUsage}`);
|
|
322
|
+
lines.push("");
|
|
323
|
+
}
|
|
324
|
+
if (overview.rows.length > 0) {
|
|
325
|
+
lines.push(overview.orderTitle);
|
|
326
|
+
for (const [index, row] of overview.rows.entries()) lines.push(` ${index + 1}. ${row.label} ${row.kind} — ${formatAuthRowStatus(row)}`);
|
|
327
|
+
}
|
|
328
|
+
while (lines.at(-1) === "") lines.pop();
|
|
329
|
+
return lines.map(formatCodexAccountLine).join("\n");
|
|
330
|
+
}
|
|
331
|
+
function formatAuthRowStatus(row) {
|
|
332
|
+
return row.billingNote ? `${row.status} · ${row.billingNote}` : row.status;
|
|
333
|
+
}
|
|
303
334
|
function formatComputerUseStatus(status) {
|
|
304
335
|
const lines = [`Computer Use: ${status.ready ? "ready" : status.enabled ? "not ready" : "disabled"}`];
|
|
305
336
|
lines.push(`Plugin: ${formatCodexDisplayText(status.pluginName)} (${computerUsePluginState(status)})`);
|
|
@@ -335,13 +366,15 @@ function formatCodexAccountSummary(value) {
|
|
|
335
366
|
return isLikelyEmailAddress(safe) ? escapeCodexChatTextPreservingAt(safe) : escapeCodexChatText(safe);
|
|
336
367
|
}
|
|
337
368
|
function formatCodexTextForDisplay(value) {
|
|
369
|
+
return sanitizeCodexTextForDisplay(value).trim() || "<unknown>";
|
|
370
|
+
}
|
|
371
|
+
function sanitizeCodexTextForDisplay(value) {
|
|
338
372
|
let safe = "";
|
|
339
373
|
for (const character of value) {
|
|
340
374
|
const codePoint = character.codePointAt(0);
|
|
341
375
|
safe += codePoint != null && isUnsafeDisplayCodePoint(codePoint) ? "?" : character;
|
|
342
376
|
}
|
|
343
|
-
|
|
344
|
-
return safe || "<unknown>";
|
|
377
|
+
return safe;
|
|
345
378
|
}
|
|
346
379
|
function escapeCodexChatText(value) {
|
|
347
380
|
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("@", "@").replaceAll("`", "`").replaceAll("[", "[").replaceAll("]", "]").replaceAll("(", "(").replaceAll(")", ")").replaceAll("*", "∗").replaceAll("_", "_").replaceAll("~", "~").replaceAll("|", "|");
|
|
@@ -349,6 +382,22 @@ function escapeCodexChatText(value) {
|
|
|
349
382
|
function escapeCodexChatTextPreservingAt(value) {
|
|
350
383
|
return escapeCodexChatText(value).replaceAll("@", "@");
|
|
351
384
|
}
|
|
385
|
+
function formatCodexAccountLine(value) {
|
|
386
|
+
if (value === "") return "";
|
|
387
|
+
const safe = sanitizeCodexTextForDisplay(value).trimEnd();
|
|
388
|
+
if (!safe.trim()) return "";
|
|
389
|
+
const emailPattern = /[^\s@<>()[\]`]+@[^\s@<>()[\]`]+\.[^\s@<>()[\]`]+/gu;
|
|
390
|
+
let formatted = "";
|
|
391
|
+
let lastIndex = 0;
|
|
392
|
+
for (const match of safe.matchAll(emailPattern)) {
|
|
393
|
+
const index = match.index ?? 0;
|
|
394
|
+
formatted += escapeCodexChatText(safe.slice(lastIndex, index));
|
|
395
|
+
formatted += escapeCodexChatTextPreservingAt(match[0]);
|
|
396
|
+
lastIndex = index + match[0].length;
|
|
397
|
+
}
|
|
398
|
+
formatted += escapeCodexChatText(safe.slice(lastIndex));
|
|
399
|
+
return formatted;
|
|
400
|
+
}
|
|
352
401
|
function isLikelyEmailAddress(value) {
|
|
353
402
|
return /^[^\s@<>()[\]`]+@[^\s@<>()[\]`]+\.[^\s@<>()[\]`]+$/.test(value);
|
|
354
403
|
}
|
|
@@ -434,17 +483,4 @@ function readString(record, key) {
|
|
|
434
483
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
435
484
|
}
|
|
436
485
|
//#endregion
|
|
437
|
-
|
|
438
|
-
async function requestCodexAppServerJson(params) {
|
|
439
|
-
const timeoutMs = params.timeoutMs ?? 6e4;
|
|
440
|
-
return await withTimeout((async () => {
|
|
441
|
-
return await (await getSharedCodexAppServerClient({
|
|
442
|
-
startOptions: params.startOptions,
|
|
443
|
-
timeoutMs,
|
|
444
|
-
authProfileId: params.authProfileId,
|
|
445
|
-
config: params.config
|
|
446
|
-
})).request(params.method, params.requestParams, { timeoutMs });
|
|
447
|
-
})(), timeoutMs, `codex app-server ${params.method} timed out`);
|
|
448
|
-
}
|
|
449
|
-
//#endregion
|
|
450
|
-
export { formatCodexStatus as a, formatModels as c, formatCodexUsageLimitErrorMessage as d, shouldRefreshCodexRateLimitsForUsageLimitMessage as f, formatCodexDisplayText as i, formatThreads as l, describeControlFailure as m, buildHelp as n, formatComputerUseStatus as o, CODEX_CONTROL_METHODS as p, formatAccount as r, formatList as s, requestCodexAppServerJson as t, readString as u };
|
|
486
|
+
export { formatComputerUseStatus as a, formatThreads as c, resolveCodexUsageLimitResetAtMs as d, shouldRefreshCodexRateLimitsForUsageLimitMessage as f, formatCodexStatus as i, readString as l, formatAccount as n, formatList as o, summarizeCodexAccountUsage as p, formatCodexDisplayText as r, formatModels as s, buildHelp as t, formatCodexUsageLimitErrorMessage as u };
|
|
@@ -1,11 +1,294 @@
|
|
|
1
1
|
import { i as isCodexFastServiceTier, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
|
|
2
|
-
import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-
|
|
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 {
|
|
5
|
-
import { i as
|
|
6
|
-
import {
|
|
7
|
-
import { a as
|
|
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
|
}
|
|
@@ -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
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-
|
|
4
|
-
import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory-
|
|
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
1
|
import { c as resolveCodexComputerUseConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
|
|
2
|
-
import {
|
|
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
|
-
|
|
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,8 +1,9 @@
|
|
|
1
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 {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
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";
|