@openclaw/codex 2026.6.2-beta.1 → 2026.6.5-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.
Files changed (28) hide show
  1. package/dist/{client-factory-BS9nYX8K.js → client-factory-Bt49r45B.js} +2 -1
  2. package/dist/{client-BFxKzFnH.js → client-kMCtlApt.js} +42 -0
  3. package/dist/{command-handlers-BaBMyAFy.js → command-handlers-DMn2M7W7.js} +9 -9
  4. package/dist/{compact-CVPc2Rag.js → compact-CwnPeYnM.js} +11 -4
  5. package/dist/{computer-use-Dhz6SrFx.js → computer-use-ClweWaMz.js} +11 -1
  6. package/dist/{conversation-binding-CMaXGYAc.js → conversation-binding-CzpvaBs1.js} +7 -7
  7. package/dist/doctor-contract-api.js +5 -0
  8. package/dist/harness.js +9 -5
  9. package/dist/index.js +8 -6
  10. package/dist/media-understanding-provider.js +13 -5
  11. package/dist/{models-D8i1zWEu.js → models-DXorTaja.js} +9 -2
  12. package/dist/{native-hook-relay-CBp3nIGk.js → native-hook-relay-DZ3Oon0b.js} +61 -3
  13. package/dist/{notification-correlation-Bg-AlEEy.js → notification-correlation-o8quHmTK.js} +30 -1
  14. package/dist/prompt-overlay.js +7 -0
  15. package/dist/{protocol-validators-DIt7cXIp.js → protocol-validators-CIpP8IJ2.js} +13 -0
  16. package/dist/provider-catalog.js +8 -0
  17. package/dist/provider-discovery.js +1 -0
  18. package/dist/provider.js +16 -1
  19. package/dist/{rate-limit-cache-N66I-Rd7.js → rate-limit-cache-C7qmZ0Jh.js} +2 -0
  20. package/dist/{request-nYrsFNU2.js → request-D64BfplD.js} +16 -4
  21. package/dist/{run-attempt-Wo9uasL_.js → run-attempt-CWfXFq9Q.js} +383 -27
  22. package/dist/{sandbox-guard-DMCJlzmz.js → sandbox-guard-C-Yv9uwY.js} +5 -0
  23. package/dist/{session-binding-D8DxeEbf.js → session-binding-BgTv_YGm.js} +11 -0
  24. package/dist/{shared-client-B31-oqN-.js → shared-client-xytpSKD0.js} +31 -2
  25. package/dist/{side-question-DbYSPUnj.js → side-question-BEpALo9c.js} +9 -9
  26. package/dist/{thread-lifecycle-BOYYMjx6.js → thread-lifecycle-BJsazZ8j.js} +50 -6
  27. package/npm-shrinkwrap.json +2 -2
  28. package/package.json +4 -4
@@ -1,20 +1,25 @@
1
- import { l as isJsonObject } from "./client-BFxKzFnH.js";
2
- import { S as invalidInlineImageText, w as sanitizeInlineImageDataUrl } from "./thread-lifecycle-BOYYMjx6.js";
3
- import { s as formatCodexDisplayText } from "./notification-correlation-Bg-AlEEy.js";
1
+ import { l as isJsonObject } from "./client-kMCtlApt.js";
2
+ import { S as invalidInlineImageText, w as sanitizeInlineImageDataUrl } from "./thread-lifecycle-BJsazZ8j.js";
3
+ import { s as formatCodexDisplayText } from "./notification-correlation-o8quHmTK.js";
4
4
  import { addTimerTimeoutGraceMs, finiteSecondsToTimerSafeMilliseconds, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
5
5
  import { createHash } from "node:crypto";
6
6
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
7
7
  import { asOptionalRecord, isRecord, normalizeTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { HEARTBEAT_RESPONSE_TOOL_NAME, buildAgentHookContextChannelFields, callGatewayTool, createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, embeddedAgentLog, extractToolResultMediaArtifact, filterToolResultMediaUrls, formatApprovalDisplayPath, hasNativeHookRelayInvocation, invokeNativeHookRelay, isMessagingTool, isMessagingToolSendAction, isToolWrappedWithBeforeToolCallHook, normalizeHeartbeatToolResponse, projectRuntimeToolInputSchema, registerNativeHookRelay, resolveNativeHookRelayDeferredToolApproval, runAgentHarnessAfterToolCallHook, runBeforeToolCallHook, setBeforeToolCallDiagnosticsEnabled, wrapToolWithBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
9
9
  import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
10
+ /** Default idle timeout while waiting for app-server turn completion. */
10
11
  const CODEX_TURN_COMPLETION_IDLE_TIMEOUT_MS = 6e4;
12
+ /** Short guard after apparent assistant completion. */
11
13
  const CODEX_TURN_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS = 1e4;
12
14
  const CODEX_POST_TOOL_RAW_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS = 5 * 6e4;
15
+ /** Guard after reasoning/commentary progress when no tool handoff occurred. */
13
16
  const CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS = 5 * 6e4;
17
+ /** Long terminal idle watch for app-server turns that never send completion. */
14
18
  const CODEX_TURN_TERMINAL_IDLE_TIMEOUT_MS = 30 * 6e4;
15
19
  function resolvePositiveIntegerTimeoutMs(value, fallbackMs) {
16
20
  return resolveTimerTimeoutMs(value, resolveTimerTimeoutMs(fallbackMs, 1));
17
21
  }
22
+ /** Runs startup work with abort and timeout handling plus optional cleanup. */
18
23
  async function withCodexStartupTimeout(params) {
19
24
  if (params.signal.aborted) throw new Error("codex app-server startup aborted");
20
25
  let timeout;
@@ -52,32 +57,43 @@ async function withCodexStartupTimeout(params) {
52
57
  abortCleanup?.();
53
58
  }
54
59
  }
60
+ /** Resolves startup timeout while honoring the configured floor. */
55
61
  function resolveCodexStartupTimeoutMs(params) {
56
62
  const timeoutFloorMs = resolvePositiveIntegerTimeoutMs(params.timeoutFloorMs, 100);
57
63
  const timeoutMs = resolvePositiveIntegerTimeoutMs(params.timeoutMs, timeoutFloorMs);
58
64
  return Math.max(timeoutFloorMs, timeoutMs);
59
65
  }
66
+ /** Resolves the completion-idle timeout for an active turn. */
60
67
  function resolveCodexTurnCompletionIdleTimeoutMs(value) {
61
68
  return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_COMPLETION_IDLE_TIMEOUT_MS);
62
69
  }
70
+ /** Resolves the short assistant-completion release timeout. */
63
71
  function resolveCodexTurnAssistantCompletionIdleTimeoutMs(value) {
64
72
  return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS);
65
73
  }
74
+ /** Resolves the conservative post-tool raw assistant guard timeout. */
66
75
  function resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs(value, fallbackMs) {
67
76
  return resolvePositiveIntegerTimeoutMs(value, Math.max(resolvePositiveIntegerTimeoutMs(void 0, fallbackMs), CODEX_POST_TOOL_RAW_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS));
68
77
  }
78
+ /** Resolves the long terminal turn idle timeout. */
69
79
  function resolveCodexTurnTerminalIdleTimeoutMs(value) {
70
80
  return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_TERMINAL_IDLE_TIMEOUT_MS);
71
81
  }
