@openclaw/codex 2026.6.5-beta.6 → 2026.6.6-beta.1

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 (27) hide show
  1. package/dist/{client-kMCtlApt.js → client-DovmVtbr.js} +3 -10
  2. package/dist/{client-factory-Bt49r45B.js → client-factory-XajDuvQ1.js} +1 -1
  3. package/dist/{command-handlers-DMn2M7W7.js → command-handlers-DIUFKqaF.js} +11 -9
  4. package/dist/{compact-CwnPeYnM.js → compact-BWiNkDSs.js} +96 -9
  5. package/dist/{computer-use-ClweWaMz.js → computer-use-D3pi5csE.js} +3 -2
  6. package/dist/{config-BT6SLiE6.js → config-DJXpBkGf.js} +214 -13
  7. package/dist/{conversation-binding-CzpvaBs1.js → conversation-binding-CMwrZrt7.js} +190 -65
  8. package/dist/harness.js +12 -5
  9. package/dist/index.js +11 -10
  10. package/dist/media-understanding-provider.js +6 -6
  11. package/dist/{models-DXorTaja.js → models-CQGfP7nG.js} +2 -2
  12. package/dist/{native-hook-relay-DHwz_ICg.js → native-hook-relay-CmUUO3Eu.js} +160 -4
  13. package/dist/notification-correlation-D-MYfJwV.js +382 -0
  14. package/dist/{request-D64BfplD.js → plugin-app-cache-key-NpzxEcSR.js} +4 -36
  15. package/dist/protocol-oeJQu4rs.js +9 -0
  16. package/dist/{protocol-validators-CIpP8IJ2.js → protocol-validators-B48C6S9O.js} +2296 -2273
  17. package/dist/provider-Cs6kWhDQ.js +584 -0
  18. package/dist/provider.js +1 -164
  19. package/dist/request-Dq0LUOqZ.js +36 -0
  20. package/dist/{run-attempt-BWdNnok4.js → run-attempt-DG9p9ReO.js} +374 -65
  21. package/dist/{session-binding-BgTv_YGm.js → session-binding-ElbcSq2o.js} +107 -44
  22. package/dist/{shared-client-xytpSKD0.js → shared-client-CflavQ_i.js} +3 -3
  23. package/dist/{side-question-BnvBQPqW.js → side-question-Ctu2VXAG.js} +82 -26
  24. package/dist/{thread-lifecycle-BJsazZ8j.js → thread-lifecycle-Cq1-IfZB.js} +115 -34
  25. package/npm-shrinkwrap.json +30 -30
  26. package/package.json +5 -5
  27. package/dist/notification-correlation-o8quHmTK.js +0 -656
@@ -1,4 +1,5 @@
1
- import { l as resolveCodexAppServerRuntimeOptions } from "./config-BT6SLiE6.js";
1
+ import { d as resolveCodexAppServerRuntimeOptions } from "./config-DJXpBkGf.js";
2
+ import { n as isRpcResponse } from "./protocol-oeJQu4rs.js";
2
3
  import { materializeWindowsSpawnProgram, resolveWindowsSpawnProgram } from "openclaw/plugin-sdk/windows-spawn";
