@openclaw/codex 2026.10.1-beta.2 → 2026.10.5-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/.setup/{account-usage-runtime-DGqFpAud.mjs → account-usage-runtime-QBZsvZS8.mjs} +8 -7
- package/dist/.setup/{app-server-policy-Bg4FZw1f.mjs → app-server-policy-D_zv8J7V.mjs} +3 -4
- package/dist/.setup/{apply-CXTudl9p.mjs → apply-CBMV8LN0.mjs} +40 -51
- package/dist/.setup/{attempt-client-cleanup-BH0hW2xU.mjs → attempt-client-cleanup-t-kd_1ys.mjs} +6 -6
- package/dist/.setup/attempt-terminal-jO5IMj9K.mjs +2 -0
- package/dist/.setup/{attempt-workspace-context-BY0jprWJ.mjs → attempt-workspace-context-CcwP3DA3.mjs} +21 -18
- package/dist/.setup/{auth-binding-BoMwpuPN.mjs → auth-binding-BaxlhaNx.mjs} +2 -2
- package/dist/.setup/{auth-cache-key-CGm0UJOr.mjs → auth-cache-key-DyfUvsSa.mjs} +30 -41
- package/dist/.setup/{binding-connection-C-08ez1w.mjs → binding-connection-B7HAAZSI.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-Dn2p-fdy.mjs → binding-connection.runtime-DAXn7iFl.mjs} +6 -5
- package/dist/.setup/{bounded-turn-pGsfXcmH.mjs → bounded-turn-CyQVQwGe.mjs} +21 -17
- package/dist/.setup/{bounded-turn-isolation-DklXNk3k.mjs → bounded-turn-isolation-BfDAo-qZ.mjs} +4 -4
- package/dist/.setup/{build-state-CqQnsg7T.mjs → build-state-CzLMy1S9.mjs} +1 -1
- package/dist/.setup/{capabilities-kQntafj_.mjs → capabilities-DbOzOglY.mjs} +1 -1
- package/dist/.setup/{client-catalog-response-Bqp7WG51.mjs → client-catalog-response-DsbEAtpd.mjs} +25 -32
- package/dist/.setup/{client-C8lgBOoO.mjs → client-y7nO6X9c.mjs} +198 -247
- package/dist/.setup/{command-dispatch-DhBbFIQ5.mjs → command-dispatch-uA9lz2Kf.mjs} +3 -4
- package/dist/.setup/{command-formatters-DV3DHhdr.mjs → command-formatters-xW9KpoSZ.mjs} +16 -26
- package/dist/.setup/{command-handlers-ztOOzm6O.mjs → command-handlers-VBaJnpZo.mjs} +270 -360
- package/dist/.setup/{command-rpc-CuC5fPom.mjs → command-rpc-C9VxOLuG.mjs} +19 -18
- package/dist/.setup/{compact-tUb9AYfH.mjs → compact-CD8xJxXS.mjs} +41 -61
- package/dist/.setup/{computer-use-BBN9y326.mjs → computer-use-CiToXF5C.mjs} +109 -147
- package/dist/.setup/{config-0Gxk3_eq.mjs → config-C1YVVLEA.mjs} +32 -59
- package/dist/.setup/config-contracts.shared-D85SGEuq.mjs +4 -0
- package/dist/.setup/{config-options-HG_Rr3W_.mjs → config-options-DDzeNQ8m.mjs} +52 -90
- package/dist/.setup/{config-parsing-BQq-CHTF.mjs → config-parsing-DsWSCPHO.mjs} +19 -55
- package/dist/.setup/{config-runtime-cUYrqu_a.mjs → config-runtime-DWzK-k0n.mjs} +2 -2
- package/dist/.setup/{config-security-KAPScztc.mjs → config-security-clxAZYWX.mjs} +35 -39
- package/dist/.setup/config-utils-DN_YT7dE.mjs +47 -0
- package/dist/.setup/{context-engine-projection-CsgYSQhW.mjs → context-engine-projection-ps-yn_ci.mjs} +10 -22
- package/dist/.setup/{conversation-binding-B3MNMVzb.mjs → conversation-binding-CTSLDM9S.mjs} +85 -119
- package/dist/.setup/{conversation-binding-data-DJ4ix-W5.mjs → conversation-binding-data-UgLuTSQT.mjs} +9 -8
- package/dist/.setup/{conversation-control-CYsMlCuE.mjs → conversation-control-GXM3unE4.mjs} +7 -10
- package/dist/.setup/{cyber-failover-Bb1J6hS1.mjs → cyber-failover-D4dgNfFf.mjs} +2 -5
- package/dist/.setup/{cyber-failover-notice-XR03ef31.mjs → cyber-failover-notice-ljgGGL0s.mjs} +1 -1
- package/dist/.setup/{doctor-start-options-DPW9JxIE.mjs → doctor-start-options-JjTAl-q_.mjs} +5 -5
- package/dist/.setup/{dynamic-tool-build-C8xGEXmR.mjs → dynamic-tool-build-D731PCdv.mjs} +57 -69
- package/dist/.setup/{dynamic-tools-DyERJnR6.mjs → dynamic-tools-D0pYbxHH.mjs} +689 -710
- package/dist/.setup/{effective-mcp-catalog-C26Mio5l.mjs → effective-mcp-catalog-1hWFKghy.mjs} +11 -20
- package/dist/.setup/{elicitation-input-r9axtppm.mjs → elicitation-input-DXG_qaXr.mjs} +14 -20
- package/dist/.setup/{ephemeral-turn-D8VcDTNo.mjs → ephemeral-turn-Cphy5Qr_.mjs} +3 -3
- package/dist/.setup/{event-projector-assistant-message-BN7CNUB5.mjs → event-projector-assistant-message-CLMKN4x-.mjs} +2 -2
- package/dist/.setup/{event-projector-usage-03R0I2dM.mjs → event-projector-usage-BpKfdoTm.mjs} +20 -33
- package/dist/.setup/{event-projector-values-DTqZHizf.mjs → event-projector-values-CLvG1Hil.mjs} +4 -5
- package/dist/.setup/history-rejection-B4nOXNXF.mjs +13 -0
- package/dist/.setup/{inference-context-D-9gWlTR.mjs → inference-context-DNlGwzwy.mjs} +10 -11
- package/dist/.setup/{inference-dispatch-B5UKEUyC.mjs → inference-dispatch-CO6tTs4q.mjs} +5 -4
- package/dist/.setup/{inference-metadata-CgIf7sOx.mjs → inference-metadata-DCvcG_N_.mjs} +36 -41
- package/dist/.setup/{inference-proxy-DUO5E2QQ.mjs → inference-proxy-BDWV0djM.mjs} +10 -14
- package/dist/.setup/{isolated-completion-C0jrcplS.mjs → isolated-completion-Bhqd2yBq.mjs} +8 -8
- package/dist/.setup/local-runtime-attribution-CZz2DJ4q.mjs +15 -0
- package/dist/.setup/{managed-binary-C1VFoVPf.mjs → managed-binary-BtIjV7yN.mjs} +16 -36
- package/dist/.setup/{mcp-app-session-preparation-BxN0_CYe.mjs → mcp-app-session-preparation-DqSvxFqc.mjs} +24 -25
- package/dist/.setup/{mcp-tool-metadata-j10HhfTC.mjs → mcp-tool-metadata-DW41snf3.mjs} +1 -1
- package/dist/.setup/{model-catalog-DZyNeDKG.mjs → model-catalog-B227ST3D.mjs} +6 -6
- package/dist/.setup/{models-DSseKSMg.mjs → models-DdRyi93L.mjs} +6 -10
- package/dist/.setup/{native-auth-Cjb9y7IZ.mjs → native-auth-esN5MdIv.mjs} +5 -5
- package/dist/.setup/{native-execution-policy-ClzpdG3D.mjs → native-execution-policy-MXEe7PB3.mjs} +11 -28
- package/dist/.setup/native-hook-relay-BUWIOrSr.mjs +561 -0
- package/dist/.setup/{native-mcp-app-CqcPVmhH.mjs → native-mcp-app-CjxJQ4F7.mjs} +6 -6
- package/dist/.setup/native-skill-isolation-UMVoNjZz.mjs +391 -0
- package/dist/.setup/{native-subagent-monitor-BUYOUp9X.mjs → native-subagent-monitor-iHc8oLg5.mjs} +505 -639
- package/dist/.setup/{native-subagent-pending-assignments-BDqhOdJp.mjs → native-subagent-pending-assignments-DmVhedNs.mjs} +11 -23
- package/dist/.setup/{native-task-assignments-C6KVqiN1.mjs → native-task-assignments-DimsQ9Qa.mjs} +73 -27
- package/dist/.setup/{node-cli-sessions-B5oNDkUS.mjs → node-cli-sessions-CzKg2nGq.mjs} +18 -26
- package/dist/.setup/{node-exec-server.runtime-0xSEjKYt.mjs → node-exec-server.runtime-BWkULhBM.mjs} +5 -8
- package/dist/.setup/{plan-BJ37d2Og.mjs → plan-C_F3aio0.mjs} +40 -50
- package/dist/.setup/{plugin-activation-BcyBv8PG.mjs → plugin-activation-D7WkJMvU.mjs} +4 -5
- package/dist/.setup/{plugin-app-cache-key-BW8rd98k.mjs → plugin-app-cache-key-Bg9DbDI6.mjs} +18 -23
- package/dist/.setup/{plugin-approval-roundtrip-CuahdPLC.mjs → plugin-approval-roundtrip-BSV-51ig.mjs} +4 -6
- package/dist/.setup/{plugin-inventory-Bf0_piTw.mjs → plugin-inventory-CYgdo14P.mjs} +28 -43
- package/dist/.setup/{plugin-marketplace-discovery-SQPhSuic.mjs → plugin-marketplace-discovery-BblHM3DU.mjs} +7 -10
- package/dist/.setup/{plugin-metadata-cache-DWnB7VMj.mjs → plugin-metadata-cache-Bi8TAPwX.mjs} +5 -10
- package/dist/.setup/project-doc-thread-config-BVcvnps8.mjs +490 -0
- package/dist/.setup/{provider-BnwHVD_z.mjs → provider-BJ4xhaGX.mjs} +4 -4
- package/dist/.setup/{provider-capabilities-D68Whix6.mjs → provider-capabilities-CjRaV3bx.mjs} +1 -1
- package/dist/.setup/{rate-limits-CMPy24F5.mjs → rate-limits-CI8pTPqL.mjs} +15 -32
- package/dist/.setup/reasoning-effort-CS9kKWB9.mjs +37 -0
- package/dist/.setup/{request-jSbhc1sg.mjs → request-Y8dmbqZ3.mjs} +28 -48
- package/dist/.setup/{rpc-error-hmWM21RB.mjs → rpc-error-C98SHchT.mjs} +3 -6
- package/dist/.setup/{run-attempt-BLDZeYLD.mjs → run-attempt-Dx7a4Mfm.mjs} +927 -849
- package/dist/.setup/{run-attempt-lifecycle-BuZgVbDA.mjs → run-attempt-lifecycle-KN4oh-7O.mjs} +13 -4
- package/dist/.setup/{runtime-artifact-CUTOOnKw.mjs → runtime-artifact-C13pR7tD.mjs} +18 -22
- package/dist/.setup/{runtime-artifact-connection-CADz3_BY.mjs → runtime-artifact-connection-jS5DeCok.mjs} +3 -3
- package/dist/.setup/{sandbox-guard-WqE8yPge.mjs → sandbox-guard-DIImwCy1.mjs} +4 -6
- package/dist/.setup/service-tier-normalization-BPgw2Wdt.mjs +9 -0
- package/dist/.setup/{session-binding-Ce7BqiPN.mjs → session-binding-JEHNMPsr.mjs} +13 -40
- package/dist/.setup/{session-binding-record-BZB8RgcF.mjs → session-binding-record-DU_0biMD.mjs} +4 -4
- package/dist/.setup/{session-binding-record-codec-z4ZpDn6E.mjs → session-binding-record-codec-BpH8u_G9.mjs} +16 -39
- package/dist/.setup/{session-binding-sidecars-BrdV95Fg.mjs → session-binding-sidecars-DD-enC8w.mjs} +49 -54
- package/dist/.setup/{session-catalog-adoption-CPIP4S_y.mjs → session-catalog-adoption-Ca3OYGYM.mjs} +23 -27
- package/dist/.setup/{session-catalog-archive-DcgwvSbF.mjs → session-catalog-archive-Bv6gV7x9.mjs} +6 -6
- package/dist/.setup/{session-catalog-events-Bdjw9HEn.mjs → session-catalog-events-DzFlXNUe.mjs} +6 -5
- package/dist/.setup/{session-catalog-index-DufISKJ6.mjs → session-catalog-index-DozvkUPd.mjs} +111 -105
- package/dist/.setup/{session-catalog-index-order-nhyO0wdW.mjs → session-catalog-index-order-CTfoefow.mjs} +28 -5
- package/dist/.setup/{session-catalog-limits-DEU36Qlo.mjs → session-catalog-limits-BynIoOYm.mjs} +1 -1
- package/dist/.setup/{session-catalog-list-request-tXephOB4.mjs → session-catalog-list-request-D4MYNgDB.mjs} +11 -8
- package/dist/.setup/{session-catalog-native-projection-D6IiLtMb.mjs → session-catalog-native-projection-rCKnZud1.mjs} +5 -61
- package/dist/.setup/{session-catalog-node-adoption-7-WEQTB1.mjs → session-catalog-node-adoption-BdP9Zjqo.mjs} +2 -2
- package/dist/.setup/{session-catalog-node-continue-DLWBwAAO.mjs → session-catalog-node-continue-CNJibO4_.mjs} +27 -49
- package/dist/.setup/{session-catalog-node-lookup-Uufckwcm.mjs → session-catalog-node-lookup-BH_DBGa9.mjs} +3 -3
- package/dist/.setup/{session-catalog-parsing-B-qWJh2x.mjs → session-catalog-parsing-DkeoVn60.mjs} +9 -19
- package/dist/.setup/{session-catalog-projection-8aHNwzWD.mjs → session-catalog-projection-DDVmALHj.mjs} +8 -22
- package/dist/.setup/session-catalog-source-CygTGmrb.mjs +58 -0
- package/dist/.setup/{session-cli-kH4vuGod.mjs → session-cli-GwU0izn-.mjs} +20 -41
- package/dist/.setup/{session-history-BogBHKLk.mjs → session-history-BO6i_pfk.mjs} +1 -1
- package/dist/.setup/{session-history-import-NWKPa4ZO.mjs → session-history-import-CaO8s6ta.mjs} +4 -4
- package/dist/.setup/{session-history-read-CNN8zwbD.mjs → session-history-read-BI_2jRED.mjs} +4 -15
- package/dist/.setup/{session-history.worker-Cq_4DYgN.mjs → session-history.worker-DJQfek5p.mjs} +147 -159
- package/dist/.setup/{session-initialization-D6dtFQkE.mjs → session-initialization-Bi_2DKhc.mjs} +3 -5
- package/dist/.setup/{session-permission-policy-BxIUJ0Zd.mjs → session-permission-policy-CD2MAWU8.mjs} +12 -20
- package/dist/.setup/{session-retirement-Czbchv_O.mjs → session-retirement-IoS3zr17.mjs} +7 -7
- package/dist/.setup/{settled-turn-context-BZsMjkIO.mjs → settled-turn-context-BPL6D3RO.mjs} +1 -1
- package/dist/.setup/{settled-turn-finalizer-DjZsIwbZ.mjs → settled-turn-finalizer-X-Fylp-u.mjs} +12 -11
- package/dist/.setup/{shared-client-qhyYWbew.mjs → shared-client-ByIwuAC-.mjs} +172 -229
- package/dist/.setup/{side-question-D3NJlgbl.mjs → side-question-BDUdozFy.mjs} +116 -137
- package/dist/.setup/{source-BYu0T780.mjs → source-Bxbqf3S1.mjs} +37 -56
- package/dist/.setup/thread-archive-guard-LKdwQKyr.mjs +56 -0
- package/dist/.setup/{thread-lifecycle-Cbz_7ySv.mjs → thread-lifecycle-run-CfP4PnEf.mjs} +348 -484
- package/dist/.setup/thread-model-selection-DcVebr8N.mjs +61 -0
- package/dist/.setup/{thread-ownership-DwuSrt3s.mjs → thread-ownership-Be53aiaG.mjs} +5 -5
- package/dist/.setup/{thread-ownership-queue-Dp24d7-F.mjs → thread-ownership-queue-CeyYScUC.mjs} +5 -6
- package/dist/.setup/{thread-policy-DoNxbhqt.mjs → thread-policy-CHgY-KNl.mjs} +4 -4
- package/dist/.setup/thread-requests-BgzJwJtS.mjs +745 -0
- package/dist/.setup/{thread-resume-BT6NHMkM.mjs → thread-resume-B2EmMcgE.mjs} +5 -5
- package/dist/.setup/{timeout-CXOfNoaX.mjs → timeout-D0mEWSGG.mjs} +6 -12
- package/dist/.setup/{transcript-history-projection-B9a7HwUV.mjs → transcript-history-projection-DfKcoZCB.mjs} +3 -4
- package/dist/.setup/{transcript-mirror-BfLRARNL.mjs → transcript-mirror-Bee2o6jj.mjs} +68 -68
- package/dist/.setup/{transcript-mirror-attestation-YSegaktH.mjs → transcript-mirror-attestation-BzUXnrvv.mjs} +5 -2
- package/dist/.setup/{transport-stdio-a0HDa2Mj.mjs → transport-stdio-CRWTkKOn.mjs} +67 -77
- package/dist/.setup/{transport-websocket-zqJ0Cmtn.mjs → transport-websocket-DIyPfkHo.mjs} +8 -16
- package/dist/.setup/{turn-router-sS69wYnI.mjs → turn-router-DKDAziUW.mjs} +30 -31
- package/dist/.setup/upstream-prompt-provenance-Ccd9MFRJ.mjs +44 -0
- package/dist/.setup/{upstream-session-fork-ChSld66u.mjs → upstream-session-fork-Djp_yssT.mjs} +50 -43
- package/dist/.setup/{usage-D8e8Xiqf.mjs → usage-DQA-peQC.mjs} +4 -4
- package/dist/.setup/{usage-limit-error-GbT-5NcW.mjs → usage-limit-error-2t3KBqiX.mjs} +12 -21
- package/dist/.setup/web-search-item-CvokaZOo.mjs +20 -0
- package/dist/.setup/{web-search-provider.runtime-dL2GD1Kl.mjs → web-search-provider.runtime-BsuCMNix.mjs} +3 -3
- package/dist/.setup/{workspace-write-sandbox-probe-DmUHLrrl.mjs → workspace-write-sandbox-probe-BDWO2Qkh.mjs} +4 -4
- package/dist/api.js +15 -15
- package/dist/catalog-page.worker.js +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/doctor-contract-api.js +5 -6
- package/dist/harness.js +32 -61
- package/dist/index.js +302 -416
- package/dist/media-understanding-provider.js +32 -43
- package/dist/migration-provider-api.js +1 -1
- package/dist/native-session-binding-api.js +1 -1
- package/dist/native-tool-policy.js +23 -1
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-runtime.js +52 -31
- package/dist/session-history.worker.js +1 -1
- package/openclaw.plugin.json +20 -3
- package/package.json +7 -7
- package/dist/.setup/attempt-terminal-gZrxQ35N.mjs +0 -5
- package/dist/.setup/plugin-thread-config-deadline-B8LGaZNW.mjs +0 -124
- package/dist/.setup/service-tier-normalization-Cei89SW6.mjs +0 -15
- package/dist/.setup/shell-dynamic-tools-D3Brj3g9.mjs +0 -85
- package/dist/.setup/thread-archive-guard-C9frICzX.mjs +0 -60
- package/dist/.setup/thread-requests-CL1e8Wmx.mjs +0 -2111
- package/dist/.setup/upstream-prompt-provenance-fXkKbPVC.mjs +0 -37
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
|
|
2
|
+
import { l as fingerprintCodexPolicy } from "./config-security-clxAZYWX.mjs";
|
|
3
|
+
import { D as nativeHookRelayUnregisterQueue } from "./shared-client-ByIwuAC-.mjs";
|
|
4
|
+
import { k as resolveCodexToolAbortTerminalReason } from "./client-y7nO6X9c.mjs";
|
|
5
|
+
import { R as normalizeCodexDynamicToolName } from "./thread-requests-BgzJwJtS.mjs";
|
|
6
|
+
import { t as codexNativeSubagentMonitorRuntime } from "./native-subagent-monitor-iHc8oLg5.mjs";
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
import { addTimerTimeoutGraceMs, finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
|
|
9
|
+
import { escapeRegExp } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { toErrorObject } from "openclaw/plugin-sdk/error-runtime";
|
|
12
|
+
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
13
|
+
import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
14
|
+
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
15
|
+
import { pinExecToolTarget } from "openclaw/plugin-sdk/codex-mcp-projection";
|
|
16
|
+
import { loadNodeExecAvailability } from "openclaw/plugin-sdk/node-selection-runtime";
|
|
17
|
+
import { registerNativeHookRelayForBundledRuntime } from "openclaw/plugin-sdk/native-hook-relay-runtime";
|
|
18
|
+
//#region extensions/codex/src/app-server/shell-dynamic-tools.ts
|
|
19
|
+
const CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME = "node_exec";
|
|
20
|
+
const CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME = "gateway_exec";
|
|
21
|
+
const CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME = "gateway_process";
|
|
22
|
+
const CODEX_DISABLED_NATIVE_SHELL_DYNAMIC_TOOLS = /* @__PURE__ */ new Set([
|
|
23
|
+
"exec",
|
|
24
|
+
"process",
|
|
25
|
+
"sandbox_exec",
|
|
26
|
+
"sandbox_process",
|
|
27
|
+
CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME,
|
|
28
|
+
CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME,
|
|
29
|
+
CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME
|
|
30
|
+
]);
|
|
31
|
+
const PROCESS_FOLLOWUP_TEXT = "Use process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up.";
|
|
32
|
+
function isCodexDynamicToolExcluded(config, names) {
|
|
33
|
+
const normalizedNames = new Set(names.map((name) => normalizeCodexDynamicToolName(name)));
|
|
34
|
+
return (config.codexDynamicToolsExclude ?? []).some((name) => normalizedNames.has(normalizeCodexDynamicToolName(name)));
|
|
35
|
+
}
|
|
36
|
+
async function createNodeExecAliasDynamicTool(execTool, node, discoverySignal, availabilityRef) {
|
|
37
|
+
const pinnedNode = node?.trim();
|
|
38
|
+
const availability = await (availabilityRef ? availabilityRef.current ??= loadNodeExecAvailability(discoverySignal) : loadNodeExecAvailability(discoverySignal));
|
|
39
|
+
discoverySignal?.throwIfAborted();
|
|
40
|
+
if (!availability.isAvailable(pinnedNode)) return;
|
|
41
|
+
const pinnedTool = pinExecToolTarget(execTool, {
|
|
42
|
+
host: "node",
|
|
43
|
+
...pinnedNode ? { node: pinnedNode } : {}
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
...pinnedTool,
|
|
47
|
+
name: CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME,
|
|
48
|
+
description: pinnedNode ? "Run a shell command to completion on the OpenClaw configured remote node for this session. This tool always uses OpenClaw host=node internally and follows the existing node exec approval and allowlist policy. Remote-node background follow-up is unavailable. Use Codex's native shell for local app-server work when it is available." : "Run a shell command to completion on an OpenClaw remote node. The sole connected node that can execute commands is selected automatically; select by name or id when several can. This tool always uses OpenClaw host=node internally and follows the existing node exec approval and allowlist policy. Remote-node background follow-up is unavailable. Use Codex's native shell for local app-server work when it is available.",
|
|
49
|
+
execute: withProcessFollowupText(pinnedTool, "Remote-node background follow-up is unavailable. Wait for the command to complete.")
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function createGatewayExecProjection(createProjection, execTool, params) {
|
|
53
|
+
return createProjection(execTool, {
|
|
54
|
+
kind: "exec",
|
|
55
|
+
name: CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME,
|
|
56
|
+
description: "Run a shell command through OpenClaw on the Gateway host for OpenClaw-managed Gateway environment access, including Secret Store agent-readable environment values and protected egress sentinels. Native Codex shell remains preferred for ordinary local work. This tool always uses OpenClaw host=gateway internally and follows Gateway exec approval and allowlist policy.",
|
|
57
|
+
followupText: params.processAliasAvailable ? "Use gateway_process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up." : "Background session follow-up is unavailable because gateway_process is not exposed. Rerun without background=true and set yieldMs high enough to wait for completion.",
|
|
58
|
+
...params.ask ? { ask: params.ask } : {}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function createGatewayProcessProjection(createProjection, processTool) {
|
|
62
|
+
return createProjection(processTool, {
|
|
63
|
+
kind: "process",
|
|
64
|
+
name: CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME,
|
|
65
|
+
description: "Manage background shell sessions in the existing per-session OpenClaw process scope: list, poll, log, write, send-keys, submit, paste, kill, clear, or remove. Use for gateway_exec follow-up; use native Codex shell session handling for ordinary local work."
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function createSandboxShellProjection(tool, kind) {
|
|
69
|
+
const projected = {
|
|
70
|
+
...tool,
|
|
71
|
+
name: `sandbox_${kind}`,
|
|
72
|
+
description: kind === "exec" ? "Run a shell command through OpenClaw's configured sandbox backend for this session. Use when OpenClaw sandboxing is active or when a command must execute in the sandbox backend, such as an SSH-backed sandbox or Docker container-path bind layout. Use Codex's native shell only when no OpenClaw sandbox is active and native Code Mode is available." : "Manage background shell sessions through OpenClaw's configured sandbox backend for this session: list, poll, log, write, send-keys, submit, paste, kill, clear, or remove. Use only for sandbox follow-up; use Codex's native shell session handling only when no OpenClaw sandbox is active and native Code Mode is available."
|
|
73
|
+
};
|
|
74
|
+
if (kind === "exec") projected.execute = withProcessFollowupText(tool, "Use sandbox_process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up.");
|
|
75
|
+
return projected;
|
|
76
|
+
}
|
|
77
|
+
function withProcessFollowupText(tool, followupText) {
|
|
78
|
+
return async (toolCallId, args, signal, onUpdate) => {
|
|
79
|
+
const result = await tool.execute(toolCallId, args, signal, onUpdate);
|
|
80
|
+
return {
|
|
81
|
+
...result,
|
|
82
|
+
content: result.content.map((item) => item.type === "text" ? Object.assign({}, item, { text: item.text.replace(PROCESS_FOLLOWUP_TEXT, followupText) }) : item)
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/** Keeps replacement shell tools direct even when model metadata mandates Codex Code Mode. */
|
|
87
|
+
function placeDisabledNativeShellToolsInDirectNamespace(tools, nativeToolSurfaceEnabled) {
|
|
88
|
+
if (nativeToolSurfaceEnabled !== false) return tools;
|
|
89
|
+
for (const tool of tools) if (CODEX_DISABLED_NATIVE_SHELL_DYNAMIC_TOOLS.has(normalizeCodexDynamicToolName(tool.name))) tool.catalogMode = "direct-only";
|
|
90
|
+
return tools;
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region extensions/codex/src/app-server/native-hook-relay-remote.ts
|
|
94
|
+
const projections = new KeyedAsyncQueue();
|
|
95
|
+
const projectionOwners = /* @__PURE__ */ new Map();
|
|
96
|
+
/** Native ephemeral threads keep their command config across foreground runs. */
|
|
97
|
+
function codexNativeHookRemoteCredentialPath(config, relayId, generation) {
|
|
98
|
+
return path.posix.join(config.credentialDirectory, `${encodeURIComponent(relayId)}.${encodeURIComponent(generation)}.json`);
|
|
99
|
+
}
|
|
100
|
+
/** The deployment owns the private directory; the live relay owns this projection. */
|
|
101
|
+
function createCodexNativeHookRemoteCredential(params) {
|
|
102
|
+
const credentialPath = codexNativeHookRemoteCredentialPath(params.config, params.relay.relayId, params.relay.generation);
|
|
103
|
+
const owner = Symbol("native-hook-credential");
|
|
104
|
+
let preparation;
|
|
105
|
+
let removal;
|
|
106
|
+
let disposed = false;
|
|
107
|
+
return {
|
|
108
|
+
path: credentialPath,
|
|
109
|
+
prepare() {
|
|
110
|
+
if (disposed) return Promise.reject(/* @__PURE__ */ new Error("Native hook relay credential is closed"));
|
|
111
|
+
preparation ??= projections.enqueue(credentialPath, async () => {
|
|
112
|
+
if (disposed) throw new Error("Native hook relay credential is closed");
|
|
113
|
+
params.assertCurrent();
|
|
114
|
+
const { token } = params.relay.enableRemoteCallback();
|
|
115
|
+
projectionOwners.set(credentialPath, owner);
|
|
116
|
+
const credential = {
|
|
117
|
+
url: `${params.config.url.replace(/\/$/, "")}/${encodeURIComponent(params.relay.relayId)}`,
|
|
118
|
+
token
|
|
119
|
+
};
|
|
120
|
+
try {
|
|
121
|
+
await params.client.request("fs/writeFile", {
|
|
122
|
+
path: credentialPath,
|
|
123
|
+
dataBase64: Buffer.from(JSON.stringify(credential)).toString("base64")
|
|
124
|
+
}, {
|
|
125
|
+
timeoutMs: params.timeoutMs,
|
|
126
|
+
signal: params.signal,
|
|
127
|
+
assertCurrent: params.assertCurrent
|
|
128
|
+
});
|
|
129
|
+
} catch {
|
|
130
|
+
throw new Error("Could not deliver the native hook relay credential to Codex");
|
|
131
|
+
}
|
|
132
|
+
params.assertCurrent();
|
|
133
|
+
if (disposed) throw new Error("Native hook relay credential closed during delivery");
|
|
134
|
+
});
|
|
135
|
+
return preparation;
|
|
136
|
+
},
|
|
137
|
+
dispose() {
|
|
138
|
+
disposed = true;
|
|
139
|
+
if (!preparation) return Promise.resolve();
|
|
140
|
+
removal ??= projections.enqueue(credentialPath, async () => {
|
|
141
|
+
if (projectionOwners.get(credentialPath) !== owner) return;
|
|
142
|
+
try {
|
|
143
|
+
await params.client.request("fs/remove", {
|
|
144
|
+
path: credentialPath,
|
|
145
|
+
force: true,
|
|
146
|
+
recursive: false
|
|
147
|
+
}, { timeoutMs: params.timeoutMs });
|
|
148
|
+
} catch {
|
|
149
|
+
throw new Error("Could not remove the retired native hook relay credential from Codex");
|
|
150
|
+
} finally {
|
|
151
|
+
projectionOwners.delete(credentialPath);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return removal;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region extensions/codex/src/app-server/native-hook-relay.ts
|
|
160
|
+
const CODEX_NATIVE_HOOK_RELAY_EVENTS = [
|
|
161
|
+
"pre_tool_use",
|
|
162
|
+
"post_tool_use",
|
|
163
|
+
"permission_request",
|
|
164
|
+
"before_agent_finalize"
|
|
165
|
+
];
|
|
166
|
+
const CODEX_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS = CODEX_NATIVE_HOOK_RELAY_EVENTS.filter((event) => event !== "permission_request");
|
|
167
|
+
const CODEX_NATIVE_HOOK_RELAY_MIN_TTL_MS = 18e5;
|
|
168
|
+
/** Extra relay lifetime after the expected turn budget, preventing late hook drops. */
|
|
169
|
+
const CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS = 3e5;
|
|
170
|
+
const CODEX_NATIVE_HOOK_RELAY_COMMAND_MIN_PARENT_MARGIN_MS = 250;
|
|
171
|
+
const CODEX_NATIVE_HOOK_RELAY_COMMAND_MAX_PARENT_MARGIN_MS = 1e3;
|
|
172
|
+
const CODEX_NATIVE_HOOK_RELAY_DEFAULT_TIMEOUT_SEC = 10;
|
|
173
|
+
const CODEX_NATIVE_HOOK_RELAY_UNREGISTER_GRACE_MS = 1e4;
|
|
174
|
+
const CODEX_NATIVE_HOOK_RELAY_UNREGISTER_EXTRA_GRACE_MS = 5e3;
|
|
175
|
+
const MAX_PENDING_DIRECT_CHILD_ADMISSIONS = 32;
|
|
176
|
+
const CODEX_NATIVE_SPAWN_HOOK_NAMES = ["spawn_agent", "Agent"];
|
|
177
|
+
const CODEX_HOOK_MATCHER_NAMES_BY_TOOL_ID = {
|
|
178
|
+
exec: [
|
|
179
|
+
"Bash",
|
|
180
|
+
"exec",
|
|
181
|
+
"exec_command"
|
|
182
|
+
],
|
|
183
|
+
apply_patch: [
|
|
184
|
+
"apply_patch",
|
|
185
|
+
"Write",
|
|
186
|
+
"Edit"
|
|
187
|
+
],
|
|
188
|
+
spawn_agent: CODEX_NATIVE_SPAWN_HOOK_NAMES
|
|
189
|
+
};
|
|
190
|
+
var CodexManagedHooksOnlyError = class extends Error {
|
|
191
|
+
constructor() {
|
|
192
|
+
super("Codex managed-only hooks disable the OpenClaw native hook relay; refusing unenforced execution");
|
|
193
|
+
this.name = "CodexManagedHooksOnlyError";
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
/** Enterprise managed-only policy silently drops the session-layer hooks that enforce OpenClaw. */
|
|
197
|
+
async function assertCodexNativeHookRelayAllowed(client, signal, timeoutMs) {
|
|
198
|
+
const response = await client.request("configRequirements/read", void 0, {
|
|
199
|
+
signal,
|
|
200
|
+
...timeoutMs === void 0 ? {} : { timeoutMs }
|
|
201
|
+
});
|
|
202
|
+
if (!isJsonObject(response) || !Object.hasOwn(response, "requirements")) throw new Error("Codex configRequirements/read returned an invalid hook policy response");
|
|
203
|
+
const requirements = response.requirements;
|
|
204
|
+
if (requirements === null) return;
|
|
205
|
+
if (!isJsonObject(requirements)) throw new Error("Codex configRequirements/read returned invalid hook policy requirements");
|
|
206
|
+
const managedOnly = requirements.allowManagedHooksOnly;
|
|
207
|
+
if (managedOnly !== void 0 && managedOnly !== null && typeof managedOnly !== "boolean") throw new Error("Codex configRequirements/read returned invalid managed-only hook policy");
|
|
208
|
+
if (managedOnly === true) throw new CodexManagedHooksOnlyError();
|
|
209
|
+
}
|
|
210
|
+
/** Defers relay unregister so late native hook subprocesses can still resolve. */
|
|
211
|
+
function scheduleCodexNativeHookRelayUnregister(params) {
|
|
212
|
+
const hookTimeoutMs = finiteSecondsToTimerSafeMilliseconds(normalizeHookTimeoutSec(params.hookTimeoutSec)) ?? 0;
|
|
213
|
+
nativeHookRelayUnregisterQueue.schedule(params.relay, Math.max(CODEX_NATIVE_HOOK_RELAY_UNREGISTER_GRACE_MS, addTimerTimeoutGraceMs(hookTimeoutMs, CODEX_NATIVE_HOOK_RELAY_UNREGISTER_EXTRA_GRACE_MS) ?? 0));
|
|
214
|
+
}
|
|
215
|
+
/** Records a native pre-tool failure that Codex does not project as a tool item. */
|
|
216
|
+
function emitCodexNativePreToolUseFailureDiagnostic(params) {
|
|
217
|
+
emitTrustedDiagnosticEvent({
|
|
218
|
+
type: "tool.execution.error",
|
|
219
|
+
...params.agentId ? { agentId: params.agentId } : {},
|
|
220
|
+
sessionId: params.sessionId,
|
|
221
|
+
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
|
|
222
|
+
runId: params.runId,
|
|
223
|
+
toolName: params.failure.toolName,
|
|
224
|
+
toolCallId: params.failure.toolCallId,
|
|
225
|
+
durationMs: params.failure.durationMs,
|
|
226
|
+
errorCategory: "before_tool_call",
|
|
227
|
+
terminalReason: params.terminalReason ?? (params.signal?.aborted ? resolveCodexToolAbortTerminalReason(params.signal) : params.failure.disposition),
|
|
228
|
+
...params.sourceTimestampMs !== void 0 ? { sourceTimestampMs: params.sourceTimestampMs } : {}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
function createCodexNativeHookRelay(params) {
|
|
232
|
+
if (params.options?.enabled === false) return;
|
|
233
|
+
const modelInputTools = params.nativeModelAdmission?.tools ?? ["multi_agent_v1send_input"];
|
|
234
|
+
const directChildClaims = /* @__PURE__ */ new Map();
|
|
235
|
+
const pendingDirectChildAdmissions = /* @__PURE__ */ new Map();
|
|
236
|
+
let foregroundClosed = false;
|
|
237
|
+
let successfulYieldRetentionAuthorized = false;
|
|
238
|
+
const assertClaim = (threadId, claim) => () => directChildClaims.get(threadId) === claim;
|
|
239
|
+
const rejectPendingAdmissions = (reason) => {
|
|
240
|
+
for (const pending of pendingDirectChildAdmissions.values()) pending.reject(new Error(reason));
|
|
241
|
+
pendingDirectChildAdmissions.clear();
|
|
242
|
+
};
|
|
243
|
+
let releaseProcessAdmission;
|
|
244
|
+
let processAdmissionDisposed = false;
|
|
245
|
+
let remoteCredential;
|
|
246
|
+
let remoteCleanup;
|
|
247
|
+
const relay = registerNativeHookRelayForBundledRuntime({
|
|
248
|
+
provider: "codex",
|
|
249
|
+
relayId: buildCodexNativeHookRelayId({
|
|
250
|
+
agentId: params.agentId,
|
|
251
|
+
sessionId: params.sessionId,
|
|
252
|
+
sessionKey: params.sessionKey
|
|
253
|
+
}),
|
|
254
|
+
...params.generation ? { generation: params.generation } : {},
|
|
255
|
+
...params.generationMismatchGraceMs ? { generationMismatchGraceMs: params.generationMismatchGraceMs } : {},
|
|
256
|
+
...params.agentId ? { agentId: params.agentId } : {},
|
|
257
|
+
sessionId: params.sessionId,
|
|
258
|
+
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
|
|
259
|
+
...params.config ? { config: params.config } : {},
|
|
260
|
+
autoApproveMcpTools: params.autoApproveMcpTools,
|
|
261
|
+
projectedMcpServers: params.projectedMcpServers,
|
|
262
|
+
runId: params.runId,
|
|
263
|
+
...params.channelId ? { channelId: params.channelId } : {},
|
|
264
|
+
...params.requester ? { requester: params.requester } : {},
|
|
265
|
+
...params.approvalContext ? { approvalContext: params.approvalContext } : {},
|
|
266
|
+
allowedEvents: params.events,
|
|
267
|
+
preToolUseLoopDetection: params.loopDetectionPreToolUseRelay,
|
|
268
|
+
ttlMs: resolveCodexNativeHookRelayTtlMs({
|
|
269
|
+
explicitTtlMs: params.options?.ttlMs,
|
|
270
|
+
attemptTimeoutMs: params.attemptTimeoutMs,
|
|
271
|
+
startupTimeoutMs: params.startupTimeoutMs,
|
|
272
|
+
turnStartTimeoutMs: params.turnStartTimeoutMs
|
|
273
|
+
}),
|
|
274
|
+
signal: params.signal,
|
|
275
|
+
runBeforeToolCall: params.hostCapabilities.runBeforeToolCall,
|
|
276
|
+
executionAdmission: params.nativeProcessAuthority || params.nativeModelAdmission ? {
|
|
277
|
+
toolNames: [...params.nativeProcessAuthority ? ["exec"] : [], ...params.nativeModelAdmission ? modelInputTools : []],
|
|
278
|
+
admit: async (invocation, assertAdmissionCurrent, preparation) => {
|
|
279
|
+
const payload = invocation.rawPayload;
|
|
280
|
+
const toolName = CODEX_NATIVE_SPAWN_HOOK_NAMES.includes(invocation.toolName ?? "") ? "spawn_agent" : invocation.toolName;
|
|
281
|
+
if (params.nativeModelAdmission && toolName && modelInputTools.includes(toolName)) {
|
|
282
|
+
const admission = params.nativeModelAdmission;
|
|
283
|
+
if (toolName.endsWith("spawn_agent")) return () => {
|
|
284
|
+
assertAdmissionCurrent();
|
|
285
|
+
if (!readCodexNativeChildThreadId(payload)) try {
|
|
286
|
+
params.hostCapabilities.assertNativeSubagentSpawnAllowed?.();
|
|
287
|
+
} catch (error) {
|
|
288
|
+
return `${toErrorObject(error, "Native spawn participant selection failed").message} Use sessions_spawn with the requester's requester_profile.id as user.`;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
const input = isJsonObject(payload) ? payload.tool_input : void 0;
|
|
292
|
+
const targetThreadId = isJsonObject(input) && typeof input.target === "string" ? input.target.trim() : void 0;
|
|
293
|
+
const threadId = readCodexNativeChildThreadId(payload) ?? admission.threadId();
|
|
294
|
+
if (!threadId || !targetThreadId || !invocation.turnId || !invocation.toolUseId) throw new Error("Codex native input requires exact sender, receiver, turn, and tool identities");
|
|
295
|
+
assertAdmissionCurrent();
|
|
296
|
+
const request = {
|
|
297
|
+
client: admission.client(),
|
|
298
|
+
threadId,
|
|
299
|
+
turnId: invocation.turnId,
|
|
300
|
+
itemId: invocation.toolUseId
|
|
301
|
+
};
|
|
302
|
+
await codexNativeSubagentMonitorRuntime.prepareModelInput({
|
|
303
|
+
...request,
|
|
304
|
+
target: targetThreadId,
|
|
305
|
+
readQualification: admission.readQualification,
|
|
306
|
+
signal: preparation.signal,
|
|
307
|
+
assertCurrent: preparation.assertCurrent
|
|
308
|
+
});
|
|
309
|
+
assertAdmissionCurrent();
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const rootThreadId = isJsonObject(payload) && typeof payload.session_id === "string" ? payload.session_id.trim() : void 0;
|
|
313
|
+
const childThreadId = readCodexNativeChildThreadId(payload);
|
|
314
|
+
const threadId = childThreadId ?? rootThreadId;
|
|
315
|
+
if (!threadId || !invocation.turnId || !invocation.toolUseId) throw new Error("Codex native process admission requires exact thread, turn, and tool identities");
|
|
316
|
+
params.nativeProcessAuthority.owner.admit(params.nativeProcessAuthority.client(), {
|
|
317
|
+
threadId,
|
|
318
|
+
turnId: invocation.turnId,
|
|
319
|
+
itemId: invocation.toolUseId
|
|
320
|
+
}, assertAdmissionCurrent, childThreadId ? rootThreadId : void 0);
|
|
321
|
+
}
|
|
322
|
+
} : void 0,
|
|
323
|
+
approvalHost: params.hostCapabilities,
|
|
324
|
+
assertActive: () => {
|
|
325
|
+
params.hostCapabilities.assertActive();
|
|
326
|
+
params.assertCurrent?.();
|
|
327
|
+
},
|
|
328
|
+
retention: {
|
|
329
|
+
readClaim: readCodexNativeChildThreadId,
|
|
330
|
+
shouldRetainAfterForegroundClose: () => successfulYieldRetentionAuthorized && directChildClaims.size > 0,
|
|
331
|
+
allowPreToolUse: (childThreadId) => directChildClaims.has(childThreadId),
|
|
332
|
+
awaitForegroundAdmission: (childThreadId, signal) => {
|
|
333
|
+
const existingClaim = directChildClaims.get(childThreadId);
|
|
334
|
+
if (existingClaim) return Promise.resolve(assertClaim(childThreadId, existingClaim));
|
|
335
|
+
if (foregroundClosed) return Promise.reject(/* @__PURE__ */ new Error("native hook relay foreground admission unavailable"));
|
|
336
|
+
let pending = pendingDirectChildAdmissions.get(childThreadId);
|
|
337
|
+
if (!pending) {
|
|
338
|
+
if (pendingDirectChildAdmissions.size >= MAX_PENDING_DIRECT_CHILD_ADMISSIONS) return Promise.reject(/* @__PURE__ */ new Error("native hook relay foreground admission capacity reached"));
|
|
339
|
+
pending = {
|
|
340
|
+
...createDeferred(),
|
|
341
|
+
waiters: 0
|
|
342
|
+
};
|
|
343
|
+
pendingDirectChildAdmissions.set(childThreadId, pending);
|
|
344
|
+
}
|
|
345
|
+
const admission = pending;
|
|
346
|
+
admission.waiters++;
|
|
347
|
+
let onAbort;
|
|
348
|
+
return new Promise((resolve, reject) => {
|
|
349
|
+
admission.promise.then(resolve, reject);
|
|
350
|
+
onAbort = () => reject(toErrorObject(signal?.reason, "native hook relay admission aborted"));
|
|
351
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
352
|
+
if (signal?.aborted) onAbort();
|
|
353
|
+
}).then((claim) => assertClaim(childThreadId, claim)).finally(() => {
|
|
354
|
+
if (onAbort) signal?.removeEventListener("abort", onAbort);
|
|
355
|
+
admission.waiters--;
|
|
356
|
+
if (admission.waiters === 0 && pendingDirectChildAdmissions.get(childThreadId) === admission) pendingDirectChildAdmissions.delete(childThreadId);
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
onDispose: () => {
|
|
360
|
+
foregroundClosed = true;
|
|
361
|
+
rejectPendingAdmissions("native hook relay registration closed");
|
|
362
|
+
processAdmissionDisposed = true;
|
|
363
|
+
releaseProcessAdmission?.();
|
|
364
|
+
if (remoteCredential) {
|
|
365
|
+
remoteCleanup = remoteCredential.dispose().catch((error) => params.remoteCallback?.onCleanupFailure(toErrorObject(error, "Native hook relay credential cleanup failed")));
|
|
366
|
+
nativeHookRelayUnregisterQueue.track(remoteCleanup);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
onPreToolUseFailure: params.onPreToolUseFailure,
|
|
371
|
+
command: {
|
|
372
|
+
nice: 10,
|
|
373
|
+
timeoutMs: params.options?.gatewayTimeoutMs
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
if (!processAdmissionDisposed) try {
|
|
377
|
+
releaseProcessAdmission = params.nativeProcessAuthority?.owner.retainAdmission();
|
|
378
|
+
} catch (error) {
|
|
379
|
+
relay.unregister();
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
382
|
+
if (params.remoteCallback) {
|
|
383
|
+
remoteCredential = createCodexNativeHookRemoteCredential({
|
|
384
|
+
...params.remoteCallback,
|
|
385
|
+
relay,
|
|
386
|
+
signal: params.signal,
|
|
387
|
+
assertCurrent: () => {
|
|
388
|
+
params.hostCapabilities.assertActive();
|
|
389
|
+
params.assertCurrent?.();
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
if (processAdmissionDisposed) remoteCredential.dispose();
|
|
393
|
+
}
|
|
394
|
+
return {
|
|
395
|
+
...relay,
|
|
396
|
+
unregister: () => {
|
|
397
|
+
foregroundClosed = true;
|
|
398
|
+
rejectPendingAdmissions("native hook relay foreground closed");
|
|
399
|
+
relay.unregister();
|
|
400
|
+
},
|
|
401
|
+
prepareInvocation: async () => {
|
|
402
|
+
await relay.prepareInvocation();
|
|
403
|
+
await remoteCredential?.prepare();
|
|
404
|
+
},
|
|
405
|
+
drain: async () => {
|
|
406
|
+
await relay.drain();
|
|
407
|
+
await remoteCleanup;
|
|
408
|
+
},
|
|
409
|
+
commandForEvent: (event, commandOptions) => relay.commandForEvent(event, {
|
|
410
|
+
...commandOptions,
|
|
411
|
+
...remoteCredential ? { remoteCredentialPath: remoteCredential.path } : {}
|
|
412
|
+
}),
|
|
413
|
+
authorizeRetentionAfterSuccessfulYield: () => {
|
|
414
|
+
successfulYieldRetentionAuthorized = true;
|
|
415
|
+
},
|
|
416
|
+
hasClaimedDirectChild: () => directChildClaims.size > 0,
|
|
417
|
+
rejectPendingDirectChild: (threadIdInput, reason) => {
|
|
418
|
+
const threadId = threadIdInput.trim();
|
|
419
|
+
const pending = threadId ? pendingDirectChildAdmissions.get(threadId) : void 0;
|
|
420
|
+
if (!pending) return;
|
|
421
|
+
pendingDirectChildAdmissions.delete(threadId);
|
|
422
|
+
pending.reject(new Error(reason));
|
|
423
|
+
},
|
|
424
|
+
claimDirectChild: (threadIdInput) => {
|
|
425
|
+
const threadId = threadIdInput.trim();
|
|
426
|
+
if (!threadId || directChildClaims.has(threadId)) return () => void 0;
|
|
427
|
+
const claim = Symbol(threadId);
|
|
428
|
+
directChildClaims.set(threadId, claim);
|
|
429
|
+
const pending = pendingDirectChildAdmissions.get(threadId);
|
|
430
|
+
pendingDirectChildAdmissions.delete(threadId);
|
|
431
|
+
pending?.resolve(claim);
|
|
432
|
+
return () => {
|
|
433
|
+
if (directChildClaims.get(threadId) !== claim) return;
|
|
434
|
+
directChildClaims.delete(threadId);
|
|
435
|
+
if (foregroundClosed && directChildClaims.size === 0) {
|
|
436
|
+
relay.unregister();
|
|
437
|
+
nativeHookRelayUnregisterQueue.track(relay.drain());
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function readCodexNativeChildThreadId(rawPayload) {
|
|
444
|
+
if (!isJsonObject(rawPayload) || typeof rawPayload.agent_id !== "string") return;
|
|
445
|
+
return rawPayload.agent_id.trim() || void 0;
|
|
446
|
+
}
|
|
447
|
+
function resolveCodexNativeHookRelayEvents(params) {
|
|
448
|
+
if (params.configuredEvents?.length) return params.configuredEvents;
|
|
449
|
+
return params.appServer.approvalPolicy === "never" ? CODEX_NATIVE_HOOK_RELAY_EVENTS : CODEX_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS;
|
|
450
|
+
}
|
|
451
|
+
function resolveCodexNativeHookRelayTtlMs(params) {
|
|
452
|
+
if (params.explicitTtlMs !== void 0) return params.explicitTtlMs;
|
|
453
|
+
const relayBudgetMs = params.attemptTimeoutMs + params.startupTimeoutMs + params.turnStartTimeoutMs + CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS;
|
|
454
|
+
return Math.max(CODEX_NATIVE_HOOK_RELAY_MIN_TTL_MS, Math.floor(relayBudgetMs));
|
|
455
|
+
}
|
|
456
|
+
function buildCodexNativeHookRelayId(params) {
|
|
457
|
+
const hash = createHash("sha256");
|
|
458
|
+
hash.update("openclaw:codex:native-hook-relay:v1");
|
|
459
|
+
hash.update("\0");
|
|
460
|
+
hash.update(params.agentId?.trim() || "");
|
|
461
|
+
hash.update("\0");
|
|
462
|
+
hash.update(params.sessionKey?.trim() || params.sessionId);
|
|
463
|
+
return `codex-${hash.digest("hex").slice(0, 40)}`;
|
|
464
|
+
}
|
|
465
|
+
const CODEX_HOOK_EVENTS = {
|
|
466
|
+
pre_tool_use: {
|
|
467
|
+
name: "PreToolUse",
|
|
468
|
+
keyLabel: "pre_tool_use"
|
|
469
|
+
},
|
|
470
|
+
post_tool_use: {
|
|
471
|
+
name: "PostToolUse",
|
|
472
|
+
keyLabel: "post_tool_use"
|
|
473
|
+
},
|
|
474
|
+
permission_request: {
|
|
475
|
+
name: "PermissionRequest",
|
|
476
|
+
keyLabel: "permission_request"
|
|
477
|
+
},
|
|
478
|
+
before_agent_finalize: {
|
|
479
|
+
name: "Stop",
|
|
480
|
+
keyLabel: "stop"
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
const CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS = ["/<session-flags>/config.toml", "<session-flags>/config.toml"];
|
|
484
|
+
function buildCodexNativeHookRelayConfig(params) {
|
|
485
|
+
const events = params.events?.length ? params.events : CODEX_NATIVE_HOOK_RELAY_EVENTS;
|
|
486
|
+
const selectedEvents = new Set(events);
|
|
487
|
+
const config = { "features.hooks": true };
|
|
488
|
+
const hookState = {};
|
|
489
|
+
for (const event of CODEX_NATIVE_HOOK_RELAY_EVENTS) {
|
|
490
|
+
const { name, keyLabel } = CODEX_HOOK_EVENTS[event];
|
|
491
|
+
const selected = selectedEvents.has(event);
|
|
492
|
+
const shouldRelay = params.relay.shouldRelayEvent(event);
|
|
493
|
+
if (!selected || !shouldRelay) {
|
|
494
|
+
if (selected || params.clearOmittedEvents) config[`hooks.${name}`] = [];
|
|
495
|
+
if (params.clearOmittedEvents) for (const sourcePath of CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS) hookState[`${sourcePath}:${keyLabel}:0:0`] = { enabled: false };
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
const timeout = normalizeHookTimeoutSec(params.hookTimeoutSec);
|
|
499
|
+
const command = params.relay.commandForEvent(event, {
|
|
500
|
+
timeoutMs: resolveCodexNativeHookRelayCommandTimeoutMs(timeout),
|
|
501
|
+
...params.remoteCredentialPath ? { remoteCredentialPath: params.remoteCredentialPath } : {}
|
|
502
|
+
});
|
|
503
|
+
const matcher = buildCodexNativeToolMatcher(params.relay.toolMatcherForEvent(event));
|
|
504
|
+
const group = {
|
|
505
|
+
...matcher ? { matcher } : {},
|
|
506
|
+
hooks: [{
|
|
507
|
+
type: "command",
|
|
508
|
+
command,
|
|
509
|
+
timeout,
|
|
510
|
+
async: false,
|
|
511
|
+
statusMessage: "OpenClaw native hook relay"
|
|
512
|
+
}]
|
|
513
|
+
};
|
|
514
|
+
config[`hooks.${name}`] = [group];
|
|
515
|
+
const state = {
|
|
516
|
+
enabled: true,
|
|
517
|
+
trusted_hash: `sha256:${fingerprintCodexPolicy({
|
|
518
|
+
event_name: keyLabel,
|
|
519
|
+
...group
|
|
520
|
+
})}`
|
|
521
|
+
};
|
|
522
|
+
for (const sourcePath of CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS) hookState[`${sourcePath}:${keyLabel}:0:0`] = state;
|
|
523
|
+
}
|
|
524
|
+
config["hooks.state"] = hookState;
|
|
525
|
+
return config;
|
|
526
|
+
}
|
|
527
|
+
function buildCodexNativeHookRelayDisabledConfig() {
|
|
528
|
+
return {
|
|
529
|
+
"features.hooks": false,
|
|
530
|
+
"hooks.PreToolUse": [],
|
|
531
|
+
"hooks.PostToolUse": [],
|
|
532
|
+
"hooks.PermissionRequest": [],
|
|
533
|
+
"hooks.Stop": []
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
function normalizeHookTimeoutSec(value) {
|
|
537
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.ceil(value) : CODEX_NATIVE_HOOK_RELAY_DEFAULT_TIMEOUT_SEC;
|
|
538
|
+
}
|
|
539
|
+
function resolveCodexNativeHookRelayCommandTimeoutMs(hookTimeoutSec) {
|
|
540
|
+
const parentTimeoutMs = finiteSecondsToTimerSafeMilliseconds(normalizeHookTimeoutSec(hookTimeoutSec)) ?? 5e3;
|
|
541
|
+
const parentMarginMs = Math.min(CODEX_NATIVE_HOOK_RELAY_COMMAND_MAX_PARENT_MARGIN_MS, Math.max(CODEX_NATIVE_HOOK_RELAY_COMMAND_MIN_PARENT_MARGIN_MS, Math.floor(parentTimeoutMs / 5)));
|
|
542
|
+
return Math.max(1, parentTimeoutMs - parentMarginMs);
|
|
543
|
+
}
|
|
544
|
+
function buildCodexNativeToolMatcher(toolNames) {
|
|
545
|
+
if (toolNames === void 0) return;
|
|
546
|
+
if (toolNames.length === 0) throw new TypeError("Codex native hook matcher requires at least one tool name");
|
|
547
|
+
const nativeNames = /* @__PURE__ */ new Set();
|
|
548
|
+
let hasCustomToolName = false;
|
|
549
|
+
for (const toolName of toolNames) {
|
|
550
|
+
const canonicalToolName = toolName.trim();
|
|
551
|
+
if (!canonicalToolName || canonicalToolName === "*") throw new TypeError("Codex native hook matcher requires canonical OpenClaw tool ids");
|
|
552
|
+
const nativeAliases = CODEX_HOOK_MATCHER_NAMES_BY_TOOL_ID[canonicalToolName];
|
|
553
|
+
if (!nativeAliases) hasCustomToolName = true;
|
|
554
|
+
for (const nativeName of nativeAliases ?? [canonicalToolName]) nativeNames.add(nativeName);
|
|
555
|
+
}
|
|
556
|
+
const sortedNames = Array.from(nativeNames).toSorted();
|
|
557
|
+
if (!hasCustomToolName && sortedNames.every((toolName) => /^[A-Za-z0-9_]+$/.test(toolName))) return sortedNames.join("|");
|
|
558
|
+
return `(?i)^(?:${sortedNames.map(escapeRegExp).join("|")})$`;
|
|
559
|
+
}
|
|
560
|
+
//#endregion
|
|
561
|
+
export { createGatewayProcessProjection as _, buildCodexNativeHookRelayDisabledConfig as a, isCodexDynamicToolExcluded as b, emitCodexNativePreToolUseFailureDiagnostic as c, scheduleCodexNativeHookRelayUnregister as d, codexNativeHookRemoteCredentialPath as f, createGatewayExecProjection as g, CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME as h, buildCodexNativeHookRelayConfig as i, resolveCodexNativeHookRelayEvents as l, CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME as m, CodexManagedHooksOnlyError as n, buildCodexNativeHookRelayId as o, CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME as p, assertCodexNativeHookRelayAllowed as r, createCodexNativeHookRelay as s, CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS as t, resolveCodexNativeHookRelayTtlMs as u, createNodeExecAliasDynamicTool as v, placeDisabledNativeShellToolsInDirectNamespace as x, createSandboxShellProjection as y };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { U as protectCodexAppServerLiveThread, _ as retainSharedCodexAppServerClientIfCurrent, n as captureCodexAppServerClientLifetime } from "./shared-client-
|
|
2
|
-
import {
|
|
3
|
-
import { n as getCodexAppServerTurnRouter } from "./turn-router-
|
|
4
|
-
import { a as requestPluginApprovalOutcome } from "./plugin-approval-roundtrip-
|
|
5
|
-
import { i as readCodexMcpToolUiVisibility, n as projectCodexMcpToolMetadata, r as readCodexMcpToolConnectorId, t as projectCodexMcpServerMetadata } from "./mcp-tool-metadata-
|
|
6
|
-
import { t as __exportAll } from "./session-binding-sidecars-
|
|
1
|
+
import { U as protectCodexAppServerLiveThread, _ as retainSharedCodexAppServerClientIfCurrent, n as captureCodexAppServerClientLifetime } from "./shared-client-ByIwuAC-.mjs";
|
|
2
|
+
import { F as getCodexAppServerClientInstanceId } from "./client-y7nO6X9c.mjs";
|
|
3
|
+
import { n as getCodexAppServerTurnRouter } from "./turn-router-DKDAziUW.mjs";
|
|
4
|
+
import { a as requestPluginApprovalOutcome } from "./plugin-approval-roundtrip-BSV-51ig.mjs";
|
|
5
|
+
import { i as readCodexMcpToolUiVisibility, n as projectCodexMcpToolMetadata, r as readCodexMcpToolConnectorId, t as projectCodexMcpServerMetadata } from "./mcp-tool-metadata-DW41snf3.mjs";
|
|
6
|
+
import { t as __exportAll } from "./session-binding-sidecars-DD-enC8w.mjs";
|
|
7
7
|
import { asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { loadAgentHarnessMcpConfig, prepareHarnessNativeMcpAppPreview } from "openclaw/plugin-sdk/agent-harness-runtime";
|