82
+ /** Adds gateway grace time to a caller timeout without overflowing invalid values. */
72
83
  function resolveCodexGatewayTimeoutWithGraceMs(timeoutMs, graceMs = 1e4) {
73
84
  const timeout = resolvePositiveIntegerTimeoutMs(timeoutMs, 1);
74
85
  return addTimerTimeoutGraceMs(timeout, resolveTimerTimeoutMs(graceMs, 0, 0)) ?? timeout;
75
86
  }
76
87
  //#endregion
77
88
  //#region extensions/codex/src/app-server/plugin-approval-roundtrip.ts
89
+ /**
90
+ * Routes Codex app-server plugin approval prompts through OpenClaw's gateway
91
+ * approval tool and maps gateway decisions back to Codex outcomes.
92
+ */
78
93
  const DEFAULT_CODEX_APPROVAL_TIMEOUT_MS = 12e4;
79
94
  const MAX_PLUGIN_APPROVAL_TITLE_LENGTH = 80;
80
95
  const MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH = 256;
96
+ /** Starts a two-phase plugin approval request through the OpenClaw gateway. */
81
97
  async function requestPluginApproval(params) {
82
98
  const timeoutMs = DEFAULT_CODEX_APPROVAL_TIMEOUT_MS;
83
99
  return callGatewayTool("plugin.approval.request", { timeoutMs: resolveCodexGatewayTimeoutWithGraceMs(timeoutMs) }, {
@@ -97,6 +113,7 @@ async function requestPluginApproval(params) {
97
113
  twoPhase: true
98
114
  }, { expectFinal: false });
99
115
  }
116
+ /** Detects the gateway's explicit null-decision marker for unavailable approvals. */
100
117
  function approvalRequestExplicitlyUnavailable(result) {
101
118
  if (result === null || result === void 0 || typeof result !== "object") return false;
102
119
  let descriptor;
@@ -107,6 +124,7 @@ function approvalRequestExplicitlyUnavailable(result) {
107
124
  }
108
125
  return descriptor !== void 0 && "value" in descriptor && descriptor.value === null;
109
126
  }
127
+ /** Waits for the gateway's final approval decision, respecting turn aborts. */
110
128
  async function waitForPluginApprovalDecision(params) {
111
129
  const waitPromise = callGatewayTool("plugin.approval.waitDecision", { timeoutMs: resolveCodexGatewayTimeoutWithGraceMs(DEFAULT_CODEX_APPROVAL_TIMEOUT_MS) }, { id: params.approvalId });
112
130
  if (!params.signal) return (await waitPromise)?.decision;
@@ -125,6 +143,7 @@ async function waitForPluginApprovalDecision(params) {
125
143
  if (onAbort) params.signal.removeEventListener("abort", onAbort);
126
144
  }
127
145
  }
146
+ /** Converts a gateway exec approval decision into the app-server approval outcome enum. */
128
147
  function mapExecDecisionToOutcome(decision) {
129
148
  if (decision === "allow-once") return "approved-once";
130
149
  if (decision === "allow-always") return "approved-session";
@@ -143,6 +162,10 @@ function toLintErrorObject(value, fallbackMessage) {
143
162
  }
144
163
  //#endregion
145
164
  //#region extensions/codex/src/app-server/approval-bridge.ts
165
+ /**
166
+ * Bridges Codex app-server approval requests into OpenClaw policy hooks and
167
+ * plugin approval UX.
168
+ */
146
169
  const PERMISSION_DESCRIPTION_MAX_LENGTH = 700;
147
170
  const PERMISSION_SAMPLE_LIMIT = 2;
148
171
  const PERMISSION_VALUE_MAX_LENGTH = 48;
@@ -154,6 +177,10 @@ const ANSI_CONTROL_SEQUENCE_RE$1 = new RegExp(String.raw`(?:\u001b\[[0-?]*[ -/]*
154
177
  const CONTROL_CHARACTER_RE$1 = new RegExp(String.raw`[\u0000-\u001f\u007f-\u009f]+`, "g");
155
178
  const INVISIBLE_FORMATTING_CONTROL_RE$1 = new RegExp(String.raw`[\u00ad\u034f\u061c\u200b-\u200f\u202a-\u202e\u2060-\u206f\ufeff\ufe00-\ufe0f\u{e0100}-\u{e01ef}]`, "gu");
156
179
  const DANGLING_TERMINAL_SEQUENCE_SUFFIX_RE$1 = new RegExp(String.raw`(?:\u001b\][^\u001b\u009c\u0007]*|\u009d[^\u001b\u009c\u0007]*|\u001b\[[0-?]*[ -/]*|\u009b[0-?]*[ -/]*|\u001b)$`);
180
+ /**
181
+ * Handles one app-server approval request for the active thread/turn, returning
182
+ * the app-server response payload when the request belongs to this run.
183
+ */
157
184
  async function handleCodexAppServerApprovalRequest(params) {
158
185
  const requestParams = isJsonObject(params.requestParams) ? params.requestParams : void 0;
159
186
  if (!matchesCurrentTurn(requestParams, params.threadId, params.turnId)) return;
@@ -269,6 +296,7 @@ async function handleCodexAppServerApprovalRequest(params) {
269
296
  return buildApprovalResponse(params.method, context.requestParams, cancelled ? "cancelled" : "denied");
270
297
  }
271
298
  }
299
+ /** Converts an OpenClaw approval outcome into the app-server method response. */
272
300
  function buildApprovalResponse(method, requestParams, outcome) {
273
301
  if (method === "item/commandExecution/requestApproval") return { decision: commandApprovalDecision(requestParams, outcome) };
274
302
  if (method === "item/fileChange/requestApproval") return { decision: fileChangeApprovalDecision(outcome) };
@@ -881,12 +909,21 @@ function formatErrorMessage$1(error) {
881
909
  }
882
910
  //#endregion
883
911
  //#region extensions/codex/src/app-server/vision-tools.ts
912
+ /**
913
+ * Filters Codex dynamic tools for turns that already contain image inputs so
914
+ * models with native vision do not get redundant image-inspection tools.
915
+ */
916
+ /** Removes the image tool when the model can directly consume inbound images. */
884
917
  function filterToolsForVisionInputs(tools, params) {
885
918
  if (!params.modelHasVision || !params.hasInboundImages) return tools;
886
919
  return tools.filter((tool) => tool.name !== "image");
887
920
  }
888
921
  //#endregion
889
922
  //#region extensions/codex/src/app-server/dynamic-tool-diagnostics.ts
923
+ /**
924
+ * Trusted diagnostics emitted around Codex dynamic tool execution lifecycle.
925
+ */
926
+ /** Emits a start event for one Codex dynamic tool call. */
890
927
  function emitDynamicToolStartedDiagnostic(params) {
891
928
  emitTrustedDiagnosticEvent({
892
929
  type: "tool.execution.started",
@@ -897,6 +934,7 @@ function emitDynamicToolStartedDiagnostic(params) {
897
934
  toolCallId: params.call.callId
898
935
  });
899
936
  }
937
+ /** Emits an error event for one Codex dynamic tool call. */
900
938
  function emitDynamicToolErrorDiagnostic(params) {
901
939
  emitTrustedDiagnosticEvent({
902
940
  type: "tool.execution.error",
@@ -909,6 +947,7 @@ function emitDynamicToolErrorDiagnostic(params) {
909
947
  errorCategory: "codex_dynamic_tool_error"
910
948
  });
911
949
  }
950
+ /** Emits the terminal event matching a dynamic tool response's diagnostic type. */
912
951
  function emitDynamicToolTerminalDiagnostic(params) {
913
952
  const terminalType = params.response.diagnosticTerminalType ?? (params.response.success ? "completed" : "error");
914
953
  if (terminalType === "completed") {
@@ -940,9 +979,14 @@ function emitDynamicToolTerminalDiagnostic(params) {
940
979
  }
941
980
  //#endregion
942
981
  //#region extensions/codex/src/app-server/dynamic-tools.ts
982
+ /** Namespace attached to OpenClaw-owned dynamic tools exposed to Codex. */
943
983
  const CODEX_OPENCLAW_DYNAMIC_TOOL_NAMESPACE = "openclaw";
944
984
  const ALWAYS_DIRECT_DYNAMIC_TOOL_NAMES = new Set(["sessions_yield"]);
945
985
  const DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS = 16e3;
986
+ /**
987
+ * Creates dynamic tool specs and a call handler that executes OpenClaw tools,
988
+ * applies hooks/middleware, and records delivery/media telemetry.
989
+ */
946
990
  function createCodexDynamicToolBridge(params) {
947
991
  const toolResultHookContext = toToolResultHookContext(params.hookContext);
948
992
  const toolResultMaxChars = resolveCodexDynamicToolResultMaxChars(params.hookContext);
@@ -1964,6 +2008,11 @@ function readFirstString(record, keys) {
1964
2008
  }
1965
2009
  //#endregion
1966
2010
  //#region extensions/codex/src/app-server/native-hook-relay.ts
2011
+ /**
2012
+ * Bridges Codex native hook callbacks into OpenClaw's native hook relay so
2013
+ * app-server tool events can still run OpenClaw policy and diagnostics.
2014
+ */
2015
+ /** Codex hook events that can be registered through OpenClaw's native relay. */
1967
2016
  const CODEX_NATIVE_HOOK_RELAY_EVENTS = [
1968
2017
  "pre_tool_use",
1969
2018
  "post_tool_use",
@@ -1972,10 +2021,12 @@ const CODEX_NATIVE_HOOK_RELAY_EVENTS = [
1972
2021
  ];
1973
2022
  const CODEX_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS = CODEX_NATIVE_HOOK_RELAY_EVENTS.filter((event) => event !== "permission_request");
1974
2023
  const CODEX_NATIVE_HOOK_RELAY_MIN_TTL_MS = 30 * 6e4;
2024
+ /** Extra relay lifetime after the expected turn budget, preventing late hook drops. */
1975
2025
  const CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS = 5 * 6e4;
1976
2026
  const CODEX_NATIVE_HOOK_RELAY_UNREGISTER_GRACE_MS = 1e4;
1977
2027
  const CODEX_NATIVE_HOOK_RELAY_UNREGISTER_EXTRA_GRACE_MS = 5e3;
1978
2028
  const pendingCodexNativeHookRelayUnregisters = /* @__PURE__ */ new Set();
2029
+ /** Defers relay unregister so late native hook subprocesses can still resolve. */
1979
2030
  function scheduleCodexNativeHookRelayUnregister(params) {
1980
2031
  let pending;
1981
2032
  const unregister = () => {
@@ -1993,10 +2044,12 @@ function scheduleCodexNativeHookRelayUnregister(params) {
1993
2044
  pendingCodexNativeHookRelayUnregisters.add(pending);
1994
2045
  timeout.unref();
1995
2046
  }
2047
+ /** Computes the delayed unregister window from Codex's hook timeout. */
1996
2048
  function resolveCodexNativeHookRelayUnregisterGraceMs(hookTimeoutSec) {
1997
2049
  const hookTimeoutMs = typeof hookTimeoutSec === "number" && Number.isFinite(hookTimeoutSec) && hookTimeoutSec > 0 ? finiteSecondsToTimerSafeMilliseconds(Math.ceil(hookTimeoutSec)) ?? 0 : 0;
1998
2050
  return Math.max(CODEX_NATIVE_HOOK_RELAY_UNREGISTER_GRACE_MS, addTimerTimeoutGraceMs(hookTimeoutMs, CODEX_NATIVE_HOOK_RELAY_UNREGISTER_EXTRA_GRACE_MS) ?? 0);
1999
2051
  }
2052
+ /** Registers an OpenClaw native hook relay for a Codex app-server turn. */
2000
2053
  function createCodexNativeHookRelay(params) {
2001
2054
  if (params.options?.enabled === false) return;
2002
2055
  return registerNativeHookRelay({
@@ -2028,15 +2081,18 @@ function createCodexNativeHookRelay(params) {
2028
2081
  }
2029
2082
  });
2030
2083
  }
2084
+ /** Selects the native hook events Codex should install for the current approval mode. */
2031
2085
  function resolveCodexNativeHookRelayEvents(params) {
2032
2086
  if (params.configuredEvents?.length) return params.configuredEvents;
2033
2087
  return params.appServer.approvalPolicy === "never" ? CODEX_NATIVE_HOOK_RELAY_EVENTS : CODEX_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS;
2034
2088
  }
2089
+ /** Derives the native hook relay TTL from the turn budget unless explicitly configured. */
2035
2090
  function resolveCodexNativeHookRelayTtlMs(params) {
2036
2091
  if (params.explicitTtlMs !== void 0) return params.explicitTtlMs;
2037
2092
  const relayBudgetMs = params.attemptTimeoutMs + params.startupTimeoutMs + params.turnStartTimeoutMs + CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS;
2038
2093
  return Math.max(CODEX_NATIVE_HOOK_RELAY_MIN_TTL_MS, Math.floor(relayBudgetMs));
2039
2094
  }
2095
+ /** Builds a stable relay id scoped to the agent and session identity. */
2040
2096
  function buildCodexNativeHookRelayId(params) {
2041
2097
  const hash = createHash("sha256");
2042
2098
  hash.update("openclaw:codex:native-hook-relay:v1");
@@ -2059,6 +2115,7 @@ const CODEX_HOOK_KEY_LABEL_BY_NATIVE_EVENT = {
2059
2115
  before_agent_finalize: "stop"
2060
2116
  };
2061
2117
  const CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS = ["/<session-flags>/config.toml", "<session-flags>/config.toml"];
2118
+ /** Builds the Codex config overlay that installs trusted command hooks for relay events. */
2062
2119
  function buildCodexNativeHookRelayConfig(params) {
2063
2120
  const events = params.events?.length ? params.events : CODEX_NATIVE_HOOK_RELAY_EVENTS;
2064
2121
  const selectedEvents = new Set(events);
@@ -2096,6 +2153,7 @@ function buildCodexNativeHookRelayConfig(params) {
2096
2153
  config["hooks.state"] = hookState;
2097
2154
  return config;
2098
2155
  }
2156
+ /** Builds a Codex config overlay that disables native hooks and clears hook arrays. */
2099
2157
  function buildCodexNativeHookRelayDisabledConfig() {
2100
2158
  return {
2101
2159
  "features.hooks": false,
@@ -1,13 +1,18 @@
1
- import { l as isJsonObject } from "./client-BFxKzFnH.js";
1
+ import { l as isJsonObject } from "./client-kMCtlApt.js";
2
2
  import { MAX_DATE_TIMESTAMP_MS, resolveExpiresAtMsFromEpochSeconds } from "openclaw/plugin-sdk/number-runtime";
3
3
  import { asFiniteNumber } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/codex/src/app-server/rate-limits.ts
5
+ /**
6
+ * Parses Codex account rate-limit payloads into user-facing usage summaries,
7
+ * reset hints, and enriched usage-limit error messages.
8
+ */
5
9
  const CODEX_LIMIT_ID = "codex";
6
10
  const LIMIT_WINDOW_KEYS = ["primary", "secondary"];
7
11
  const ONE_SECOND_MS = 1e3;
8
12
  const ONE_MINUTE_MS = 6e4;
9
13
  const ONE_HOUR_MS = 60 * ONE_MINUTE_MS;
10
14
  const ONE_DAY_MS = 24 * ONE_HOUR_MS;
15
+ /** Enriches Codex usage-limit failures with reset timing and recovery guidance. */
11
16
  function formatCodexUsageLimitErrorMessage(params) {
12
17
  const message = normalizeText(params.message);
13
18
  if (!isCodexUsageLimitError(params.codexErrorInfo, message)) return;
@@ -32,28 +37,34 @@ function formatCodexUsageLimitErrorMessage(params) {
32
37
  parts.push(`${recoveryAction}, use another Codex account if available, or switch to another configured model/provider.`);
33
38
  return parts.join(" ");
34
39
  }
40
+ /** Detects usage-limit messages that need a fresh rate-limit query before display. */
35
41
  function shouldRefreshCodexRateLimitsForUsageLimitMessage(message) {
36
42
  const text = normalizeText(message);
37
43
  return Boolean(text?.includes("You've reached your Codex subscription usage limit.") && !text.includes("Next reset "));
38
44
  }
45
+ /** Formats compact summaries for raw Codex rate-limit snapshot payloads. */
39
46
  function summarizeCodexRateLimits(value, nowMs = Date.now()) {
40
47
  const snapshots = collectCodexRateLimitSnapshots(value).filter(snapshotHasDisplayableData);
41
48
  if (snapshots.length === 0) return;
42
49
  const summaries = snapshots.slice(0, 4).map((snapshot) => summarizeRateLimitSnapshot(snapshot, nowMs)).filter((summary) => summary !== void 0);
43
50
  return summaries.length > 0 ? summaries.join("; ") : void 0;
44
51
  }
52
+ /** Returns true when a value contains any recognizable Codex rate-limit snapshots. */
45
53
  function hasCodexRateLimitSnapshots(value) {
46
54
  return collectCodexRateLimitSnapshots(value).length > 0;
47
55
  }
56
+ /** Builds short account availability lines suitable for status surfaces. */
48
57
  function summarizeCodexAccountRateLimits(value, nowMs = Date.now()) {
49
58
  const summary = summarizeCodexAccountUsage(value, nowMs);
50
59
  if (!summary) return;
51
60
  if (!summary.blocked) return ["Codex is available."];
52
61
  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."];
53
62
  }
63
+ /** Returns the reset timestamp for the currently blocking Codex usage limit. */
54
64
  function resolveCodexUsageLimitResetAtMs(value, nowMs = Date.now()) {
55
65
  return selectBlockingRateLimitReset(value, nowMs)?.resetsAtMs;
56
66
  }
67
+ /** Summarizes account availability, blocking reason, and reset time from rate-limit data. */
57
68
  function summarizeCodexAccountUsage(value, nowMs = Date.now()) {
58
69
  const snapshots = collectCodexRateLimitSnapshots(value).filter(snapshotHasDisplayableData);
59
70
  if (snapshots.length === 0) return;
@@ -312,6 +323,7 @@ function normalizeText(value) {
312
323
  }
313
324
  //#endregion
314
325
  //#region extensions/codex/src/command-formatters.ts
326
+ /** Formats the combined `/codex status` probe result. */
315
327
  function formatCodexStatus(probes) {
316
328
  const lines = [`Codex app-server: ${probes.models.ok || probes.account.ok || probes.limits.ok || probes.mcps.ok || probes.skills.ok ? "connected" : "unavailable"}`];
317
329
  if (probes.models.ok) lines.push(`Models: ${probes.models.value.models.map((model) => formatCodexDisplayText(model.id)).slice(0, 8).join(", ") || "none"}`);
@@ -322,12 +334,14 @@ function formatCodexStatus(probes) {
322
334
  lines.push(`Skills: ${probes.skills.ok ? summarizeCodexSkills(probes.skills.value) : formatCodexDisplayText(probes.skills.error)}`);
323
335
  return lines.join("\n");
324
336
  }
337
+ /** Formats Codex model-list results for `/codex models`. */
325
338
  function formatModels(result) {
326
339
  if (result.models.length === 0) return "No Codex app-server models returned.";
327
340
  const lines = ["Codex models:", ...result.models.map((model) => `- ${formatCodexDisplayText(model.id)}${model.isDefault ? " (default)" : ""}`)];
328
341
  if (result.truncated) lines.push("- More models available; output truncated.");
329
342
  return lines.join("\n");
330
343
  }
344
+ /** Formats Codex thread-list responses with safe resume hints. */
331
345
  function formatThreads(response) {
332
346
  const threads = extractArray(response);
333
347
  if (threads.length === 0) return "No Codex threads returned.";
@@ -343,6 +357,7 @@ function formatThreads(response) {
343
357
  return `- ${formatCodexDisplayText(id)}${title ? ` - ${formatCodexDisplayText(title)}` : ""}${details.length > 0 ? ` (${details.map(formatCodexDisplayText).join(", ")})` : ""}\n Resume: ${formatCodexResumeHint(id)}`;
344
358
  })].join("\n");
345
359
  }
360
+ /** Formats account and rate-limit output for `/codex account`. */
346
361
  function formatAccount(account, limits, authOverview) {
347
362
  if (authOverview) return formatAccountAuthOverview(authOverview);
348
363
  const formattedLimits = limits.ok ? formatCodexRateLimitDetails(limits.value) : formatCodexDisplayText(limits.error);
@@ -367,6 +382,7 @@ function formatAccountAuthOverview(overview) {
367
382
  function formatAuthRowStatus(row) {
368
383
  return row.billingNote ? `${row.status} · ${row.billingNote}` : row.status;
369
384
  }
385
+ /** Formats Codex Computer Use readiness and plugin/MCP availability. */
370
386
  function formatComputerUseStatus(status) {
371
387
  const lines = [`Computer Use: ${status.ready ? "ready" : status.enabled ? "not ready" : "disabled"}`];
372
388
  lines.push(`Plugin: ${formatCodexDisplayText(status.pluginName)} (${computerUsePluginState(status)})`);
@@ -380,6 +396,7 @@ function computerUsePluginState(status) {
380
396
  if (!status.installed) return "not installed";
381
397
  return status.pluginEnabled ? "installed" : "installed, disabled";
382
398
  }
399
+ /** Formats generic array-like Codex app-server responses. */
383
400
  function formatList(response, label) {
384
401
  const entries = extractArray(response);
385
402
  if (entries.length === 0) return `${label}: none returned.`;
@@ -388,6 +405,7 @@ function formatList(response, label) {
388
405
  return `- ${formatCodexDisplayText(readString$1(record, "name") ?? readString$1(record, "id") ?? JSON.stringify(entry))}`;
389
406
  })].join("\n");
390
407
  }
408
+ /** Formats Codex skills grouped by scope, omitting disabled entries. */
391
409
  function formatSkills(response) {
392
410
  const groups = isJsonObject(response) && Array.isArray(response.data) ? response.data : [];
393
411
  if (groups.length === 0) return "Codex skills: none returned.";
@@ -420,6 +438,7 @@ function formatCodexResumeHint(threadId) {
420
438
  if (!CODEX_RESUME_SAFE_THREAD_ID_PATTERN.test(safe)) return "copy the thread id above and run /codex resume <thread-id>";
421
439
  return `/codex resume ${safe}`;
422
440
  }
441
+ /** Escapes Codex-originated text so it is safe to render in chat command output. */
423
442
  function formatCodexDisplayText(value) {
424
443
  return escapeCodexChatText(formatCodexTextForDisplay(value));
425
444
  }
@@ -466,6 +485,7 @@ function isLikelyEmailAddress(value) {
466
485
  function isUnsafeDisplayCodePoint(codePoint) {
467
486
  return codePoint <= 31 || codePoint >= 127 && codePoint <= 159 || codePoint === 173 || codePoint === 1564 || codePoint === 6158 || codePoint >= 8203 && codePoint <= 8207 || codePoint >= 8234 && codePoint <= 8238 || codePoint >= 8288 && codePoint <= 8303 || codePoint === 65279 || codePoint >= 65529 && codePoint <= 65531 || codePoint >= 917504 && codePoint <= 917631;
468
487
  }
488
+ /** Builds the portable `/codex` command help text. */
469
489
  function buildHelp() {
470
490
  return [
471
491
  "Codex commands:",
@@ -568,22 +588,31 @@ function extractArray(value) {
568
588
  }
569
589
  return [];
570
590
  }
591
+ /** Reads and trims a non-empty string field from a JSON object. */
571
592
  function readString$1(record, key) {
572
593
  const value = record[key];
573
594
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
574
595
  }
575
596
  //#endregion
576
597
  //#region extensions/codex/src/app-server/notification-correlation.ts
598
+ /**
599
+ * Correlates Codex app-server notifications with the active thread/turn so
600
+ * projectors can ignore global or stale events without losing diagnostics.
601
+ */
602
+ /** Returns true when a notification payload belongs to the exact active thread and turn. */
577
603
  function isCodexNotificationForTurn(value, threadId, turnId) {
578
604
  if (!isJsonObject(value)) return false;
579
605
  return readCodexNotificationThreadId(value) === threadId && readCodexNotificationTurnId(value) === turnId;
580
606
  }
607
+ /** Reads a thread id from either top-level notification params or nested turn payloads. */
581
608
  function readCodexNotificationThreadId(record) {
582
609
  return readNestedTurnThreadId(record) ?? readString(record, "threadId");
583
610
  }
611
+ /** Reads a turn id from either top-level notification params or nested turn payloads. */
584
612
  function readCodexNotificationTurnId(record) {
585
613
  return readNestedTurnId(record) ?? readString(record, "turnId");
586
614
  }
615
+ /** Builds structured correlation details for logs when notification routing is ambiguous. */
587
616
  function describeCodexNotificationCorrelation(notification, active) {
588
617
  const params = isJsonObject(notification.params) ? notification.params : void 0;
589
618
  const turn = params && isJsonObject(params.turn) ? params.turn : void 0;
@@ -1,10 +1,17 @@
1
1
  import { GPT5_BEHAVIOR_CONTRACT, GPT5_HEARTBEAT_PROMPT_OVERLAY, renderGpt5PromptOverlay, resolveGpt5SystemPromptContribution } from "openclaw/plugin-sdk/provider-model-shared";
2
2
  //#region extensions/codex/prompt-overlay.ts
3
+ /**
4
+ * Codex prompt-overlay facade for GPT-5 behavior and heartbeat guidance.
5
+ */
6
+ /** GPT-5 behavior contract re-exported under the Codex provider namespace. */
3
7
  const CODEX_GPT5_BEHAVIOR_CONTRACT = GPT5_BEHAVIOR_CONTRACT;
8
+ /** Heartbeat prompt overlay re-exported under the Codex provider namespace. */
4
9
  const CODEX_GPT5_HEARTBEAT_PROMPT_OVERLAY = GPT5_HEARTBEAT_PROMPT_OVERLAY;
10
+ /** Resolves the Codex system-prompt contribution for GPT-5-family models. */
5
11
  function resolveCodexSystemPromptContribution(params) {
6
12
  return resolveGpt5SystemPromptContribution(params);
7
13
  }
14
+ /** Renders the Codex prompt overlay text for supported GPT-5-family models. */
8
15
  function renderCodexPromptOverlay(params) {
9
16
  return renderGpt5PromptOverlay(params);
10
17
  }
@@ -5494,6 +5494,10 @@ var TurnStartResponse_default = {
5494
5494
  };
5495
5495
  //#endregion
5496
5496
  //#region extensions/codex/src/app-server/protocol-validators.ts
5497
+ /**
5498
+ * Runtime validators for Codex app-server protocol payloads, including schema
5499
+ * normalization for generated JSON Schema before TypeBox compilation.
5500
+ */
5497
5501
  function compileCodexSchema(schema) {
5498
5502
  const validator = Compile(normalizeJsonSchemaNode(schema));
5499
5503
  return {
@@ -5613,30 +5617,39 @@ const validateThreadResumeResponse = compileCodexSchema(ThreadResumeResponse_def
5613
5617
  const validateThreadStartResponse = compileCodexSchema(ThreadStartResponse_default);
5614
5618
  const validateTurnCompletedNotification = compileCodexSchema(TurnCompletedNotification_default);
5615
5619
  const validateTurnStartResponse = compileCodexSchema(TurnStartResponse_default);
5620
+ /** Asserts and normalizes a Codex thread/start response. */
5616
5621
  function assertCodexThreadStartResponse(value) {
5617
5622
  return assertCodexShape(validateThreadStartResponse, normalizeWithDefaults(ThreadStartResponse_default, normalizeThreadResponse(value)), "thread/start response");
5618
5623
  }
5624
+ /** Asserts and normalizes a Codex thread/fork response. */
5619
5625
  function assertCodexThreadForkResponse(value) {
5620
5626
  return assertCodexShape(validateThreadStartResponse, normalizeWithDefaults(ThreadStartResponse_default, normalizeThreadResponse(value)), "thread/fork response");
5621
5627
  }
5628
+ /** Asserts and normalizes a Codex thread/resume response. */
5622
5629
  function assertCodexThreadResumeResponse(value) {
5623
5630
  return assertCodexShape(validateThreadResumeResponse, normalizeWithDefaults(ThreadResumeResponse_default, normalizeThreadResponse(value)), "thread/resume response");
5624
5631
  }
5632
+ /** Asserts and normalizes a Codex turn/start response. */
5625
5633
  function assertCodexTurnStartResponse(value) {
5626
5634
  return assertCodexShape(validateTurnStartResponse, normalizeWithDefaults(TurnStartResponse_default, normalizeTurnStartResponse(value)), "turn/start response");
5627
5635
  }
5636
+ /** Reads Codex dynamic-tool call params, returning undefined for invalid payloads. */
5628
5637
  function readCodexDynamicToolCallParams(value) {
5629
5638
  return readCodexShape(validateDynamicToolCallParams, normalizeWithDefaults(DynamicToolCallParams_default, value));
5630
5639
  }
5640
+ /** Reads a Codex error notification payload if it matches the protocol schema. */
5631
5641
  function readCodexErrorNotification(value) {
5632
5642
  return readCodexShape(validateErrorNotification, normalizeWithDefaults(ErrorNotification_default, value));
5633
5643
  }
5644
+ /** Reads a Codex model/list response if it matches the protocol schema. */
5634
5645
  function readCodexModelListResponse(value) {
5635
5646
  return readCodexShape(validateModelListResponse, normalizeWithDefaults(ModelListResponse_default, value));
5636
5647
  }
5648
+ /** Reads and normalizes a Codex turn object. */
5637
5649
  function readCodexTurn(value) {
5638
5650
  return readCodexShape(validateTurnStartResponse, normalizeWithDefaults(TurnStartResponse_default, { turn: normalizeTurn(value) }))?.turn;
5639
5651
  }
5652
+ /** Reads a Codex turn/completed notification payload if it matches the protocol schema. */
5640
5653
  function readCodexTurnCompletedNotification(value) {
5641
5654
  return readCodexShape(validateTurnCompletedNotification, normalizeWithDefaults(TurnCompletedNotification_default, normalizeTurnCompletedNotification(value)));
5642
5655
  }
@@ -1,9 +1,13 @@
1
1
  //#region extensions/codex/provider-catalog.ts
2
+ /** Provider id used by Codex model refs. */
2
3
  const CODEX_PROVIDER_ID = "codex";
4
+ /** Synthetic base URL used to route Codex app-server model requests. */
3
5
  const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
6
+ /** Synthetic auth marker understood by Codex app-server runtime paths. */
4
7
  const CODEX_APP_SERVER_AUTH_MARKER = "codex-app-server";
5
8
  const DEFAULT_CONTEXT_WINDOW = 272e3;
6
9
  const DEFAULT_MAX_TOKENS = 128e3;
10
+ /** Offline fallback catalog used when live app-server discovery is unavailable. */
7
11
  const FALLBACK_CODEX_MODELS = [{
8
12
  id: "gpt-5.5",
9
13
  model: "gpt-5.5",
@@ -30,6 +34,9 @@ const FALLBACK_CODEX_MODELS = [{
30
34
  "xhigh"
31
35
  ]
32
36
  }];
37
+ /**
38
+ * Converts a Codex app-server model record into OpenClaw provider model config.
39
+ */
33
40
  function buildCodexModelDefinition(model) {
34
41
  const id = model.id.trim() || model.model.trim();
35
42
  return {
@@ -52,6 +59,7 @@ function buildCodexModelDefinition(model) {
52
59
  }
53
60
  };
54
61
  }
62
+ /** Builds the synthetic Codex provider config for a model list. */
55
63
  function buildCodexProviderConfig(models) {
56
64
  return {
57
65
  baseUrl: CODEX_BASE_URL,
@@ -10,6 +10,7 @@ async function runCodexCatalog(ctx) {
10
10
  pluginConfig: resolveCodexPluginConfig(ctx)
11
11
  });
12
12
  }
13
+ /** Provider discovery descriptor with static fallback and synthetic auth. */
13
14
  const codexProviderDiscovery = {
14
15
  id: CODEX_PROVIDER_ID,
15
16
  label: "Codex",
package/dist/provider.js CHANGED
@@ -5,12 +5,19 @@ import { resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-run
5
5
  import { normalizeModelCompat } from "openclaw/plugin-sdk/provider-model-shared";
6
6
  import { createSubsystemLogger } from "openclaw/plugin-sdk/core";
7
7
  //#region extensions/codex/provider.ts
8
+ /**
9
+ * Codex provider plugin and live app-server model catalog discovery.
10
+ */
8
11
  const DEFAULT_DISCOVERY_TIMEOUT_MS = 2500;
9
12
  const LIVE_DISCOVERY_ENV = "OPENCLAW_CODEX_DISCOVERY_LIVE";
10
13
  const MODEL_DISCOVERY_PAGE_LIMIT = 100;
11
14
  const CODEX_APP_SERVER_SETUP_METHOD_ID = "app-server";
12
15
  const CODEX_DEFAULT_MODEL_REF = `${CODEX_PROVIDER_ID}/${FALLBACK_CODEX_MODELS[0].id}`;
13
16
  const codexCatalogLog = createSubsystemLogger("codex/catalog");
17
+ /**
18
+ * Builds the Codex provider plugin, including setup metadata, catalog discovery,
19
+ * dynamic model resolution, and prompt/thinking hooks.
20
+ */
14
21
  function buildCodexProvider(options = {}) {
15
22
  return {
16
23
  id: CODEX_PROVIDER_ID,
@@ -72,6 +79,10 @@ function buildCodexProvider(options = {}) {
72
79
  isModernModelRef: ({ modelId }) => isModernCodexModel(modelId)
73
80
  };
74
81
  }
82
+ /**
83
+ * Builds the Codex model catalog from live app-server discovery, falling back
84
+ * to built-in model records when discovery is disabled or unavailable.
85
+ */
75
86
  async function buildCodexProviderCatalog(options = {}) {
76
87
  const config = readCodexPluginConfig(options.pluginConfig);
77
88
  const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: options.pluginConfig });
@@ -123,7 +134,7 @@ async function listModelsBestEffort(params) {
123
134
  }
124
135
  }
125
136
  async function listCodexAppServerModelsLazy(options) {
126
- const { listCodexAppServerModels } = await import("./models-D8i1zWEu.js").then((n) => n.r);
137
+ const { listCodexAppServerModels } = await import("./models-DXorTaja.js").then((n) => n.r);
127
138
  return listCodexAppServerModels(options);
128
139
  }
129
140
  function normalizeTimeoutMs(value) {
@@ -142,6 +153,10 @@ function isKnownXHighCodexModel(modelId) {
142
153
  const lower = modelId.trim().toLowerCase();
143
154
  return lower.startsWith("gpt-5") || lower.startsWith("o3") || lower.startsWith("o4") || lower.includes("codex");
144
155
  }
156
+ /**
157
+ * Returns true for Codex models that use the modern reasoning effort enum and
158
+ * reject the legacy CLI `minimal` default.
159
+ */
145
160
  function isModernCodexModel(modelId) {
146
161
  const lower = modelId.trim().toLowerCase();
147
162
  return lower === "gpt-5.5" || lower === "gpt-5.4" || lower === "gpt-5.4-mini" || lower === "gpt-5.3-codex-spark";
@@ -6,12 +6,14 @@ function getCodexRateLimitCacheState() {
6
6
  globalState[CODEX_RATE_LIMIT_CACHE_STATE] ??= {};
7
7
  return globalState[CODEX_RATE_LIMIT_CACHE_STATE];
8
8
  }
9
+ /** Stores a non-empty Codex rate-limit payload with its observation time. */
9
10
  function rememberCodexRateLimits(value, nowMs = Date.now()) {
10
11
  if (value === void 0) return;
11
12
  const state = getCodexRateLimitCacheState();
12
13
  state.value = value;
13
14
  state.updatedAtMs = nowMs;
14
15
  }
16
+ /** Reads the cached Codex rate-limit payload when it is still within the max-age window. */
15
17
  function readRecentCodexRateLimits(options) {
16
18
  const state = getCodexRateLimitCacheState();
17
19
  if (state.value === void 0 || state.updatedAtMs === void 0) return;
@@ -1,9 +1,13 @@
1
- import { n as CodexAppServerRpcError } from "./client-BFxKzFnH.js";
2
- import { b as buildCodexAppInventoryCacheKey } from "./thread-lifecycle-BOYYMjx6.js";
3
- import { a as getLeasedSharedCodexAppServerClient, h as resolveCodexAppServerHomeDir, i as createIsolatedCodexAppServerClient, l as withTimeout, o as releaseLeasedSharedCodexAppServerClient } from "./shared-client-B31-oqN-.js";
4
- import { t as resolveCodexAppServerDirectSandboxBypassBlock } from "./sandbox-guard-DMCJlzmz.js";
1
+ import { n as CodexAppServerRpcError } from "./client-kMCtlApt.js";
2
+ import { b as buildCodexAppInventoryCacheKey } from "./thread-lifecycle-BJsazZ8j.js";
3
+ import { a as getLeasedSharedCodexAppServerClient, h as resolveCodexAppServerHomeDir, i as createIsolatedCodexAppServerClient, l as withTimeout, o as releaseLeasedSharedCodexAppServerClient } from "./shared-client-xytpSKD0.js";
4
+ import { t as resolveCodexAppServerDirectSandboxBypassBlock } from "./sandbox-guard-C-Yv9uwY.js";
5
5
  import { createHash } from "node:crypto";
6
6
  //#region extensions/codex/src/app-server/capabilities.ts
7
+ /**
8
+ * Capability helpers for optional Codex app-server control-plane methods.
9
+ */
10
+ /** Known app-server methods used by OpenClaw control surfaces. */
7
11
  const CODEX_CONTROL_METHODS = {
8
12
  account: "account/read",
9
13
  compact: "thread/compact/start",
@@ -15,6 +19,7 @@ const CODEX_CONTROL_METHODS = {
15
19
  resumeThread: "thread/resume",
16
20
  review: "review/start"
17
21
  };
22
+ /** Formats unsupported control calls differently from ordinary RPC failures. */
18
23
  function describeControlFailure(error) {
19
24
  if (isUnsupportedControlError(error)) return "unsupported by this Codex app-server";
20
25
  return error instanceof Error ? error.message : String(error);
@@ -24,6 +29,11 @@ function isUnsupportedControlError(error) {
24
29
  }
25
30
  //#endregion
26
31
  //#region extensions/codex/src/app-server/plugin-app-cache-key.ts
32
+ /**
33
+ * Builds stable Codex plugin/app inventory cache keys from app-server startup,
34
+ * auth, account, and version inputs without storing secret material.
35
+ */
36
+ /** Builds the full app inventory cache key for Codex plugin/app discovery. */
27
37
  function buildCodexPluginAppCacheKey(params) {
28
38
  return buildCodexAppInventoryCacheKey({
29
39
  codexHome: resolveCodexPluginAppCacheCodexHome(params.appServer, params.agentDir),
@@ -34,6 +44,7 @@ function buildCodexPluginAppCacheKey(params) {
34
44
  appServerVersion: params.appServerVersion
35
45
  });
36
46
  }
47
+ /** Serializes app-server endpoint identity, including credential fingerprints. */
37
48
  function resolveCodexPluginAppCacheEndpoint(appServer) {
38
49
  return JSON.stringify({
39
50
  transport: appServer.start.transport,
@@ -43,6 +54,7 @@ function resolveCodexPluginAppCacheEndpoint(appServer) {
43
54
  credentialFingerprint: fingerprintCodexPluginAppCacheCredentials(appServer.start)
44
55
  });
45
56
  }
57
+ /** Resolves the CODEX_HOME value that scopes local app-server inventory. */
46
58
  function resolveCodexPluginAppCacheCodexHome(appServer, agentDir) {
47
59
  const configuredCodexHome = appServer.start.env?.CODEX_HOME?.trim();
48
60
  if (configuredCodexHome) return configuredCodexHome;