3
4
  import { OPENCLAW_VERSION, embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
4
5
  import { createInterface } from "node:readline";
@@ -6,14 +7,6 @@ import { spawn } from "node:child_process";
6
7
  import { EventEmitter } from "node:events";
7
8
  import { PassThrough, Writable } from "node:stream";
8
9
  import WebSocket from "ws";
9
- //#region extensions/codex/src/app-server/protocol.ts
10
- function isJsonObject$1(value) {
11
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
12
- }
13
- function isRpcResponse(message) {
14
- return "id" in message && !("method" in message);
15
- }
16
- //#endregion
17
10
  //#region extensions/codex/src/app-server/transport-stdio.ts
18
11
  /**
19
12
  * Creates and configures stdio-backed Codex app-server transports, including
@@ -711,4 +704,4 @@ function formatExitValue(value) {
711
704
  return "unknown";
712
705
  }
713
706
  //#endregion
714
- export { isCodexAppServerConnectionClosedError as a, resolveCodexAppServerSpawnEnv as c, isCodexAppServerApprovalRequest as i, isJsonObject$1 as l, CodexAppServerRpcError as n, MANAGED_CODEX_APP_SERVER_PACKAGE as o, compareCodexAppServerVersions as r, MIN_CODEX_SANDBOX_EXEC_SERVER_APP_SERVER_VERSION as s, CodexAppServerClient as t };
707
+ export { isCodexAppServerConnectionClosedError as a, resolveCodexAppServerSpawnEnv as c, isCodexAppServerApprovalRequest as i, CodexAppServerRpcError as n, MANAGED_CODEX_APP_SERVER_PACKAGE as o, compareCodexAppServerVersions as r, MIN_CODEX_SANDBOX_EXEC_SERVER_APP_SERVER_VERSION as s, CodexAppServerClient as t };
@@ -1,7 +1,7 @@
1
1
  //#region extensions/codex/src/app-server/client-factory.ts
2
2
  let sharedClientModulePromise = null;
3
3
  const loadSharedClientModule = async () => {
4
- sharedClientModulePromise ??= import("./shared-client-xytpSKD0.js").then((n) => n.c);
4
+ sharedClientModulePromise ??= import("./shared-client-CflavQ_i.js").then((n) => n.c);
5
5
  return await sharedClientModulePromise;
6
6
  };
7
7
  /** Returns a leased shared client so startup can release ownership explicitly. */
@@ -1,17 +1,19 @@
1
- import { a as isCodexFastServiceTier, l as resolveCodexAppServerRuntimeOptions } from "./config-BT6SLiE6.js";
2
- import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-DXorTaja.js";
3
- import { l as isJsonObject } from "./client-kMCtlApt.js";
4
- import { a as readCodexAppServerBinding, s as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-BgTv_YGm.js";
5
- import { i as describeControlFailure, r as CODEX_CONTROL_METHODS, t as requestCodexAppServerJson } from "./request-D64BfplD.js";
6
- import { a as buildHelp, c as formatCodexStatus, d as formatModels, f as formatSkills, l as formatComputerUseStatus, m as readString$1, o as formatAccount, p as formatThreads, s as formatCodexDisplayText, u as formatList, v as summarizeCodexAccountUsage } from "./notification-correlation-o8quHmTK.js";
1
+ import { d as resolveCodexAppServerRuntimeOptions, o as isCodexFastServiceTier } from "./config-DJXpBkGf.js";
2
+ import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-CQGfP7nG.js";
3
+ import { t as isJsonObject } from "./protocol-oeJQu4rs.js";
4
+ import { l as summarizeCodexAccountUsage } from "./provider-Cs6kWhDQ.js";
5
+ import { l as writeCodexAppServerBinding, n as clearCodexAppServerBinding, o as readCodexAppServerBinding } from "./session-binding-ElbcSq2o.js";
6
+ import { n as CODEX_CONTROL_METHODS, r as describeControlFailure } from "./plugin-app-cache-key-NpzxEcSR.js";
7
+ import { c as formatAccount, d as formatComputerUseStatus, f as formatList, g as readString$1, h as formatThreads, l as formatCodexDisplayText, m as formatSkills, p as formatModels, s as buildHelp, u as formatCodexStatus } from "./notification-correlation-D-MYfJwV.js";
7
8
  import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-C-Yv9uwY.js";
8
- import { _ as steerCodexConversationTurn, b as readCodexConversationBindingData, d as parseCodexFastModeArg, f as parseCodexPermissionsModeArg, g as setCodexConversationPermissions, h as setCodexConversationModel, m as setCodexConversationFastMode, o as formatCodexCliSessions, p as readCodexConversationActiveTurn, r as startCodexConversationThread, u as formatPermissionsMode, v as stopCodexConversationTurn, x as resolveCodexDefaultWorkspaceDir, y as createCodexCliNodeConversationBindingData } from "./conversation-binding-CzpvaBs1.js";
9
- import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-ClweWaMz.js";
9
+ import { _ as steerCodexConversationTurn, b as readCodexConversationBindingData, d as parseCodexFastModeArg, f as parseCodexPermissionsModeArg, g as setCodexConversationPermissions, h as setCodexConversationModel, m as setCodexConversationFastMode, o as formatCodexCliSessions, p as readCodexConversationActiveTurn, r as startCodexConversationThread, u as formatPermissionsMode, v as stopCodexConversationTurn, x as resolveCodexDefaultWorkspaceDir, y as createCodexCliNodeConversationBindingData } from "./conversation-binding-CMwrZrt7.js";
10
+ import { t as requestCodexAppServerJson } from "./request-Dq0LUOqZ.js";
11
+ import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-D3pi5csE.js";
10
12
  import { n as rememberCodexRateLimits } from "./rate-limit-cache-C7qmZ0Jh.js";
11
13
  import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
12
14
  import crypto from "node:crypto";
13
- import { normalizeOptionalString, normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
14
15
  import { ensureAuthProfileStore, findNormalizedProviderValue, resolveAgentDir, resolveAuthProfileEligibility, resolveAuthProfileOrder, resolveDefaultAgentDir, resolveProfileUnusableUntilForDisplay, resolveSessionAgentIds } from "openclaw/plugin-sdk/agent-runtime";
16
+ import { normalizeOptionalString, normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
15
17
  //#region extensions/codex/src/command-account.ts
16
18
  const OPENAI_PROVIDER_ID = "openai";
17
19
  const OPENAI_CODEX_PROVIDER_ID = OPENAI_PROVIDER_ID;
@@ -1,8 +1,8 @@
1
- import { l as resolveCodexAppServerRuntimeOptions } from "./config-BT6SLiE6.js";
2
- import { a as readCodexAppServerBinding } from "./session-binding-BgTv_YGm.js";
3
- import { o as releaseLeasedSharedCodexAppServerClient } from "./shared-client-xytpSKD0.js";
1
+ import { d as resolveCodexAppServerRuntimeOptions } from "./config-DJXpBkGf.js";
2
+ import { c as withCodexAppServerBindingLock, l as writeCodexAppServerBinding, o as readCodexAppServerBinding, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-ElbcSq2o.js";
3
+ import { o as releaseLeasedSharedCodexAppServerClient } from "./shared-client-CflavQ_i.js";
4
4
  import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-C-Yv9uwY.js";
5
- import { t as defaultLeasedCodexAppServerClientFactory } from "./client-factory-Bt49r45B.js";
5
+ import { t as defaultLeasedCodexAppServerClientFactory } from "./client-factory-XajDuvQ1.js";
6
6
  import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
7
7
  //#region extensions/codex/src/app-server/compact.ts
8
8
  /**
@@ -71,7 +71,7 @@ function readRecord(value) {
71
71
  return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
72
72
  }
73
73
  async function compactCodexNativeThread(params, options = {}) {
74
- if (params.trigger !== "manual") {
74
+ if (params.trigger !== "manual" && !options.allowNonManualNativeRequest) {
75
75
  embeddedAgentLog.info("skipping codex app-server compaction for non-manual trigger", {
76
76
  sessionId: params.sessionId,
77
77
  sessionKey: params.sessionKey,
@@ -106,11 +106,12 @@ async function compactCodexNativeThread(params, options = {}) {
106
106
  reason: nativeExecutionBlock
107
107
  };
108
108
  const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: options.pluginConfig });
109
- const binding = await readCodexAppServerBinding(params.sessionFile, { config: params.config });
110
- if (!binding?.threadId) return failedCodexThreadBindingCompactionResult(params, {
109
+ const initialBinding = await readCodexAppServerBinding(params.sessionFile, { config: params.config });
110
+ if (!initialBinding?.threadId) return failedCodexThreadBindingCompactionResult(params, {
111
111
  reason: "no codex app-server thread binding",
112
112
  recovery: "missing_thread_binding"
113
113
  });
114
+ let binding = initialBinding;
114
115
  const requestedAuthProfileId = params.authProfileId?.trim() || void 0;
115
116
  if (requestedAuthProfileId && binding.authProfileId && binding.authProfileId !== requestedAuthProfileId) return {
116
117
  ok: false,
@@ -120,7 +121,47 @@ async function compactCodexNativeThread(params, options = {}) {
120
121
  const shouldReleaseDefaultLease = !options.clientFactory;
121
122
  const client = await (options.clientFactory ?? defaultLeasedCodexAppServerClientFactory)(appServer.start, requestedAuthProfileId ?? binding.authProfileId, params.agentDir, params.config);
122
123
  try {
123
- await client.request("thread/compact/start", { threadId: binding.threadId });
124
+ if (options.allowNonManualNativeRequest) {
125
+ const guardedResult = await withCodexAppServerBindingLock(params.sessionFile, async () => {
126
+ const currentBinding = await readCodexAppServerBinding(params.sessionFile, { config: params.config });
127
+ if (params.abortSignal?.aborted) return {
128
+ started: false,
129
+ result: skippedCodexNativeCompactionResult(params, {
130
+ reason: "codex app-server compaction aborted before native compaction",
131
+ code: "aborted_before_native_compaction",
132
+ expectedThreadId: binding.threadId,
133
+ currentThreadId: currentBinding?.threadId
134
+ })
135
+ };
136
+ if (!currentBinding || !isSameNativeCompactionBinding(currentBinding, binding)) {
137
+ embeddedAgentLog.warn("skipping codex app-server compaction because the thread binding changed", {
138
+ sessionId: params.sessionId,
139
+ sessionKey: params.sessionKey,
140
+ expectedThreadId: binding.threadId,
141
+ currentThreadId: currentBinding?.threadId
142
+ });
143
+ return {
144
+ started: false,
145
+ result: skippedCodexNativeCompactionResult(params, {
146
+ reason: "codex app-server binding changed before native compaction",
147
+ code: "binding_changed_before_native_compaction",
148
+ expectedThreadId: binding.threadId,
149
+ currentThreadId: currentBinding?.threadId
150
+ })
151
+ };
152
+ }
153
+ binding = currentBinding;
154
+ await clearContextEngineProjectionBeforeNativeCompaction({
155
+ sessionId: params.sessionId,
156
+ sessionFile: params.sessionFile,
157
+ binding,
158
+ config: params.config
159
+ });
160
+ await client.request("thread/compact/start", { threadId: binding.threadId }, { timeoutMs: Math.min(appServer.requestTimeoutMs, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS) });
161
+ return { started: true };
162
+ });
163
+ if (!guardedResult.started) return guardedResult.result;
164
+ } else await client.request("thread/compact/start", { threadId: binding.threadId });
124
165
  embeddedAgentLog.info("started codex app-server compaction", {
125
166
  sessionId: params.sessionId,
126
167
  threadId: binding.threadId
@@ -149,7 +190,11 @@ async function compactCodexNativeThread(params, options = {}) {
149
190
  backend: "codex-app-server",
150
191
  threadId: binding.threadId,
151
192
  signal: "thread/compact/start",
152
- pending: true
193
+ pending: true,
194
+ ...options.allowNonManualNativeRequest ? {
195
+ request: "after_context_engine",
196
+ trigger: params.trigger ?? "unknown"
197
+ } : {}
153
198
  };
154
199
  return {
155
200
  ok: true,
@@ -162,6 +207,27 @@ async function compactCodexNativeThread(params, options = {}) {
162
207
  }
163
208
  };
164
209
  }
210
+ function skippedCodexNativeCompactionResult(params, skipped) {
211
+ return {
212
+ ok: true,
213
+ compacted: false,
214
+ reason: skipped.reason,
215
+ result: {
216
+ summary: "",
217
+ firstKeptEntryId: "",
218
+ tokensBefore: params.currentTokenCount ?? 0,
219
+ details: {
220
+ backend: "codex-app-server",
221
+ skipped: true,
222
+ reason: skipped.code,
223
+ request: "after_context_engine",
224
+ trigger: params.trigger ?? "unknown",
225
+ ...skipped.expectedThreadId ? { expectedThreadId: skipped.expectedThreadId } : {},
226
+ ...skipped.currentThreadId ? { currentThreadId: skipped.currentThreadId } : {}
227
+ }
228
+ }
229
+ };
230
+ }
165
231
  function failedCodexThreadBindingCompactionResult(params, recovery) {
166
232
  embeddedAgentLog.warn("codex app-server compaction could not use thread binding", {
167
233
  sessionId: params.sessionId,
@@ -180,6 +246,27 @@ function failedCodexThreadBindingCompactionResult(params, recovery) {
180
246
  }
181
247
  };
182
248
  }
249
+ async function clearContextEngineProjectionBeforeNativeCompaction(params) {
250
+ const contextEngineBinding = params.binding.contextEngine;
251
+ if (!contextEngineBinding?.projection) return;
252
+ await writeCodexAppServerBinding(params.sessionFile, {
253
+ ...params.binding,
254
+ contextEngine: {
255
+ ...contextEngineBinding,
256
+ projection: void 0
257
+ },
258
+ createdAt: params.binding.createdAt
259
+ }, { config: params.config });
260
+ embeddedAgentLog.info("cleared codex context-engine projection before native compaction", {
261
+ sessionId: params.sessionId,
262
+ threadId: params.binding.threadId,
263
+ previousEpoch: contextEngineBinding.projection.epoch,
264
+ previousFingerprint: contextEngineBinding.projection.fingerprint
265
+ });
266
+ }
267
+ function isSameNativeCompactionBinding(current, expected) {
268
+ return current.threadId === expected.threadId && current.authProfileId === expected.authProfileId && current.contextEngine?.engineId === expected.contextEngine?.engineId && current.contextEngine?.policyFingerprint === expected.contextEngine?.policyFingerprint && current.contextEngine?.projection?.mode === expected.contextEngine?.projection?.mode && current.contextEngine?.projection?.epoch === expected.contextEngine?.projection?.epoch && current.contextEngine?.projection?.fingerprint === expected.contextEngine?.projection?.fingerprint;
269
+ }
183
270
  function isCodexThreadNotFoundError(error) {
184
271
  return formatCompactionError(error).toLowerCase().includes("thread not found");
185
272
  }
@@ -1,5 +1,6 @@
1
- import { l as resolveCodexAppServerRuntimeOptions, u as resolveCodexComputerUseConfig } from "./config-BT6SLiE6.js";
2
- import { i as describeControlFailure, t as requestCodexAppServerJson } from "./request-D64BfplD.js";
1
+ import { d as resolveCodexAppServerRuntimeOptions, f as resolveCodexComputerUseConfig } from "./config-DJXpBkGf.js";
2
+ import { r as describeControlFailure } from "./plugin-app-cache-key-NpzxEcSR.js";
3
+ import { t as requestCodexAppServerJson } from "./request-Dq0LUOqZ.js";
3
4
  import { existsSync } from "node:fs";
4
5
  //#region extensions/codex/src/app-server/computer-use.ts
5
6
  /**
@@ -2,6 +2,8 @@ import { resolvePositiveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtim
2
2
  import { createHmac, randomBytes } from "node:crypto";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { hostname } from "node:os";
5
+ import path from "node:path";
6
+ import { resolveProviderIdForAuth } from "openclaw/plugin-sdk/agent-runtime";
5
7
  import { resolveExecApprovalsFromFile } from "openclaw/plugin-sdk/exec-approvals-runtime";
6
8
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
7
9
  import { normalizeTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -12,6 +14,8 @@ const START_OPTIONS_KEY_SECRET_SYMBOL = Symbol.for("openclaw.codexAppServerStart
12
14
  const START_OPTIONS_KEY_SECRET = getStartOptionsKeySecret();
13
15
  const UNIX_CODEX_REQUIREMENTS_PATH = "/etc/codex/requirements.toml";
14
16
  const WINDOWS_CODEX_REQUIREMENTS_SUFFIX = "\\OpenAI\\Codex\\requirements.toml";
17
+ const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
18
+ const CODEX_CONFIG_TOML_FILENAME = "config.toml";
15
19
  const PLAIN_DECIMAL_NUMBER_RE = /^[+-]?(?:(?:\d+\.?\d*)|(?:\.\d+))$/;
16
20
  const CODEX_PLUGINS_MARKETPLACE_NAME = "openai-curated";
17
21
  function shouldAutoApproveCodexAppServerApprovals(appServer) {
@@ -160,21 +164,31 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
160
164
  const explicitApprovalsReviewer = resolveApprovalsReviewer(config.approvalsReviewer);
161
165
  const normalizedPolicyMode = resolveCodexPolicyModeForOpenClawExecMode(execMode);
162
166
  const ignoreLegacyYoloPolicyMode = normalizedPolicyMode === "guardian" && explicitPolicyMode === "yolo";
163
- const forceUserReviewer = execMode !== void 0 && execMode !== "auto" && execMode !== "full";
164
- const forceGuardianReviewer = execMode === "auto";
167
+ const canUseModelBackedReviewer = canUseCodexModelBackedApprovalsReviewerForModel({
168
+ modelProvider: params.modelProvider,
169
+ model: params.model,
170
+ config: params.config,
171
+ env,
172
+ agentDir: params.agentDir,
173
+ codexConfigToml: params.codexConfigToml
174
+ });
175
+ const forceUserReviewer = !canUseModelBackedReviewer && (explicitApprovalsReviewer === "auto_review" || explicitApprovalsReviewer === "guardian_subagent" || explicitPolicyMode === "guardian" && explicitApprovalsReviewer !== "user") || execMode !== void 0 && execMode !== "full" && (execMode !== "auto" || !canUseModelBackedReviewer);
176
+ const forceGuardianReviewer = execMode === "auto" && canUseModelBackedReviewer;
177
+ const execModeRequiringPromptingApprovals = execMode === "auto" || execMode === "ask" ? execMode : forceUserReviewer ? "ask" : void 0;
165
178
  const forceDangerFullAccessSandbox = params.execPolicy?.touched === true && params.execPolicy.security === "full" && params.execPolicy.ask === "always";
166
179
  const forceRuntimePolicy = forceUserReviewer || forceGuardianReviewer || forceDangerFullAccessSandbox;
167
180
  const defaultPolicy = explicitPolicyMode && !forceRuntimePolicy && !ignoreLegacyYoloPolicyMode ? void 0 : resolveDefaultCodexAppServerPolicy({
168
181
  transport,
169
182
  env,
170
183
  forceGuardian: normalizedPolicyMode === "guardian",
171
- forceUserReviewer,
172
- execModeRequiringPromptingApprovals: execMode === "auto" || execMode === "ask" ? execMode : void 0,
184
+ forceUserReviewer: forceUserReviewer || !canUseModelBackedReviewer,
185
+ execModeRequiringPromptingApprovals,
173
186
  requirementsToml: params.requirementsToml,
174
187
  requirementsPath: params.requirementsPath,
175
188
  readRequirementsFile: params.readRequirementsFile,
176
189
  platform: params.platform,
177
- hostName: params.hostName
190
+ hostName: params.hostName,
191
+ execModeRequiringUserReviewer: forceUserReviewer ? execMode : void 0
178
192
  });
179
193
  const preserveExplicitAutoSandbox = forceGuardianReviewer && configuredSandbox === "read-only";
180
194
  const forcedPolicy = forceRuntimePolicy ? {
@@ -228,6 +242,48 @@ function isCodexAppServerApprovalPolicyAllowedByRequirements(policy, params = {}
228
242
  const allowedApprovalPolicies = parseAllowedApprovalPoliciesFromCodexRequirements(content);
229
243
  return allowedApprovalPolicies === void 0 || allowedApprovalPolicies.has(policy);
230
244
  }
245
+ function canUseCodexModelBackedApprovalsReviewerForModel(params) {
246
+ const explicitProvider = params.modelProvider?.trim().toLowerCase();
247
+ const inferredProvider = inferProviderFromModelRef(params.model);
248
+ if (explicitProvider && explicitProvider !== "codex") return isTrustedCodexModelBackedApprovalsReviewerProvider(explicitProvider, params) && (inferredProvider === void 0 || isTrustedCodexModelBackedApprovalsReviewerProvider(inferredProvider, params));
249
+ if (inferredProvider !== void 0) return isTrustedCodexModelBackedApprovalsReviewerProvider(inferredProvider, params);
250
+ return isTrustedCodexModelBackedApprovalsReviewerProvider(explicitProvider, params);
251
+ }
252
+ function isTrustedCodexModelBackedOpenAIProvider(params) {
253
+ if (!openAIBaseUrlEnvOverridesAreTrustedForModelBackedReview(params.env)) return false;
254
+ const codexBaseUrlOverrides = readCodexBaseUrlOverridesForModelBackedReview(params);
255
+ if (codexBaseUrlOverrides === false || !codexBaseUrlOverrides.openAI.every(isNativeOpenAIBaseUrl) || !codexBaseUrlOverrides.chatGPT.every(isNativeChatGPTBaseUrl)) return false;
256
+ const openAIProviders = readConfiguredOpenAIProvidersForModelBackedReview(params.config);
257
+ if (openAIProviders.length === 0) return true;
258
+ return openAIProviders.every((openAIProvider) => configuredOpenAIProviderIsTrustedForModelBackedReview(openAIProvider, params.model));
259
+ }
260
+ function resolveCodexModelBackedReviewerPolicyContext(params) {
261
+ const provider = params.provider?.trim();
262
+ if (provider && provider.toLowerCase() !== "codex") return {
263
+ modelProvider: normalizeCodexModelBackedReviewerPolicyProvider(provider),
264
+ model: params.model
265
+ };
266
+ const bindingModelProvider = params.bindingModelProvider?.trim();
267
+ const currentModel = params.model?.trim();
268
+ const bindingModel = params.bindingModel?.trim();
269
+ if (bindingModelProvider && currentModel && bindingModel && currentModel === bindingModel) return {
270
+ modelProvider: normalizeCodexModelBackedReviewerPolicyProvider(bindingModelProvider),
271
+ model: params.model ?? params.bindingModel
272
+ };
273
+ const currentModelProvider = inferProviderFromModelRef(params.model);
274
+ if (currentModelProvider) return {
275
+ modelProvider: normalizeCodexModelBackedReviewerPolicyProvider(currentModelProvider),
276
+ model: params.model
277
+ };
278
+ if (bindingModelProvider) return {
279
+ modelProvider: normalizeCodexModelBackedReviewerPolicyProvider(bindingModelProvider),
280
+ model: params.model ?? params.bindingModel
281
+ };
282
+ return {
283
+ modelProvider: params.nativeAuthProfile === true ? "openai" : void 0,
284
+ model: params.model ?? params.bindingModel
285
+ };
286
+ }
231
287
  function resolveCodexComputerUseConfig(params = {}) {
232
288
  const env = params.env ?? process.env;
233
289
  const config = readCodexPluginConfig(params.pluginConfig).computerUse ?? {};
@@ -314,7 +370,7 @@ function resolveDefaultCodexAppServerPolicy(params) {
314
370
  mode: "guardian",
315
371
  dangerFullAccessAllowed: true,
316
372
  approvalPolicy: selectGuardianApprovalPolicy(void 0, params.execModeRequiringPromptingApprovals),
317
- approvalsReviewer: params.forceUserReviewer ? selectUserApprovalsReviewer(void 0) : selectGuardianApprovalsReviewer(void 0, params.execModeRequiringPromptingApprovals === "auto" ? "auto" : void 0),
373
+ approvalsReviewer: params.forceUserReviewer ? selectUserApprovalsReviewer(void 0, params.execModeRequiringUserReviewer) : selectGuardianApprovalsReviewer(void 0, params.execModeRequiringPromptingApprovals === "auto" ? "auto" : void 0),
318
374
  sandbox: selectGuardianSandbox(void 0)
319
375
  };
320
376
  }
@@ -332,16 +388,16 @@ function resolveDefaultCodexAppServerPolicy(params) {
332
388
  mode: "guardian",
333
389
  dangerFullAccessAllowed: yoloSandboxAllowed,
334
390
  approvalPolicy: selectGuardianApprovalPolicy(allowedApprovalPolicies, params.execModeRequiringPromptingApprovals),
335
- approvalsReviewer: params.forceUserReviewer ? selectUserApprovalsReviewer(allowedApprovalsReviewers) : selectGuardianApprovalsReviewer(allowedApprovalsReviewers, params.execModeRequiringPromptingApprovals === "auto" ? "auto" : void 0),
391
+ approvalsReviewer: params.forceUserReviewer ? selectUserApprovalsReviewer(allowedApprovalsReviewers, params.execModeRequiringUserReviewer) : selectGuardianApprovalsReviewer(allowedApprovalsReviewers, params.execModeRequiringPromptingApprovals === "auto" ? "auto" : void 0),
336
392
  sandbox: selectGuardianSandbox(allowedSandboxModes)
337
393
  };
338
394
  }
339
395
  function readCodexRequirementsToml(params) {
340
396
  if (params.requirementsToml !== void 0) return params.requirementsToml ?? void 0;
341
- const path = readNonEmptyString(params.requirementsPath) ?? resolveCodexRequirementsPath(params.env ?? process.env, params.platform ?? process.platform);
397
+ const requirementsPath = readNonEmptyString(params.requirementsPath) ?? resolveCodexRequirementsPath(params.env ?? process.env, params.platform ?? process.platform);
342
398
  try {
343
- if (params.readRequirementsFile) return params.readRequirementsFile(path);
344
- return readFileSync(path, "utf8");
399
+ if (params.readRequirementsFile) return params.readRequirementsFile(requirementsPath);
400
+ return readFileSync(requirementsPath, "utf8");
345
401
  } catch {
346
402
  return;
347
403
  }
@@ -384,6 +440,24 @@ function parseRequirementsSandboxModes(values) {
384
440
  function parseTopLevelRequirementsStringArray(content, key) {
385
441
  return parseRequirementsStringArray(stripTomlLineComments(content).slice(0, firstTomlTableOffset(content)), key);
386
442
  }
443
+ function parseTomlStringValue(content, key) {
444
+ const match = parseTomlStringAssignment(content, tomlDottedKeyPattern(key));
445
+ return match ? match[1] ?? match[2] ?? "" : void 0;
446
+ }
447
+ function parseInlineOpenAIModelProviderBaseUrl(content) {
448
+ const match = parseTomlStringAssignment(content, `${tomlKeyPattern("model_providers")}\\s*=\\s*\\{[\\s\\S]*?${tomlKeyPattern("openai")}\\s*=\\s*\\{[\\s\\S]*?${tomlKeyPattern("base_url")}`);
449
+ return match ? match[1] ?? match[2] ?? "" : void 0;
450
+ }
451
+ function parseTomlStringAssignment(content, keyPattern) {
452
+ return content.match(new RegExp(`(?:^|\\n)\\s*${keyPattern}\\s*=\\s*(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|'([^']*)')`));
453
+ }
454
+ function tomlDottedKeyPattern(key) {
455
+ return key.split(".").map(tomlKeyPattern).join("\\s*\\.\\s*");
456
+ }
457
+ function tomlKeyPattern(key) {
458
+ const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
459
+ return `(?:"${escaped}"|'${escaped}'|${escaped})`;
460
+ }
387
461
  function parseRequirementsStringArray(content, key) {
388
462
  const match = content.match(new RegExp(`(?:^|\\n)\\s*${key}\\s*=\\s*\\[([\\s\\S]*?)\\]`));
389
463
  if (!match) return;
@@ -392,6 +466,16 @@ function parseRequirementsStringArray(content, key) {
392
466
  if (stringMatches.length === 0 && arrayBody.trim().length > 0) return;
393
467
  return stringMatches.map((entry) => entry[1] ?? entry[2] ?? "");
394
468
  }
469
+ function parseTomlTableSection(content, table) {
470
+ const strippedContent = stripTomlLineComments(content);
471
+ const tablePattern = tomlDottedKeyPattern(table);
472
+ const match = new RegExp(`^\\s*\\[\\s*${tablePattern}\\s*\\]\\s*$`, "m").exec(strippedContent);
473
+ if (!match) return;
474
+ const sectionStart = match.index + match[0].length;
475
+ const rest = strippedContent.slice(sectionStart);
476
+ const nextTableOffset = rest.search(/^\s*\[/m);
477
+ return nextTableOffset === -1 ? rest : rest.slice(0, nextTableOffset);
478
+ }
395
479
  function parseTomlArrayTableSections(content, table) {
396
480
  const strippedContent = stripTomlLineComments(content);
397
481
  const escapedTable = table.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -486,9 +570,126 @@ function selectGuardianApprovalsReviewer(allowedApprovalsReviewers, execModeRequ
486
570
  if (allowedApprovalsReviewers.has("user")) return "user";
487
571
  return "auto_review";
488
572
  }
489
- function selectUserApprovalsReviewer(allowedApprovalsReviewers) {
573
+ function selectUserApprovalsReviewer(allowedApprovalsReviewers, execModeRequiringUserReviewer) {
490
574
  if (allowedApprovalsReviewers === void 0 || allowedApprovalsReviewers.has("user")) return "user";
491
- throw new Error("tools.exec.mode=ask requires Codex app-server user approvals");
575
+ throw new Error(`tools.exec.mode=${execModeRequiringUserReviewer ?? "ask"} requires Codex app-server user approvals`);
576
+ }
577
+ function isCodexModelBackedApprovalsReviewerProvider(provider) {
578
+ return provider?.trim().toLowerCase() === "openai";
579
+ }
580
+ function isTrustedCodexModelBackedApprovalsReviewerProvider(provider, params) {
581
+ return isCodexModelBackedApprovalsReviewerProvider(provider) && isTrustedCodexModelBackedOpenAIProvider({
582
+ config: params.config,
583
+ env: params.env,
584
+ model: params.model,
585
+ agentDir: params.agentDir,
586
+ codexConfigToml: params.codexConfigToml
587
+ });
588
+ }
589
+ function readCodexBaseUrlOverridesForModelBackedReview(params) {
590
+ const configToml = readCodexAppServerConfigToml(params);
591
+ if (configToml === false) return false;
592
+ if (configToml === void 0) return {
593
+ openAI: [],
594
+ chatGPT: []
595
+ };
596
+ const topLevelContent = stripTomlLineComments(configToml).slice(0, firstTomlTableOffset(configToml));
597
+ const modelProviderOpenAISection = parseTomlTableSection(configToml, "model_providers.openai");
598
+ return {
599
+ openAI: [
600
+ parseTomlStringValue(topLevelContent, "openai_base_url"),
601
+ parseTomlStringValue(topLevelContent, "model_providers.openai.base_url"),
602
+ parseInlineOpenAIModelProviderBaseUrl(topLevelContent),
603
+ modelProviderOpenAISection ? parseTomlStringValue(modelProviderOpenAISection, "base_url") : void 0
604
+ ].filter((entry) => entry !== void 0),
605
+ chatGPT: [parseTomlStringValue(topLevelContent, "chatgpt_base_url")].filter((entry) => entry !== void 0)
606
+ };
607
+ }
608
+ function readCodexAppServerConfigToml(params) {
609
+ if (params.codexConfigToml !== void 0) return params.codexConfigToml ?? void 0;
610
+ const configPath = resolveCodexAppServerConfigPath(params);
611
+ if (!configPath) return;
612
+ try {
613
+ return readFileSync(configPath, "utf8");
614
+ } catch (error) {
615
+ return readErrorCode(error) === "ENOENT" ? void 0 : false;
616
+ }
617
+ }
618
+ function resolveCodexAppServerConfigPath(params) {
619
+ const agentDir = readNonEmptyString(params.agentDir);
620
+ const codexHome = agentDir ? path.join(path.resolve(agentDir), CODEX_APP_SERVER_HOME_DIRNAME) : void 0;
621
+ return codexHome ? path.join(codexHome, CODEX_CONFIG_TOML_FILENAME) : void 0;
622
+ }
623
+ function readErrorCode(error) {
624
+ return error && typeof error === "object" && "code" in error ? String(error.code) : void 0;
625
+ }
626
+ function readConfiguredOpenAIProvidersForModelBackedReview(config) {
627
+ const providerRecords = readRecord(readRecord(readRecord(config)?.models)?.providers);
628
+ if (!providerRecords) return [];
629
+ const openAIProviders = [];
630
+ for (const [providerId, providerConfig] of Object.entries(providerRecords)) {
631
+ if (resolveProviderIdForAuth(providerId, { config }) !== "openai") continue;
632
+ const record = readRecord(providerConfig);
633
+ if (record) openAIProviders.push(record);
634
+ }
635
+ return openAIProviders;
636
+ }
637
+ function configuredOpenAIProviderIsTrustedForModelBackedReview(openAIProvider, modelInput) {
638
+ if (readRecord(openAIProvider.localService) || hasNonEmptyRecord(openAIProvider.headers) || hasNonEmptyRecord(openAIProvider.request) || typeof openAIProvider.authHeader === "boolean" || !isNativeOpenAIBaseUrl(openAIProvider.baseUrl)) return false;
639
+ const models = openAIProvider.models;
640
+ if (!Array.isArray(models)) return true;
641
+ const modelId = normalizeOpenAIModelBackedReviewerModelId(modelInput);
642
+ if (!modelId) return false;
643
+ for (const entry of models) {
644
+ const model = readRecord(entry);
645
+ if (typeof model?.id !== "string" || !matchesConfiguredOpenAIModelId(modelId, model.id)) continue;
646
+ if (hasNonEmptyRecord(model.headers) || hasNonEmptyRecord(model.request) || !isNativeOpenAIBaseUrl(model.baseUrl)) return false;
647
+ }
648
+ return true;
649
+ }
650
+ function normalizeOpenAIModelBackedReviewerModelId(modelInput) {
651
+ const normalized = modelInput?.trim() ?? "";
652
+ const authProfileIndex = normalized.indexOf("@");
653
+ const withoutAuthProfile = authProfileIndex > 0 ? normalized.slice(0, authProfileIndex) : normalized;
654
+ const slashIndex = withoutAuthProfile.indexOf("/");
655
+ return slashIndex > 0 ? withoutAuthProfile.slice(slashIndex + 1).trim() : withoutAuthProfile;
656
+ }
657
+ function matchesConfiguredOpenAIModelId(modelId, configuredModelId) {
658
+ const configured = normalizeOpenAIModelBackedReviewerModelId(configuredModelId);
659
+ return Boolean(configured) && (modelId === configured || modelId.startsWith(`${configured}@`));
660
+ }
661
+ function hasNonEmptyRecord(value) {
662
+ const record = readRecord(value);
663
+ return record !== void 0 && Object.keys(record).length > 0;
664
+ }
665
+ function isNativeOpenAIBaseUrl(value) {
666
+ if (typeof value !== "string" || !value.trim()) return true;
667
+ try {
668
+ const url = new URL(value);
669
+ return url.protocol === "https:" && url.hostname.toLowerCase() === "api.openai.com";
670
+ } catch {
671
+ return false;
672
+ }
673
+ }
674
+ function openAIBaseUrlEnvOverridesAreTrustedForModelBackedReview(env) {
675
+ return [env?.OPENAI_BASE_URL, env?.OPENAI_API_BASE].every(isNativeOpenAIBaseUrl);
676
+ }
677
+ function isNativeChatGPTBaseUrl(value) {
678
+ if (typeof value !== "string" || !value.trim()) return true;
679
+ try {
680
+ const url = new URL(value);
681
+ return url.protocol === "https:" && url.hostname.toLowerCase() === "chatgpt.com";
682
+ } catch {
683
+ return false;
684
+ }
685
+ }
686
+ function normalizeCodexModelBackedReviewerPolicyProvider(provider) {
687
+ return provider.toLowerCase() === "openai" ? "openai" : provider;
688
+ }
689
+ function inferProviderFromModelRef(model) {
690
+ const normalized = model?.trim().toLowerCase();
691
+ const slashIndex = normalized?.indexOf("/") ?? -1;
692
+ return slashIndex > 0 ? normalized?.slice(0, slashIndex) : void 0;
492
693
  }
493
694
  function selectForcedPromptingSandbox(params) {
494
695
  if (params.configuredSandbox === "read-only" || params.defaultSandbox === "read-only") return "read-only";
@@ -757,4 +958,4 @@ function splitShellWords(value) {
757
958
  return words;
758
959
  }
759
960
  //#endregion
760
- export { isCodexFastServiceTier as a, readCodexPluginConfig as c, resolveCodexPluginsPolicy as d, resolveOpenClawExecPolicyForCodexAppServer as f, isCodexAppServerApprovalPolicyAllowedByRequirements as i, resolveCodexAppServerRuntimeOptions as l, withMcpElicitationsApprovalPolicy as m, codexAppServerStartOptionsKey as n, isCodexSandboxExecServerEnabled as o, shouldAutoApproveCodexAppServerApprovals as p, codexSandboxPolicyForTurn as r, normalizeCodexServiceTier as s, CODEX_PLUGINS_MARKETPLACE_NAME as t, resolveCodexComputerUseConfig as u };
961
+ export { withMcpElicitationsApprovalPolicy as _, isCodexAppServerApprovalPolicyAllowedByRequirements as a, isTrustedCodexModelBackedOpenAIProvider as c, resolveCodexAppServerRuntimeOptions as d, resolveCodexComputerUseConfig as f, shouldAutoApproveCodexAppServerApprovals as g, resolveOpenClawExecPolicyForCodexAppServer as h, codexSandboxPolicyForTurn as i, normalizeCodexServiceTier as l, resolveCodexPluginsPolicy as m, canUseCodexModelBackedApprovalsReviewerForModel as n, isCodexFastServiceTier as o, resolveCodexModelBackedReviewerPolicyContext as p, codexAppServerStartOptionsKey as r, isCodexSandboxExecServerEnabled as s, CODEX_PLUGINS_MARKETPLACE_NAME as t, readCodexPluginConfig as u };