@openclaw/codex 2026.6.5 → 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.
- package/dist/{client-kMCtlApt.js → client-DovmVtbr.js} +3 -10
- package/dist/{client-factory-Bt49r45B.js → client-factory-XajDuvQ1.js} +1 -1
- package/dist/{command-handlers-DMn2M7W7.js → command-handlers-DIUFKqaF.js} +11 -9
- package/dist/{compact-CwnPeYnM.js → compact-BWiNkDSs.js} +96 -9
- package/dist/{computer-use-ClweWaMz.js → computer-use-D3pi5csE.js} +3 -2
- package/dist/{config-BT6SLiE6.js → config-DJXpBkGf.js} +214 -13
- package/dist/{conversation-binding-CzpvaBs1.js → conversation-binding-CMwrZrt7.js} +190 -65
- package/dist/harness.js +12 -5
- package/dist/index.js +11 -10
- package/dist/media-understanding-provider.js +6 -6
- package/dist/{models-DXorTaja.js → models-CQGfP7nG.js} +2 -2
- package/dist/{native-hook-relay-DHwz_ICg.js → native-hook-relay-CmUUO3Eu.js} +160 -4
- package/dist/notification-correlation-D-MYfJwV.js +382 -0
- package/dist/{request-D64BfplD.js → plugin-app-cache-key-NpzxEcSR.js} +4 -36
- package/dist/protocol-oeJQu4rs.js +9 -0
- package/dist/{protocol-validators-CIpP8IJ2.js → protocol-validators-B48C6S9O.js} +2296 -2273
- package/dist/provider-Cs6kWhDQ.js +584 -0
- package/dist/provider.js +1 -164
- package/dist/request-Dq0LUOqZ.js +36 -0
- package/dist/{run-attempt-BWdNnok4.js → run-attempt-DG9p9ReO.js} +374 -65
- package/dist/{session-binding-BgTv_YGm.js → session-binding-ElbcSq2o.js} +107 -44
- package/dist/{shared-client-xytpSKD0.js → shared-client-CflavQ_i.js} +3 -3
- package/dist/{side-question-BnvBQPqW.js → side-question-Ctu2VXAG.js} +82 -26
- package/dist/{thread-lifecycle-BJsazZ8j.js → thread-lifecycle-Cq1-IfZB.js} +115 -34
- package/npm-shrinkwrap.json +30 -30
- package/package.json +5 -5
- package/dist/notification-correlation-o8quHmTK.js +0 -656
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
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,
|
|
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-
|
|
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 {
|
|
2
|
-
import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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-
|
|
9
|
-
import {
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import { o as releaseLeasedSharedCodexAppServerClient } from "./shared-client-
|
|
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-
|
|
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
|
|
110
|
-
if (!
|
|
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
|
-
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
|
164
|
-
|
|
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
|
|
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
|
|
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(
|
|
344
|
-
return readFileSync(
|
|
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(
|
|
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 {
|
|
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 };
|