@openclaw/codex 2026.6.8 → 2026.6.9-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/{notification-correlation-BGoG0N90.js → app-server-policy-KpyUye2D.js} +15 -74
- package/dist/attempt-notifications-Meja3TX6.js +249 -0
- package/dist/{client-factory-C71Xdb6z.js → client-factory-CPuoOOx6.js} +3 -2
- package/dist/{client-DovmVtbr.js → client-m7XiCQpO.js} +24 -2
- package/dist/{command-handlers-DHecBkuc.js → command-handlers-CqS0Kv3Z.js} +17 -13
- package/dist/{compact-GEKusemL.js → compact-CMVlldii.js} +5 -5
- package/dist/{computer-use-D1qxvTE_.js → computer-use-qLm7Gf35.js} +3 -3
- package/dist/{config-DJXpBkGf.js → config-BksX0T33.js} +160 -20
- package/dist/{conversation-binding-CbnMilVW.js → conversation-binding-DBof5w9J.js} +166 -58
- package/dist/doctor-contract-api.js +37 -3
- package/dist/harness.js +6 -6
- package/dist/index.js +108 -27
- package/dist/media-understanding-provider-CiwPkR58.js +463 -0
- package/dist/media-understanding-provider.js +1 -355
- package/dist/{models-DRKnOpzF.js → models-BsyV1Psm.js} +2 -2
- package/dist/{plugin-app-cache-key-kIqpGTQj.js → plugin-app-cache-key-CN9zBiCG.js} +17 -6
- package/dist/{protocol-oeJQu4rs.js → protocol-dh-ETiNd.js} +4 -1
- package/dist/{protocol-validators-B48C6S9O.js → protocol-validators-B19q5BIX.js} +210 -16
- package/dist/{native-hook-relay-C3i3FYtc.js → provider-capabilities-BOvTfMhF.js} +803 -78
- package/dist/{provider-C5P6352f.js → provider-qJygHQx4.js} +4 -4
- package/dist/provider.js +1 -1
- package/dist/{request-BxZ40QKY.js → request-DTIEyUrA.js} +2 -2
- package/dist/{run-attempt-D_q-VrpR.js → run-attempt-DRhB6bTc.js} +421 -774
- package/dist/{sandbox-guard-C-Yv9uwY.js → sandbox-guard-3tnjhjFb.js} +37 -10
- package/dist/{session-binding-ElbcSq2o.js → session-binding-BRUi8y6E.js} +27 -8
- package/dist/{shared-client-jFMumCOe.js → shared-client-Bg5d7VV9.js} +4 -4
- package/dist/{side-question-DqKLfWMB.js → side-question-BdYL4kj1.js} +106 -42
- package/dist/{thread-lifecycle-cban34w3.js → thread-lifecycle-CbJqqnEw.js} +912 -616
- package/dist/web-search-contract-api.js +10 -0
- package/dist/web-search-provider.runtime-DrpQ8Cyd.js +74 -0
- package/dist/web-search-provider.shared-BrZmlqyR.js +32 -0
- package/npm-shrinkwrap.json +2 -2
- package/openclaw.plugin.json +129 -4
- package/package.json +4 -4
|
@@ -1,35 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import { d as
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
6
|
-
import {
|
|
7
|
-
import { a as
|
|
8
|
-
import {
|
|
1
|
+
import { n as isJsonObject } from "./protocol-dh-ETiNd.js";
|
|
2
|
+
import { B as readCodexNotificationThreadId, V as readCodexNotificationTurnId, d as resolveCodexAppServerRequestModelSelection, p as resolveCodexBindingModelProviderFallback, t as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-lifecycle-CbJqqnEw.js";
|
|
3
|
+
import { d as resolveCodexAppServerRuntimeOptions, h as resolveOpenClawExecPolicyForCodexAppServer, i as codexSandboxPolicyForTurn, n as canUseCodexModelBackedApprovalsReviewerForModel, o as isCodexFastServiceTier, p as resolveCodexModelBackedReviewerPolicyContext } from "./config-BksX0T33.js";
|
|
4
|
+
import { r as assertCodexThreadStartResponse } from "./protocol-validators-B19q5BIX.js";
|
|
5
|
+
import { a as normalizeCodexAppServerBindingModelProvider, i as isCodexAppServerNativeAuthProfile, l as writeCodexAppServerBinding, n as clearCodexAppServerBinding, o as readCodexAppServerBinding } from "./session-binding-BRUi8y6E.js";
|
|
6
|
+
import { r as CODEX_CONTROL_METHODS } from "./plugin-app-cache-key-CN9zBiCG.js";
|
|
7
|
+
import { a as formatCodexDisplayText, t as resolveCodexAppServerForModelProvider } from "./app-server-policy-KpyUye2D.js";
|
|
8
|
+
import { a as getLeasedSharedCodexAppServerClient, o as releaseLeasedSharedCodexAppServerClient, p as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-Bg5d7VV9.js";
|
|
9
|
+
import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-3tnjhjFb.js";
|
|
10
|
+
import fs from "node:fs/promises";
|
|
11
|
+
import path from "node:path";
|
|
9
12
|
import { resolveTimerTimeoutMs, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
13
|
+
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
|
14
|
+
import { asOptionalRecord, isRecord, normalizeSingleOrTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
10
15
|
import os from "node:os";
|
|
11
|
-
import path from "node:path";
|
|
12
16
|
import { resolveSessionAgentIds } from "openclaw/plugin-sdk/agent-runtime";
|
|
13
17
|
import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
|
|
14
|
-
import { asOptionalRecord, isRecord, normalizeSingleOrTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
15
18
|
import { materializeWindowsSpawnProgram, resolveWindowsSpawnProgram } from "openclaw/plugin-sdk/windows-spawn";
|
|
16
19
|
import { formatErrorMessage, resolveSandboxContext } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
17
20
|
import { spawn } from "node:child_process";
|
|
18
|
-
import fs from "node:fs/promises";
|
|
19
21
|
import { loadSessionStore, resolveSessionStoreEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
20
22
|
import { fileURLToPath } from "node:url";
|
|
21
23
|
import process$1 from "node:process";
|
|
22
|
-
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
|
23
24
|
//#region extensions/codex/src/conversation-binding-data.ts
|
|
24
25
|
const BINDING_DATA_VERSION = 1;
|
|
25
26
|
function createCodexConversationBindingData(params) {
|
|
26
27
|
const agentDir = params.agentDir?.trim();
|
|
28
|
+
const agentId = params.agentId?.trim();
|
|
27
29
|
return {
|
|
28
30
|
kind: "codex-app-server-session",
|
|
29
31
|
version: BINDING_DATA_VERSION,
|
|
30
32
|
sessionFile: params.sessionFile,
|
|
31
33
|
workspaceDir: params.workspaceDir,
|
|
32
|
-
...agentDir ? { agentDir } : {}
|
|
34
|
+
...agentDir ? { agentDir } : {},
|
|
35
|
+
...agentId ? { agentId } : {}
|
|
33
36
|
};
|
|
34
37
|
}
|
|
35
38
|
function createCodexCliNodeConversationBindingData(params) {
|
|
@@ -65,7 +68,8 @@ function readCodexConversationBindingDataRecord(data) {
|
|
|
65
68
|
version: BINDING_DATA_VERSION,
|
|
66
69
|
sessionFile: data.sessionFile,
|
|
67
70
|
workspaceDir: typeof data.workspaceDir === "string" && data.workspaceDir.trim() ? data.workspaceDir : process$1.cwd(),
|
|
68
|
-
agentDir: typeof data.agentDir === "string" && data.agentDir.trim() ? data.agentDir : void 0
|
|
71
|
+
agentDir: typeof data.agentDir === "string" && data.agentDir.trim() ? data.agentDir : void 0,
|
|
72
|
+
agentId: typeof data.agentId === "string" && data.agentId.trim() ? data.agentId : void 0
|
|
69
73
|
};
|
|
70
74
|
}
|
|
71
75
|
function resolveCodexDefaultWorkspaceDir(pluginConfig) {
|
|
@@ -957,6 +961,11 @@ function formatNodeLabel(node) {
|
|
|
957
961
|
//#endregion
|
|
958
962
|
//#region extensions/codex/src/conversation-binding.ts
|
|
959
963
|
const DEFAULT_BOUND_TURN_TIMEOUT_MS = 20 * 6e4;
|
|
964
|
+
const DEFAULT_AGENT_ID = "main";
|
|
965
|
+
const VALID_AGENT_ID_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
|
|
966
|
+
const INVALID_AGENT_ID_CHARS_PATTERN = /[^a-z0-9_-]+/g;
|
|
967
|
+
const LEADING_DASH_PATTERN = /^-+/;
|
|
968
|
+
const TRAILING_DASH_PATTERN = /-+$/;
|
|
960
969
|
const NATIVE_CONVERSATION_INTERACTIVE_APPROVALS_UNAVAILABLE = "OpenClaw native Codex conversation binding cannot route interactive approvals yet; use the Codex harness or explicit /acp spawn codex for that workflow.";
|
|
961
970
|
async function resolveConversationAppServerRuntime(params) {
|
|
962
971
|
const execPolicy = resolveConversationExecPolicy({
|
|
@@ -983,6 +992,7 @@ async function resolveConversationAppServerRuntime(params) {
|
|
|
983
992
|
};
|
|
984
993
|
}
|
|
985
994
|
const CODEX_CONVERSATION_GLOBAL_STATE = Symbol.for("openclaw.codex.conversationBinding");
|
|
995
|
+
const CODEX_CONVERSATION_THREAD_DEVELOPER_INSTRUCTIONS = "This Codex thread is bound to an OpenClaw conversation. Answer normally; OpenClaw will deliver your final response back to the conversation.";
|
|
986
996
|
function getGlobalState() {
|
|
987
997
|
const globalState = globalThis;
|
|
988
998
|
globalState[CODEX_CONVERSATION_GLOBAL_STATE] ??= { queues: /* @__PURE__ */ new Map() };
|
|
@@ -1013,7 +1023,8 @@ async function startCodexConversationThread(params) {
|
|
|
1013
1023
|
sandbox: params.sandbox,
|
|
1014
1024
|
serviceTier: params.serviceTier,
|
|
1015
1025
|
config: params.config,
|
|
1016
|
-
sessionKey: params.sessionKey
|
|
1026
|
+
sessionKey: params.sessionKey,
|
|
1027
|
+
agentId: params.agentId
|
|
1017
1028
|
});
|
|
1018
1029
|
else await createThread({
|
|
1019
1030
|
pluginConfig: params.pluginConfig,
|
|
@@ -1027,12 +1038,14 @@ async function startCodexConversationThread(params) {
|
|
|
1027
1038
|
sandbox: params.sandbox,
|
|
1028
1039
|
serviceTier: params.serviceTier,
|
|
1029
1040
|
config: params.config,
|
|
1030
|
-
sessionKey: params.sessionKey
|
|
1041
|
+
sessionKey: params.sessionKey,
|
|
1042
|
+
agentId: params.agentId
|
|
1031
1043
|
});
|
|
1032
1044
|
return createCodexConversationBindingData({
|
|
1033
1045
|
sessionFile: params.sessionFile,
|
|
1034
1046
|
workspaceDir,
|
|
1035
|
-
...agentDir ? { agentDir } : {}
|
|
1047
|
+
...agentDir ? { agentDir } : {},
|
|
1048
|
+
agentId: params.agentId
|
|
1036
1049
|
});
|
|
1037
1050
|
}
|
|
1038
1051
|
async function handleCodexConversationInboundClaim(event, ctx, options = {}) {
|
|
@@ -1048,6 +1061,7 @@ async function handleCodexConversationInboundClaim(event, ctx, options = {}) {
|
|
|
1048
1061
|
}) : resolveCodexNativeExecutionBlock({
|
|
1049
1062
|
config: options.config,
|
|
1050
1063
|
sessionKey: event.sessionKey ?? ctx.sessionKey,
|
|
1064
|
+
agentId: data.agentId,
|
|
1051
1065
|
surface: "Codex app-server conversation binding"
|
|
1052
1066
|
});
|
|
1053
1067
|
if (nativeExecutionBlock) return {
|
|
@@ -1174,13 +1188,31 @@ async function resolveThreadBindingRuntime(params) {
|
|
|
1174
1188
|
}
|
|
1175
1189
|
function buildThreadRequestRuntimeOptions(params, resolved) {
|
|
1176
1190
|
const serviceTier = params.serviceTier ?? resolved.runtime.serviceTier;
|
|
1191
|
+
const sandbox = resolved.execPolicy?.touched ? resolved.runtime.sandbox : params.sandbox ?? resolved.runtime.sandbox;
|
|
1177
1192
|
return {
|
|
1178
1193
|
approvalPolicy: resolved.execPolicy?.touched ? resolved.runtime.approvalPolicy : params.approvalPolicy ?? resolved.runtime.approvalPolicy,
|
|
1179
1194
|
approvalsReviewer: resolved.runtime.approvalsReviewer,
|
|
1180
|
-
|
|
1195
|
+
...codexConversationSandboxOrPermissions(resolved.runtime, sandbox),
|
|
1181
1196
|
...serviceTier ? { serviceTier } : {}
|
|
1182
1197
|
};
|
|
1183
1198
|
}
|
|
1199
|
+
function codexConversationSandboxOrPermissions(runtime, sandbox) {
|
|
1200
|
+
const networkProxy = runtime.networkProxy;
|
|
1201
|
+
if (networkProxy) return { config: networkProxy.configPatch };
|
|
1202
|
+
return { sandbox };
|
|
1203
|
+
}
|
|
1204
|
+
async function requestNewConversationBindingThread(params, resolved) {
|
|
1205
|
+
return await resolved.client.request("thread/start", {
|
|
1206
|
+
cwd: params.workspaceDir,
|
|
1207
|
+
...resolved.model ? { model: resolved.model } : {},
|
|
1208
|
+
...resolved.modelProvider ? { modelProvider: resolved.modelProvider } : {},
|
|
1209
|
+
personality: CODEX_NATIVE_PERSONALITY_NONE,
|
|
1210
|
+
...buildThreadRequestRuntimeOptions(params, resolved),
|
|
1211
|
+
developerInstructions: CODEX_CONVERSATION_THREAD_DEVELOPER_INSTRUCTIONS,
|
|
1212
|
+
experimentalRawEvents: true,
|
|
1213
|
+
persistExtendedHistory: true
|
|
1214
|
+
}, { timeoutMs: resolved.runtime.requestTimeoutMs });
|
|
1215
|
+
}
|
|
1184
1216
|
async function writeThreadBindingFromResponse(params, resolved, response) {
|
|
1185
1217
|
const runtimeApprovalPolicy = typeof resolved.runtime.approvalPolicy === "string" ? resolved.runtime.approvalPolicy : void 0;
|
|
1186
1218
|
await writeCodexAppServerBinding(params.sessionFile, {
|
|
@@ -1195,13 +1227,15 @@ async function writeThreadBindingFromResponse(params, resolved, response) {
|
|
|
1195
1227
|
}),
|
|
1196
1228
|
approvalPolicy: resolved.execPolicy?.touched ? runtimeApprovalPolicy : params.approvalPolicy ?? runtimeApprovalPolicy,
|
|
1197
1229
|
sandbox: resolved.execPolicy?.touched ? resolved.runtime.sandbox : params.sandbox ?? resolved.runtime.sandbox,
|
|
1198
|
-
serviceTier: params.serviceTier ?? resolved.runtime.serviceTier
|
|
1230
|
+
serviceTier: params.serviceTier ?? resolved.runtime.serviceTier,
|
|
1231
|
+
networkProxyProfileName: resolved.runtime.networkProxy?.profileName,
|
|
1232
|
+
networkProxyConfigFingerprint: resolved.runtime.networkProxy?.configFingerprint
|
|
1199
1233
|
}, { ...resolved.agentLookup });
|
|
1200
1234
|
}
|
|
1201
1235
|
async function attachExistingThread(params) {
|
|
1202
1236
|
const resolved = await resolveThreadBindingRuntime(params);
|
|
1203
1237
|
try {
|
|
1204
|
-
await writeThreadBindingFromResponse(params, resolved, await resolved.client.request(CODEX_CONTROL_METHODS.resumeThread, {
|
|
1238
|
+
await writeThreadBindingFromResponse(params, resolved, resolved.runtime.networkProxy ? await requestNewConversationBindingThread(params, resolved) : await resolved.client.request(CODEX_CONTROL_METHODS.resumeThread, {
|
|
1205
1239
|
threadId: params.threadId,
|
|
1206
1240
|
...resolved.model ? { model: resolved.model } : {},
|
|
1207
1241
|
...resolved.modelProvider ? { modelProvider: resolved.modelProvider } : {},
|
|
@@ -1216,16 +1250,7 @@ async function attachExistingThread(params) {
|
|
|
1216
1250
|
async function createThread(params) {
|
|
1217
1251
|
const resolved = await resolveThreadBindingRuntime(params);
|
|
1218
1252
|
try {
|
|
1219
|
-
await writeThreadBindingFromResponse(params, resolved, await
|
|
1220
|
-
cwd: params.workspaceDir,
|
|
1221
|
-
...resolved.model ? { model: resolved.model } : {},
|
|
1222
|
-
...resolved.modelProvider ? { modelProvider: resolved.modelProvider } : {},
|
|
1223
|
-
personality: CODEX_NATIVE_PERSONALITY_NONE,
|
|
1224
|
-
...buildThreadRequestRuntimeOptions(params, resolved),
|
|
1225
|
-
developerInstructions: "This Codex thread is bound to an OpenClaw conversation. Answer normally; OpenClaw will deliver your final response back to the conversation.",
|
|
1226
|
-
experimentalRawEvents: true,
|
|
1227
|
-
persistExtendedHistory: true
|
|
1228
|
-
}, { timeoutMs: resolved.runtime.requestTimeoutMs }));
|
|
1253
|
+
await writeThreadBindingFromResponse(params, resolved, await requestNewConversationBindingThread(params, resolved));
|
|
1229
1254
|
} finally {
|
|
1230
1255
|
releaseLeasedSharedCodexAppServerClient(resolved.client);
|
|
1231
1256
|
}
|
|
@@ -1236,8 +1261,8 @@ async function runBoundTurn(params) {
|
|
|
1236
1261
|
config: params.config
|
|
1237
1262
|
});
|
|
1238
1263
|
const binding = await readCodexAppServerBinding(params.data.sessionFile, agentLookup);
|
|
1239
|
-
|
|
1240
|
-
|
|
1264
|
+
if (!binding?.threadId) throw new Error("bound Codex conversation has no thread binding");
|
|
1265
|
+
let threadId = binding.threadId;
|
|
1241
1266
|
const workspaceDir = binding.cwd || params.data.workspaceDir;
|
|
1242
1267
|
const reviewerModelProvider = resolveModelBackedReviewerPolicyProvider({
|
|
1243
1268
|
authProfileId: binding.authProfileId,
|
|
@@ -1247,6 +1272,7 @@ async function runBoundTurn(params) {
|
|
|
1247
1272
|
const { execPolicy, runtime } = await resolveConversationAppServerRuntime({
|
|
1248
1273
|
pluginConfig: params.pluginConfig,
|
|
1249
1274
|
config: params.config,
|
|
1275
|
+
agentId: params.data.agentId,
|
|
1250
1276
|
sessionKey: params.sessionKey,
|
|
1251
1277
|
workspaceDir,
|
|
1252
1278
|
modelProvider: reviewerModelProvider,
|
|
@@ -1271,6 +1297,11 @@ async function runBoundTurn(params) {
|
|
|
1271
1297
|
const useModelScopedPolicy = execPolicy?.touched === true || modelBackedApprovalsReviewerUnavailable;
|
|
1272
1298
|
const approvalPolicy = useModelScopedPolicy ? modelScopedRuntime.approvalPolicy : binding.approvalPolicy ?? modelScopedRuntime.approvalPolicy;
|
|
1273
1299
|
const sandbox = useModelScopedPolicy ? modelScopedRuntime.sandbox : binding.sandbox ?? modelScopedRuntime.sandbox;
|
|
1300
|
+
const permissionProfile = modelScopedRuntime.networkProxy?.profileName;
|
|
1301
|
+
const networkProxyConfigFingerprint = modelScopedRuntime.networkProxy?.configFingerprint;
|
|
1302
|
+
const networkProxyBindingChanged = binding.networkProxyProfileName !== permissionProfile || binding.networkProxyConfigFingerprint !== networkProxyConfigFingerprint;
|
|
1303
|
+
const serviceTier = binding.serviceTier ?? runtime.serviceTier;
|
|
1304
|
+
let useStickyNetworkProfile = permissionProfile !== void 0 && binding.networkProxyProfileName === permissionProfile && binding.networkProxyConfigFingerprint === networkProxyConfigFingerprint;
|
|
1274
1305
|
assertNativeConversationApprovalPolicySupported({
|
|
1275
1306
|
execPolicy,
|
|
1276
1307
|
approvalPolicy,
|
|
@@ -1289,30 +1320,65 @@ async function runBoundTurn(params) {
|
|
|
1289
1320
|
authProfileId: binding.authProfileId,
|
|
1290
1321
|
...agentLookup
|
|
1291
1322
|
});
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
const requestCleanup = client.addRequestHandler(async (request) => {
|
|
1295
|
-
if (request.method === "item/tool/call") return {
|
|
1296
|
-
contentItems: [{
|
|
1297
|
-
type: "inputText",
|
|
1298
|
-
text: "OpenClaw native Codex conversation binding does not expose dynamic OpenClaw tools yet."
|
|
1299
|
-
}],
|
|
1300
|
-
success: false
|
|
1301
|
-
};
|
|
1302
|
-
if (request.method === "item/commandExecution/requestApproval" || request.method === "item/fileChange/requestApproval") return {
|
|
1303
|
-
decision: "decline",
|
|
1304
|
-
reason: "OpenClaw native Codex conversation binding cannot route interactive approvals yet; use the Codex harness or explicit /acp spawn codex for that workflow."
|
|
1305
|
-
};
|
|
1306
|
-
if (request.method === "item/permissions/requestApproval") return {
|
|
1307
|
-
permissions: {},
|
|
1308
|
-
scope: "turn"
|
|
1309
|
-
};
|
|
1310
|
-
if (request.method.includes("requestApproval")) return {
|
|
1311
|
-
decision: "decline",
|
|
1312
|
-
reason: "OpenClaw native Codex conversation binding cannot route interactive approvals yet; use the Codex harness or explicit /acp spawn codex for that workflow."
|
|
1313
|
-
};
|
|
1314
|
-
});
|
|
1323
|
+
let notificationCleanup = () => void 0;
|
|
1324
|
+
let requestCleanup = () => void 0;
|
|
1315
1325
|
try {
|
|
1326
|
+
if (networkProxyBindingChanged) {
|
|
1327
|
+
const response = assertCodexThreadStartResponse(await client.request("thread/start", {
|
|
1328
|
+
cwd: workspaceDir,
|
|
1329
|
+
...modelSelection?.model ? { model: modelSelection.model } : {},
|
|
1330
|
+
...modelSelection?.modelProvider ? { modelProvider: modelSelection.modelProvider } : {},
|
|
1331
|
+
personality: CODEX_NATIVE_PERSONALITY_NONE,
|
|
1332
|
+
approvalPolicy,
|
|
1333
|
+
approvalsReviewer: modelScopedRuntime.approvalsReviewer,
|
|
1334
|
+
...modelScopedRuntime.networkProxy ? { config: modelScopedRuntime.networkProxy.configPatch } : { sandbox },
|
|
1335
|
+
...serviceTier ? { serviceTier } : {},
|
|
1336
|
+
developerInstructions: CODEX_CONVERSATION_THREAD_DEVELOPER_INSTRUCTIONS,
|
|
1337
|
+
experimentalRawEvents: true,
|
|
1338
|
+
persistExtendedHistory: true
|
|
1339
|
+
}, { timeoutMs: runtime.requestTimeoutMs }));
|
|
1340
|
+
threadId = response.thread.id;
|
|
1341
|
+
await writeCodexAppServerBinding(params.data.sessionFile, {
|
|
1342
|
+
threadId,
|
|
1343
|
+
cwd: response.thread.cwd ?? workspaceDir,
|
|
1344
|
+
authProfileId: binding.authProfileId,
|
|
1345
|
+
model: response.model ?? modelSelection?.model ?? binding.model,
|
|
1346
|
+
modelProvider: normalizeCodexAppServerBindingModelProvider({
|
|
1347
|
+
authProfileId: binding.authProfileId,
|
|
1348
|
+
modelProvider: response.modelProvider ?? modelSelection?.modelProvider ?? binding.modelProvider,
|
|
1349
|
+
...agentLookup
|
|
1350
|
+
}),
|
|
1351
|
+
approvalPolicy: typeof approvalPolicy === "string" ? approvalPolicy : void 0,
|
|
1352
|
+
sandbox,
|
|
1353
|
+
serviceTier,
|
|
1354
|
+
networkProxyProfileName: modelScopedRuntime.networkProxy?.profileName,
|
|
1355
|
+
networkProxyConfigFingerprint: modelScopedRuntime.networkProxy?.configFingerprint
|
|
1356
|
+
}, agentLookup);
|
|
1357
|
+
useStickyNetworkProfile = modelScopedRuntime.networkProxy !== void 0;
|
|
1358
|
+
}
|
|
1359
|
+
const collector = createCodexConversationTurnCollector(threadId);
|
|
1360
|
+
notificationCleanup = client.addNotificationHandler((notification) => collector.handleNotification(notification));
|
|
1361
|
+
requestCleanup = client.addRequestHandler(async (request) => {
|
|
1362
|
+
if (request.method === "item/tool/call") return {
|
|
1363
|
+
contentItems: [{
|
|
1364
|
+
type: "inputText",
|
|
1365
|
+
text: "OpenClaw native Codex conversation binding does not expose dynamic OpenClaw tools yet."
|
|
1366
|
+
}],
|
|
1367
|
+
success: false
|
|
1368
|
+
};
|
|
1369
|
+
if (request.method === "item/commandExecution/requestApproval" || request.method === "item/fileChange/requestApproval") return {
|
|
1370
|
+
decision: "decline",
|
|
1371
|
+
reason: "OpenClaw native Codex conversation binding cannot route interactive approvals yet; use the Codex harness or explicit /acp spawn codex for that workflow."
|
|
1372
|
+
};
|
|
1373
|
+
if (request.method === "item/permissions/requestApproval") return {
|
|
1374
|
+
permissions: {},
|
|
1375
|
+
scope: "turn"
|
|
1376
|
+
};
|
|
1377
|
+
if (request.method.includes("requestApproval")) return {
|
|
1378
|
+
decision: "decline",
|
|
1379
|
+
reason: "OpenClaw native Codex conversation binding cannot route interactive approvals yet; use the Codex harness or explicit /acp spawn codex for that workflow."
|
|
1380
|
+
};
|
|
1381
|
+
});
|
|
1316
1382
|
const turnId = (await client.request("turn/start", {
|
|
1317
1383
|
threadId,
|
|
1318
1384
|
input: buildCodexConversationTurnInput({
|
|
@@ -1322,10 +1388,10 @@ async function runBoundTurn(params) {
|
|
|
1322
1388
|
cwd: workspaceDir,
|
|
1323
1389
|
approvalPolicy,
|
|
1324
1390
|
approvalsReviewer: modelScopedRuntime.approvalsReviewer,
|
|
1325
|
-
sandboxPolicy: codexSandboxPolicyForTurn(sandbox, workspaceDir),
|
|
1391
|
+
...useStickyNetworkProfile ? {} : { sandboxPolicy: codexSandboxPolicyForTurn(sandbox, workspaceDir) },
|
|
1326
1392
|
...modelSelection?.model ? { model: modelSelection.model } : {},
|
|
1327
1393
|
personality: CODEX_NATIVE_PERSONALITY_NONE,
|
|
1328
|
-
...
|
|
1394
|
+
...serviceTier ? { serviceTier } : {}
|
|
1329
1395
|
}, { timeoutMs: runtime.requestTimeoutMs })).turn.id;
|
|
1330
1396
|
const activeCleanup = trackCodexConversationActiveTurn({
|
|
1331
1397
|
sessionFile: params.data.sessionFile,
|
|
@@ -1355,6 +1421,7 @@ async function runBoundTurnWithMissingThreadRecovery(params) {
|
|
|
1355
1421
|
const binding = await readCodexAppServerBinding(params.data.sessionFile, agentLookup);
|
|
1356
1422
|
const useCurrentRuntimePolicy = resolveConversationExecPolicy({
|
|
1357
1423
|
config: params.config,
|
|
1424
|
+
agentId: params.data.agentId,
|
|
1358
1425
|
sessionKey: params.sessionKey
|
|
1359
1426
|
}).touched;
|
|
1360
1427
|
await startCodexConversationThread({
|
|
@@ -1369,7 +1436,8 @@ async function runBoundTurnWithMissingThreadRecovery(params) {
|
|
|
1369
1436
|
sandbox: useCurrentRuntimePolicy ? void 0 : binding?.sandbox,
|
|
1370
1437
|
serviceTier: binding?.serviceTier,
|
|
1371
1438
|
config: params.config,
|
|
1372
|
-
sessionKey: params.sessionKey
|
|
1439
|
+
sessionKey: params.sessionKey,
|
|
1440
|
+
agentId: params.data.agentId
|
|
1373
1441
|
});
|
|
1374
1442
|
return await runBoundTurn(params);
|
|
1375
1443
|
}
|
|
@@ -1393,6 +1461,11 @@ function resolveConversationExecPolicy(params) {
|
|
|
1393
1461
|
function readSessionExecOverrides(params) {
|
|
1394
1462
|
const sessionKey = params.sessionKey?.trim();
|
|
1395
1463
|
if (!params.config || !sessionKey) return;
|
|
1464
|
+
if (!canReadSessionExecOverrides({
|
|
1465
|
+
config: params.config,
|
|
1466
|
+
agentId: params.agentId,
|
|
1467
|
+
sessionKey
|
|
1468
|
+
})) return;
|
|
1396
1469
|
const entry = resolveSessionStoreEntry({
|
|
1397
1470
|
store: loadSessionStore(resolveStorePath(params.config.session?.store, { agentId: params.agentId }), { skipCache: true }),
|
|
1398
1471
|
sessionKey
|
|
@@ -1403,6 +1476,41 @@ function readSessionExecOverrides(params) {
|
|
|
1403
1476
|
ask: entry.execAsk
|
|
1404
1477
|
};
|
|
1405
1478
|
}
|
|
1479
|
+
function canReadSessionExecOverrides(params) {
|
|
1480
|
+
const agentId = normalizeAgentIdOrDefault(params.agentId);
|
|
1481
|
+
if (!agentId) return true;
|
|
1482
|
+
const sessionAgentId = parseAgentIdFromSessionKey(params.sessionKey);
|
|
1483
|
+
if (!sessionAgentId) return isDefaultAgentSessionKeyForAgent({
|
|
1484
|
+
config: params.config,
|
|
1485
|
+
agentId
|
|
1486
|
+
});
|
|
1487
|
+
return sessionAgentId === agentId;
|
|
1488
|
+
}
|
|
1489
|
+
function parseAgentIdFromSessionKey(sessionKey) {
|
|
1490
|
+
const raw = sessionKey?.trim();
|
|
1491
|
+
if (!raw) return;
|
|
1492
|
+
const parts = raw.toLowerCase().split(":").filter(Boolean);
|
|
1493
|
+
if (parts.length < 3 || parts[0] !== "agent" || !parts[2]) return;
|
|
1494
|
+
return normalizeAgentIdOrDefault(parts[1]);
|
|
1495
|
+
}
|
|
1496
|
+
function isDefaultAgentSessionKeyForAgent(params) {
|
|
1497
|
+
return normalizeAgentId(params.agentId) === resolveDefaultPolicyAgentId(params.config);
|
|
1498
|
+
}
|
|
1499
|
+
function resolveDefaultPolicyAgentId(config) {
|
|
1500
|
+
const agents = (config.agents?.list ?? []).filter((entry) => entry !== null && typeof entry === "object");
|
|
1501
|
+
return normalizeAgentId((agents.find((entry) => entry?.default) ?? agents[0])?.id);
|
|
1502
|
+
}
|
|
1503
|
+
function normalizeAgentIdOrDefault(value) {
|
|
1504
|
+
const normalized = normalizeAgentId(value);
|
|
1505
|
+
return normalized === DEFAULT_AGENT_ID && !(value ?? "").trim() ? void 0 : normalized;
|
|
1506
|
+
}
|
|
1507
|
+
function normalizeAgentId(value) {
|
|
1508
|
+
const trimmed = (value ?? "").trim();
|
|
1509
|
+
if (!trimmed) return DEFAULT_AGENT_ID;
|
|
1510
|
+
const normalized = trimmed.toLowerCase();
|
|
1511
|
+
if (VALID_AGENT_ID_PATTERN.test(trimmed)) return normalized;
|
|
1512
|
+
return normalized.replace(INVALID_AGENT_ID_CHARS_PATTERN, "-").replace(LEADING_DASH_PATTERN, "").replace(TRAILING_DASH_PATTERN, "").slice(0, 64) || DEFAULT_AGENT_ID;
|
|
1513
|
+
}
|
|
1406
1514
|
function isCodexThreadNotFoundError(error) {
|
|
1407
1515
|
const message = formatErrorMessage(error);
|
|
1408
1516
|
return /\bthread not found:/iu.test(message) || /\bbound Codex conversation has no thread binding\b/u.test(message);
|
|
@@ -5,6 +5,13 @@ function asRecord(value) {
|
|
|
5
5
|
function hasRetiredDynamicToolsProfile(value) {
|
|
6
6
|
return Object.hasOwn(asRecord(value) ?? {}, "codexDynamicToolsProfile");
|
|
7
7
|
}
|
|
8
|
+
function hasLegacyPluginDestructivePolicy(value) {
|
|
9
|
+
const codexPlugins = asRecord(value);
|
|
10
|
+
if (!codexPlugins) return false;
|
|
11
|
+
if (codexPlugins.allow_destructive_actions === "on-request") return true;
|
|
12
|
+
const plugins = asRecord(codexPlugins.plugins);
|
|
13
|
+
return Object.values(plugins ?? {}).some((plugin) => asRecord(plugin)?.allow_destructive_actions === "on-request");
|
|
14
|
+
}
|
|
8
15
|
/** Legacy Codex config keys that doctor should report or repair. */
|
|
9
16
|
const legacyConfigRules = [{
|
|
10
17
|
path: [
|
|
@@ -15,13 +22,26 @@ const legacyConfigRules = [{
|
|
|
15
22
|
],
|
|
16
23
|
message: "plugins.entries.codex.config.codexDynamicToolsProfile is retired; Codex app-server always keeps Codex-native workspace tools native. Run \"openclaw doctor --fix\".",
|
|
17
24
|
match: hasRetiredDynamicToolsProfile
|
|
25
|
+
}, {
|
|
26
|
+
path: [
|
|
27
|
+
"plugins",
|
|
28
|
+
"entries",
|
|
29
|
+
"codex",
|
|
30
|
+
"config",
|
|
31
|
+
"codexPlugins"
|
|
32
|
+
],
|
|
33
|
+
message: "plugins.entries.codex.config.codexPlugins.allow_destructive_actions=\"on-request\" was renamed to \"auto\". Run \"openclaw doctor --fix\".",
|
|
34
|
+
match: hasLegacyPluginDestructivePolicy
|
|
18
35
|
}];
|
|
19
36
|
/**
|
|
20
37
|
* Removes retired Codex plugin config keys while preserving unrelated config.
|
|
21
38
|
*/
|
|
22
39
|
function normalizeCompatibilityConfig({ cfg }) {
|
|
23
40
|
const rawPluginConfig = asRecord(asRecord(cfg.plugins?.entries?.codex)?.config);
|
|
24
|
-
|
|
41
|
+
const rawCodexPlugins = asRecord(rawPluginConfig?.codexPlugins);
|
|
42
|
+
const shouldRemoveDynamicToolsProfile = rawPluginConfig !== null && hasRetiredDynamicToolsProfile(rawPluginConfig);
|
|
43
|
+
const shouldRewriteDestructivePolicy = hasLegacyPluginDestructivePolicy(rawCodexPlugins);
|
|
44
|
+
if (!rawPluginConfig || !shouldRemoveDynamicToolsProfile && !shouldRewriteDestructivePolicy) return {
|
|
25
45
|
config: cfg,
|
|
26
46
|
changes: []
|
|
27
47
|
};
|
|
@@ -31,10 +51,24 @@ function normalizeCompatibilityConfig({ cfg }) {
|
|
|
31
51
|
config: cfg,
|
|
32
52
|
changes: []
|
|
33
53
|
};
|
|
34
|
-
|
|
54
|
+
const changes = [];
|
|
55
|
+
if (shouldRemoveDynamicToolsProfile) {
|
|
56
|
+
delete nextPluginConfig.codexDynamicToolsProfile;
|
|
57
|
+
changes.push("Removed retired plugins.entries.codex.config.codexDynamicToolsProfile; Codex app-server always keeps Codex-native workspace tools native.");
|
|
58
|
+
}
|
|
59
|
+
if (shouldRewriteDestructivePolicy) {
|
|
60
|
+
const nextCodexPlugins = asRecord(nextPluginConfig.codexPlugins);
|
|
61
|
+
if (nextCodexPlugins?.allow_destructive_actions === "on-request") nextCodexPlugins.allow_destructive_actions = "auto";
|
|
62
|
+
const nextPluginPolicies = asRecord(nextCodexPlugins?.plugins);
|
|
63
|
+
for (const plugin of Object.values(nextPluginPolicies ?? {})) {
|
|
64
|
+
const nextPlugin = asRecord(plugin);
|
|
65
|
+
if (nextPlugin?.allow_destructive_actions === "on-request") nextPlugin.allow_destructive_actions = "auto";
|
|
66
|
+
}
|
|
67
|
+
changes.push("Renamed plugins.entries.codex.config.codexPlugins allow_destructive_actions=\"on-request\" values to \"auto\".");
|
|
68
|
+
}
|
|
35
69
|
return {
|
|
36
70
|
config: nextConfig,
|
|
37
|
-
changes
|
|
71
|
+
changes
|
|
38
72
|
};
|
|
39
73
|
}
|
|
40
74
|
/** Session/auth ownership metadata used by doctor route-state checks. */
|
package/dist/harness.js
CHANGED
|
@@ -32,25 +32,25 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
32
32
|
};
|
|
33
33
|
},
|
|
34
34
|
runAttempt: async (params) => {
|
|
35
|
-
const { runCodexAppServerAttempt } = await import("./run-attempt-
|
|
35
|
+
const { runCodexAppServerAttempt } = await import("./run-attempt-DRhB6bTc.js");
|
|
36
36
|
return runCodexAppServerAttempt(params, {
|
|
37
37
|
pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
|
|
38
38
|
nativeHookRelay: { enabled: true }
|
|
39
39
|
});
|
|
40
40
|
},
|
|
41
41
|
runSideQuestion: async (params) => {
|
|
42
|
-
const { runCodexAppServerSideQuestion } = await import("./side-question-
|
|
42
|
+
const { runCodexAppServerSideQuestion } = await import("./side-question-BdYL4kj1.js");
|
|
43
43
|
return runCodexAppServerSideQuestion(params, {
|
|
44
44
|
pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
|
|
45
45
|
nativeHookRelay: { enabled: true }
|
|
46
46
|
});
|
|
47
47
|
},
|
|
48
48
|
compact: async (params) => {
|
|
49
|
-
const { maybeCompactCodexAppServerSession } = await import("./compact-
|
|
49
|
+
const { maybeCompactCodexAppServerSession } = await import("./compact-CMVlldii.js");
|
|
50
50
|
return maybeCompactCodexAppServerSession(params, { pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig });
|
|
51
51
|
},
|
|
52
52
|
compactAfterContextEngine: async (params) => {
|
|
53
|
-
const { maybeCompactCodexAppServerSession } = await import("./compact-
|
|
53
|
+
const { maybeCompactCodexAppServerSession } = await import("./compact-CMVlldii.js");
|
|
54
54
|
return maybeCompactCodexAppServerSession(params, {
|
|
55
55
|
pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
|
|
56
56
|
allowNonManualNativeRequest: true
|
|
@@ -58,12 +58,12 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
58
58
|
},
|
|
59
59
|
reset: async (params) => {
|
|
60
60
|
if (params.sessionFile) {
|
|
61
|
-
const { clearCodexAppServerBinding } = await import("./session-binding-
|
|
61
|
+
const { clearCodexAppServerBinding } = await import("./session-binding-BRUi8y6E.js").then((n) => n.s);
|
|
62
62
|
await clearCodexAppServerBinding(params.sessionFile);
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
dispose: async () => {
|
|
66
|
-
const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-
|
|
66
|
+
const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-Bg5d7VV9.js").then((n) => n.c);
|
|
67
67
|
await clearSharedCodexAppServerClientAndWait();
|
|
68
68
|
}
|
|
69
69
|
};
|