@openclaw/codex 2026.5.16-beta.4 → 2026.5.16-beta.6
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/{command-handlers-jZV_1Ks9.js → command-handlers-DcoFMn4e.js} +86 -32
- package/dist/harness.js +6 -3
- package/dist/index.js +2 -2
- package/dist/{node-cli-sessions-BKhlcAB9.js → node-cli-sessions-C9rlYMPw.js} +79 -31
- package/dist/{run-attempt-DMKAwtUV.js → run-attempt-D6sdcUE0.js} +425 -119
- package/dist/{side-question-BYYJZq23.js → side-question-BzVnOoBU.js} +103 -16
- package/dist/test-api.js +1 -1
- package/dist/{thread-lifecycle-wcyYqwrl.js → thread-lifecycle-Cc_ljZLZ.js} +243 -21
- package/dist/{vision-tools-Cm_YicZb.js → vision-tools-BX9YuTEK.js} +203 -7
- package/package.json +5 -5
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { t as isJsonObject } from "./protocol-C9UWI98H.js";
|
|
2
2
|
import { r as formatCodexDisplayText } from "./command-formatters-BRW7_Nu7.js";
|
|
3
|
-
import {
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { buildAgentHookContextChannelFields, callGatewayTool, embeddedAgentLog, formatApprovalDisplayPath, hasNativeHookRelayInvocation, invokeNativeHookRelay, runBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
4
5
|
//#region extensions/codex/src/app-server/plugin-approval-roundtrip.ts
|
|
5
6
|
const DEFAULT_CODEX_APPROVAL_TIMEOUT_MS = 12e4;
|
|
6
7
|
const MAX_PLUGIN_APPROVAL_TITLE_LENGTH = 80;
|
|
@@ -89,9 +90,10 @@ async function handleCodexAppServerApprovalRequest(params) {
|
|
|
89
90
|
requestParams,
|
|
90
91
|
paramsForRun: params.paramsForRun,
|
|
91
92
|
context,
|
|
93
|
+
nativeHookRelay: params.nativeHookRelay,
|
|
92
94
|
signal: params.signal
|
|
93
95
|
});
|
|
94
|
-
if (policyOutcome?.
|
|
96
|
+
if (policyOutcome?.outcome === "denied") {
|
|
95
97
|
emitApprovalEvent(params.paramsForRun, {
|
|
96
98
|
phase: "resolved",
|
|
97
99
|
kind: context.kind,
|
|
@@ -221,6 +223,26 @@ async function runOpenClawToolPolicyForApprovalRequest(params) {
|
|
|
221
223
|
const policyRequest = buildOpenClawToolPolicyRequest(params.method, params.requestParams);
|
|
222
224
|
if (!policyRequest) return;
|
|
223
225
|
const cwd = readString$1(params.requestParams, "cwd") ?? params.paramsForRun.workspaceDir;
|
|
226
|
+
const nativeRelayOutcome = await runNativeRelayToolPolicyForApprovalRequest({
|
|
227
|
+
method: params.method,
|
|
228
|
+
requestParams: params.requestParams,
|
|
229
|
+
context: params.context,
|
|
230
|
+
policyRequest,
|
|
231
|
+
nativeHookRelay: params.nativeHookRelay,
|
|
232
|
+
cwd
|
|
233
|
+
});
|
|
234
|
+
if (nativeRelayOutcome?.blocked) return {
|
|
235
|
+
outcome: "denied",
|
|
236
|
+
reason: nativeRelayOutcome.reason
|
|
237
|
+
};
|
|
238
|
+
if (nativeRelayOutcome?.handled) return { outcome: "no-decision" };
|
|
239
|
+
const hookChannelId = buildAgentHookContextChannelFields({
|
|
240
|
+
sessionKey: params.paramsForRun.sessionKey,
|
|
241
|
+
messageChannel: params.paramsForRun.messageChannel,
|
|
242
|
+
messageProvider: params.paramsForRun.messageProvider,
|
|
243
|
+
currentChannelId: params.paramsForRun.currentChannelId,
|
|
244
|
+
messageTo: params.paramsForRun.messageTo
|
|
245
|
+
}).channelId;
|
|
224
246
|
const outcome = await runBeforeToolCallHook({
|
|
225
247
|
toolName: policyRequest.toolName,
|
|
226
248
|
params: policyRequest.params,
|
|
@@ -234,23 +256,108 @@ async function runOpenClawToolPolicyForApprovalRequest(params) {
|
|
|
234
256
|
...params.paramsForRun.sessionKey ? { sessionKey: params.paramsForRun.sessionKey } : {},
|
|
235
257
|
...params.paramsForRun.sessionId ? { sessionId: params.paramsForRun.sessionId } : {},
|
|
236
258
|
...params.paramsForRun.runId ? { runId: params.paramsForRun.runId } : {},
|
|
237
|
-
...
|
|
259
|
+
...hookChannelId ? { channelId: hookChannelId } : {}
|
|
238
260
|
}
|
|
239
261
|
});
|
|
240
262
|
if (outcome.blocked) return {
|
|
241
|
-
|
|
263
|
+
outcome: "denied",
|
|
242
264
|
reason: outcome.reason
|
|
243
265
|
};
|
|
244
266
|
if ("params" in outcome && toolPolicyParamsWereRewritten(policyRequest.params, outcome.params)) return {
|
|
245
|
-
|
|
267
|
+
outcome: "denied",
|
|
246
268
|
reason: "OpenClaw tool policy rewrote Codex app-server approval params; refusing original request."
|
|
247
269
|
};
|
|
248
270
|
}
|
|
271
|
+
async function runNativeRelayToolPolicyForApprovalRequest(params) {
|
|
272
|
+
if (params.method !== "item/commandExecution/requestApproval" || !params.nativeHookRelay?.allowedEvents.includes("pre_tool_use")) return;
|
|
273
|
+
const payload = buildNativeRelayPreToolUsePayload({
|
|
274
|
+
requestParams: params.requestParams,
|
|
275
|
+
policyRequest: params.policyRequest,
|
|
276
|
+
context: params.context,
|
|
277
|
+
cwd: params.cwd
|
|
278
|
+
});
|
|
279
|
+
if (!payload) return;
|
|
280
|
+
if (hasNativeHookRelayInvocation({
|
|
281
|
+
relayId: params.nativeHookRelay.relayId,
|
|
282
|
+
event: "pre_tool_use",
|
|
283
|
+
toolUseId: params.context.itemId
|
|
284
|
+
})) return { handled: true };
|
|
285
|
+
try {
|
|
286
|
+
const decision = readNativeRelayPreToolUseDecision(await invokeNativeHookRelay({
|
|
287
|
+
provider: "codex",
|
|
288
|
+
relayId: params.nativeHookRelay.relayId,
|
|
289
|
+
event: "pre_tool_use",
|
|
290
|
+
rawPayload: payload
|
|
291
|
+
}));
|
|
292
|
+
if (decision.blocked) return {
|
|
293
|
+
handled: true,
|
|
294
|
+
blocked: true,
|
|
295
|
+
reason: decision.reason
|
|
296
|
+
};
|
|
297
|
+
return { handled: true };
|
|
298
|
+
} catch (error) {
|
|
299
|
+
return {
|
|
300
|
+
handled: true,
|
|
301
|
+
blocked: true,
|
|
302
|
+
reason: `OpenClaw native hook relay unavailable for Codex app-server approval: ${formatCodexDisplayText(formatErrorMessage$1(error))}`
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function buildNativeRelayPreToolUsePayload(params) {
|
|
307
|
+
const command = readString$1(params.policyRequest.params, "command");
|
|
308
|
+
if (!command) return;
|
|
309
|
+
const turnId = readString$1(params.requestParams, "turnId");
|
|
310
|
+
return {
|
|
311
|
+
hook_event_name: "PreToolUse",
|
|
312
|
+
openclaw_approval_mode: "report",
|
|
313
|
+
tool_name: "exec_command",
|
|
314
|
+
...params.context.itemId ? { tool_use_id: params.context.itemId } : {},
|
|
315
|
+
...params.cwd ? { cwd: params.cwd } : {},
|
|
316
|
+
...turnId ? { turn_id: turnId } : {},
|
|
317
|
+
tool_input: {
|
|
318
|
+
...params.policyRequest.params,
|
|
319
|
+
command,
|
|
320
|
+
cmd: command
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
function readNativeRelayPreToolUseDecision(response) {
|
|
325
|
+
if (!response || response.exitCode !== 0) return {
|
|
326
|
+
blocked: true,
|
|
327
|
+
reason: sanitizeRelayDecisionReason(response?.stderr) || sanitizeRelayDecisionReason(response?.stdout) || "OpenClaw native hook relay failed for Codex app-server approval."
|
|
328
|
+
};
|
|
329
|
+
const stdout = response.stdout?.trim();
|
|
330
|
+
if (!stdout) return { blocked: false };
|
|
331
|
+
const parsed = parseRelayJsonResponse(stdout);
|
|
332
|
+
const output = isJsonObject(parsed?.hookSpecificOutput) ? parsed.hookSpecificOutput : void 0;
|
|
333
|
+
if (output?.permissionDecision === "deny") return {
|
|
334
|
+
blocked: true,
|
|
335
|
+
reason: readString$1(output, "permissionDecisionReason") || "OpenClaw native hook policy denied Codex app-server approval."
|
|
336
|
+
};
|
|
337
|
+
return {
|
|
338
|
+
blocked: true,
|
|
339
|
+
reason: output ? "OpenClaw native hook relay returned a non-deny Codex app-server approval decision." : "OpenClaw native hook relay returned an unreadable Codex app-server approval result."
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
function parseRelayJsonResponse(text) {
|
|
343
|
+
try {
|
|
344
|
+
const parsed = JSON.parse(text);
|
|
345
|
+
return isJsonObject(parsed) ? parsed : void 0;
|
|
346
|
+
} catch {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function sanitizeRelayDecisionReason(value) {
|
|
351
|
+
return sanitizeApprovalPreview(value ? {
|
|
352
|
+
value,
|
|
353
|
+
clipped: false
|
|
354
|
+
} : void 0, 240).text;
|
|
355
|
+
}
|
|
249
356
|
function buildOpenClawToolPolicyRequest(method, requestParams) {
|
|
250
357
|
if (method === "item/commandExecution/requestApproval") {
|
|
251
358
|
const command = readPolicyCommand(requestParams);
|
|
252
359
|
return {
|
|
253
|
-
toolName: "
|
|
360
|
+
toolName: "exec",
|
|
254
361
|
params: {
|
|
255
362
|
...command ? { command } : {},
|
|
256
363
|
...readString$1(requestParams, "cwd") ? { cwd: readString$1(requestParams, "cwd") } : {},
|
|
@@ -1120,10 +1227,99 @@ function readFirstString(record, keys) {
|
|
|
1120
1227
|
}
|
|
1121
1228
|
}
|
|
1122
1229
|
//#endregion
|
|
1230
|
+
//#region extensions/codex/src/app-server/native-hook-relay.ts
|
|
1231
|
+
const CODEX_NATIVE_HOOK_RELAY_EVENTS = [
|
|
1232
|
+
"pre_tool_use",
|
|
1233
|
+
"post_tool_use",
|
|
1234
|
+
"permission_request",
|
|
1235
|
+
"before_agent_finalize"
|
|
1236
|
+
];
|
|
1237
|
+
const CODEX_HOOK_EVENT_BY_NATIVE_EVENT = {
|
|
1238
|
+
pre_tool_use: "PreToolUse",
|
|
1239
|
+
post_tool_use: "PostToolUse",
|
|
1240
|
+
permission_request: "PermissionRequest",
|
|
1241
|
+
before_agent_finalize: "Stop"
|
|
1242
|
+
};
|
|
1243
|
+
const CODEX_HOOK_KEY_LABEL_BY_NATIVE_EVENT = {
|
|
1244
|
+
pre_tool_use: "pre_tool_use",
|
|
1245
|
+
post_tool_use: "post_tool_use",
|
|
1246
|
+
permission_request: "permission_request",
|
|
1247
|
+
before_agent_finalize: "stop"
|
|
1248
|
+
};
|
|
1249
|
+
const CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS = ["/<session-flags>/config.toml", "<session-flags>/config.toml"];
|
|
1250
|
+
function buildCodexNativeHookRelayConfig(params) {
|
|
1251
|
+
const events = params.events?.length ? params.events : CODEX_NATIVE_HOOK_RELAY_EVENTS;
|
|
1252
|
+
const selectedEvents = new Set(events);
|
|
1253
|
+
const config = { "features.hooks": true };
|
|
1254
|
+
const hookState = {};
|
|
1255
|
+
for (const event of CODEX_NATIVE_HOOK_RELAY_EVENTS) {
|
|
1256
|
+
const codexEvent = CODEX_HOOK_EVENT_BY_NATIVE_EVENT[event];
|
|
1257
|
+
const selected = selectedEvents.has(event);
|
|
1258
|
+
if (!selected || !params.relay.shouldRelayEvent(event)) {
|
|
1259
|
+
if (selected || params.clearOmittedEvents) config[`hooks.${codexEvent}`] = [];
|
|
1260
|
+
if (params.clearOmittedEvents) for (const sourcePath of CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS) hookState[`${sourcePath}:${CODEX_HOOK_KEY_LABEL_BY_NATIVE_EVENT[event]}:0:0`] = { enabled: false };
|
|
1261
|
+
continue;
|
|
1262
|
+
}
|
|
1263
|
+
const command = params.relay.commandForEvent(event);
|
|
1264
|
+
const timeout = normalizeHookTimeoutSec(params.hookTimeoutSec);
|
|
1265
|
+
config[`hooks.${codexEvent}`] = [{ hooks: [{
|
|
1266
|
+
type: "command",
|
|
1267
|
+
command,
|
|
1268
|
+
timeout,
|
|
1269
|
+
async: false,
|
|
1270
|
+
statusMessage: "OpenClaw native hook relay"
|
|
1271
|
+
}] }];
|
|
1272
|
+
const state = {
|
|
1273
|
+
enabled: true,
|
|
1274
|
+
trusted_hash: codexCommandHookTrustedHash({
|
|
1275
|
+
event,
|
|
1276
|
+
command,
|
|
1277
|
+
timeout,
|
|
1278
|
+
statusMessage: "OpenClaw native hook relay"
|
|
1279
|
+
})
|
|
1280
|
+
};
|
|
1281
|
+
for (const sourcePath of CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS) hookState[`${sourcePath}:${CODEX_HOOK_KEY_LABEL_BY_NATIVE_EVENT[event]}:0:0`] = state;
|
|
1282
|
+
}
|
|
1283
|
+
config["hooks.state"] = hookState;
|
|
1284
|
+
return config;
|
|
1285
|
+
}
|
|
1286
|
+
function buildCodexNativeHookRelayDisabledConfig() {
|
|
1287
|
+
return {
|
|
1288
|
+
"features.hooks": false,
|
|
1289
|
+
"hooks.PreToolUse": [],
|
|
1290
|
+
"hooks.PostToolUse": [],
|
|
1291
|
+
"hooks.PermissionRequest": [],
|
|
1292
|
+
"hooks.Stop": []
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
function normalizeHookTimeoutSec(value) {
|
|
1296
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.ceil(value) : 5;
|
|
1297
|
+
}
|
|
1298
|
+
function codexCommandHookTrustedHash(params) {
|
|
1299
|
+
const identity = {
|
|
1300
|
+
event_name: CODEX_HOOK_KEY_LABEL_BY_NATIVE_EVENT[params.event],
|
|
1301
|
+
hooks: [{
|
|
1302
|
+
async: false,
|
|
1303
|
+
command: params.command,
|
|
1304
|
+
statusMessage: params.statusMessage,
|
|
1305
|
+
timeout: params.timeout,
|
|
1306
|
+
type: "command"
|
|
1307
|
+
}]
|
|
1308
|
+
};
|
|
1309
|
+
return `sha256:${createHash("sha256").update(JSON.stringify(sortJsonValue(identity))).digest("hex")}`;
|
|
1310
|
+
}
|
|
1311
|
+
function sortJsonValue(value) {
|
|
1312
|
+
if (!value || typeof value !== "object") return value;
|
|
1313
|
+
if (Array.isArray(value)) return value.map(sortJsonValue);
|
|
1314
|
+
const sorted = {};
|
|
1315
|
+
for (const key of Object.keys(value).toSorted()) sorted[key] = sortJsonValue(value[key]);
|
|
1316
|
+
return sorted;
|
|
1317
|
+
}
|
|
1318
|
+
//#endregion
|
|
1123
1319
|
//#region extensions/codex/src/app-server/vision-tools.ts
|
|
1124
1320
|
function filterToolsForVisionInputs(tools, params) {
|
|
1125
1321
|
if (!params.modelHasVision || !params.hasInboundImages) return tools;
|
|
1126
1322
|
return tools.filter((tool) => tool.name !== "image");
|
|
1127
1323
|
}
|
|
1128
1324
|
//#endregion
|
|
1129
|
-
export { handleCodexAppServerElicitationRequest as n, handleCodexAppServerApprovalRequest as r, filterToolsForVisionInputs as t };
|
|
1325
|
+
export { handleCodexAppServerElicitationRequest as a, buildCodexNativeHookRelayDisabledConfig as i, CODEX_NATIVE_HOOK_RELAY_EVENTS as n, handleCodexAppServerApprovalRequest as o, buildCodexNativeHookRelayConfig as r, filterToolsForVisionInputs as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/codex",
|
|
3
|
-
"version": "2026.5.16-beta.
|
|
3
|
+
"version": "2026.5.16-beta.6",
|
|
4
4
|
"description": "OpenClaw Codex harness and model provider plugin",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@earendil-works/pi-coding-agent": "0.74.
|
|
11
|
+
"@earendil-works/pi-coding-agent": "0.74.1",
|
|
12
12
|
"@openai/codex": "0.130.0",
|
|
13
13
|
"ajv": "8.20.0",
|
|
14
14
|
"ws": "8.20.1",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"minHostVersion": ">=2026.5.1-beta.1"
|
|
28
28
|
},
|
|
29
29
|
"compat": {
|
|
30
|
-
"pluginApi": ">=2026.5.16-beta.
|
|
30
|
+
"pluginApi": ">=2026.5.16-beta.6"
|
|
31
31
|
},
|
|
32
32
|
"build": {
|
|
33
|
-
"openclawVersion": "2026.5.16-beta.
|
|
33
|
+
"openclawVersion": "2026.5.16-beta.6"
|
|
34
34
|
},
|
|
35
35
|
"release": {
|
|
36
36
|
"publishToClawHub": true,
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"openclaw.plugin.json"
|
|
46
46
|
],
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"openclaw": ">=2026.5.16-beta.
|
|
48
|
+
"openclaw": ">=2026.5.16-beta.6"
|
|
49
49
|
},
|
|
50
50
|
"peerDependenciesMeta": {
|
|
51
51
|
"openclaw": {
|