@openclaw/codex 2026.9.1-beta.1 → 2026.9.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/api.js +5 -6
- package/dist/{attempt-client-cleanup-bfsmcQ6m.js → attempt-client-cleanup-DYHcRQAa.js} +31 -45
- package/dist/attempt-context-DmQUNWwT.js +634 -0
- package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
- package/dist/{binding-connection-BMvPX73o.js → binding-connection-E6uDsPlx.js} +2 -2
- package/dist/{bounded-turn-B7iBUcuP.js → bounded-turn-wzJrwKKe.js} +15 -20
- package/dist/{capabilities-BRMh0aIq.js → capabilities-dIjNVCYH.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-DEsIufkt.js → command-formatters-CLHhEB1Q.js} +5 -4
- package/dist/{command-handlers-D_-1_qRp.js → command-handlers-CTGb2csu.js} +124 -101
- package/dist/{compact-BglNFZrQ.js → compact-_t0HQrUS.js} +38 -29
- package/dist/{config-giW8X0QA.js → config-BhmfC1s6.js} +294 -282
- package/dist/{context-compaction-activity-BOeJf7yo.js → context-compaction-activity-CMla5FPJ.js} +4 -1
- package/dist/{conversation-binding-data-CW2GuupV.js → conversation-binding-data-BiodpIzq.js} +2 -1
- package/dist/doctor-contract-api.js +143 -12
- package/dist/{dynamic-tools-Dnlfa--w.js → dynamic-tools-BU9tmlYm.js} +599 -655
- package/dist/{effective-mcp-catalog-CTeGrnfO.js → effective-mcp-catalog-DzYBW4h1.js} +2 -2
- package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-DHRFXKbS.js} +4 -4
- package/dist/{event-projector-usage-Bk1I90Bg.js → event-projector-usage-C5mcrGjp.js} +15 -148
- package/dist/{harness-Csz0F-DK.js → harness-DXVZ5II5.js} +42 -52
- package/dist/harness.js +1 -1
- package/dist/index.js +458 -404
- package/dist/{isolated-completion-Cv6FqygM.js → isolated-completion-kg9kv4iH.js} +4 -4
- package/dist/launch-args-RXQwn8zV.js +90 -0
- package/dist/{managed-binary-DFYK4DWq.js → managed-binary-4-Vjz5GH.js} +14 -9
- package/dist/media-understanding-provider.js +1 -1
- package/dist/model-catalog-CUM68Hkl.js +101 -0
- package/dist/{models-TS3HBU-q.js → models-sYnEc0gd.js} +25 -28
- package/dist/{native-subagent-monitor-4Mfq2HDs.js → native-subagent-monitor-CnH147jH.js} +55 -115
- package/dist/{node-exec-server.runtime-BpWqJO1V.js → node-exec-server.runtime-CstNHCmC.js} +9 -6
- package/dist/{plugin-approval-roundtrip-bUm777tR.js → plugin-approval-roundtrip-CNe-Xrjx.js} +30 -3
- package/dist/{plugin-marketplace-discovery-B9DvaAG-.js → plugin-marketplace-discovery-CfFlKqDl.js} +15 -14
- package/dist/{plugin-metadata-cache-CTCT3w5L.js → plugin-metadata-cache-BFrPhb2c.js} +6 -6
- package/dist/provider-capabilities-DW5p4k9w.js +101 -0
- package/dist/{rate-limits-C5_D8Gmb.js → rate-limits-CawQJfUS.js} +3 -2
- package/dist/{sandbox-guard-kuWTn9C5.js → request-DYAI5FQE.js} +195 -2
- package/dist/{run-attempt-DYc0QCBF.js → run-attempt-D1hJO4fX.js} +828 -2100
- package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-C3jVimFn.js} +21 -14
- package/dist/{session-binding-Bcynfd-_.js → session-binding-BHuTCRZQ.js} +198 -127
- package/dist/{session-catalog-DaLKVtpH.js → session-catalog-yyvTWFOw.js} +564 -408
- package/dist/{session-cli-DMc4oS2w.js → session-cli-CmFEXMAM.js} +1 -1
- package/dist/session-history-C5J1AKzG.js +87 -0
- package/dist/session-initialization-BeWzjGiR.js +74 -0
- package/dist/{session-permission-policy-BrNH1bjy.js → session-permission-policy-DeWVTCMj.js} +2 -2
- package/dist/session-retirement-BujDjXVF.js +97 -0
- package/dist/{session-upstream-marker-BIkusb95.js → session-upstream-marker-C351-5Qw.js} +19 -4
- package/dist/settled-turn-context-D3SNWtUn.js +268 -0
- package/dist/settled-turn-finalizer-BVJx4yoc.js +104 -0
- package/dist/{shared-client-DKz23hHY.js → shared-client-DxcfF9KX.js} +3480 -679
- package/dist/{side-question-DjA_jsNe.js → side-question-BTZAII4l.js} +108 -70
- package/dist/{thread-lifecycle-L7oEkTlq.js → thread-lifecycle-DAcEJ_Om.js} +2188 -1915
- package/dist/{thread-ownership-DZeuKH1j.js → thread-ownership-zGokd8i1.js} +25 -14
- package/dist/thread-policy-g4KbJPzp.js +54 -0
- package/dist/{plugin-app-cache-key-C1CAdfcP.js → thread-resume-C7pyVKeW.js} +59 -7
- package/dist/{transcript-mirror-DsCMWBca.js → transcript-mirror-DTUxFWa_.js} +79 -17
- package/dist/transport-stdio-CyPldczm.js +726 -0
- package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
- package/dist/upstream-session-fork-CYlBIGVt.js +966 -0
- package/dist/{usage-ROIaW3wo.js → usage-Bj-rrzkR.js} +3 -3
- package/dist/{web-search-provider.runtime-ClaNPV7N.js → web-search-provider.runtime-D2FWSK4w.js} +3 -3
- package/openclaw.plugin.json +1 -30
- package/package.json +6 -6
- package/dist/command-rpc-CCeCkf_v.js +0 -90
- package/dist/incognito-session-ET_ufDH-.js +0 -2
- package/dist/model-catalog-i9rNBthX.js +0 -48
- package/dist/protocol-validators-VeJxxJ0U.js +0 -2421
- package/dist/request-DXXGHko0.js +0 -157
- package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
- package/dist/session-retirement-CcNC3YSY.js +0 -36
- package/dist/settled-turn-finalizer-Dc3ApjU4.js +0 -328
- package/dist/thread-resume-BE9qNEW0.js +0 -30
- package/dist/transport-stdio-DhoGy33Z.js +0 -99
- package/dist/upstream-session-fork-DlaHxSLC.js +0 -326
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { t as createStdioTransport } from "./transport-stdio-DhoGy33Z.js";
|
|
1
|
+
import { n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-4-Vjz5GH.js";
|
|
2
|
+
import { i as closeCodexAppServerTransportAndWait, t as createStdioTransport } from "./transport-stdio-CyPldczm.js";
|
|
4
3
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
4
|
import { mkdir } from "node:fs/promises";
|
|
6
5
|
import path from "node:path";
|
|
@@ -9,7 +8,7 @@ import { killProcessTree } from "openclaw/plugin-sdk/process-runtime";
|
|
|
9
8
|
import { once } from "node:events";
|
|
10
9
|
import { sanitizeEnvVars } from "openclaw/plugin-sdk/sandbox";
|
|
11
10
|
//#region extensions/codex/src/node-exec-server.runtime.ts
|
|
12
|
-
const MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES =
|
|
11
|
+
const MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES = 67108864;
|
|
13
12
|
const CODEX_EXEC_SERVER_TERMINATION_GRACE_MS = 1e3;
|
|
14
13
|
const CODEX_EXEC_SERVER_REAP_TIMEOUT_MS = 5e3;
|
|
15
14
|
const NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT = /^(?:SYSTEMROOT|WINDIR|COMSPEC|PATHEXT|TEMP|TMP|TMPDIR)$/iu;
|
|
@@ -125,7 +124,8 @@ async function runCodexNodeExecServer(params) {
|
|
|
125
124
|
customAllowedPatterns: [NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT]
|
|
126
125
|
}).allowed;
|
|
127
126
|
if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
|
|
128
|
-
|
|
127
|
+
params.assertExecAuthorized();
|
|
128
|
+
const child = await createStdioTransport({
|
|
129
129
|
transport: "stdio",
|
|
130
130
|
command: native,
|
|
131
131
|
commandSource: "resolved-managed",
|
|
@@ -138,7 +138,10 @@ async function runCodexNodeExecServer(params) {
|
|
|
138
138
|
...process.platform === "win32" ? { USERPROFILE: dir } : {}
|
|
139
139
|
},
|
|
140
140
|
clearEnv: ["NODE_OPTIONS"]
|
|
141
|
-
}, baseEnv)
|
|
141
|
+
}, baseEnv, () => {
|
|
142
|
+
if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
|
|
143
|
+
params.assertExecAuthorized();
|
|
144
|
+
});
|
|
142
145
|
child.stdin.on("error", (error) => {
|
|
143
146
|
rejectDisconnected(error);
|
|
144
147
|
});
|
package/dist/{plugin-approval-roundtrip-bUm777tR.js → plugin-approval-roundtrip-CNe-Xrjx.js}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { N as resolveCodexGatewayTimeoutWithGraceMs } from "./shared-client-DxcfF9KX.js";
|
|
2
2
|
import { isApprovalNotFoundError, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
|
|
3
3
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
4
4
|
//#region extensions/codex/src/app-server/plugin-approval-roundtrip.ts
|
|
5
5
|
const DEFAULT_CODEX_APPROVAL_TIMEOUT_MS = 12e4;
|
|
6
6
|
const MAX_PLUGIN_APPROVAL_TITLE_LENGTH = 80;
|
|
7
|
-
const MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH =
|
|
7
|
+
const MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH = 512;
|
|
8
8
|
const ANSI_OSC_SEQUENCE_RE = new RegExp(String.raw`(?:\u001b]|\u009d)[^\u001b\u009c\u0007]*(?:\u0007|\u001b\\|\u009c)`, "g");
|
|
9
9
|
const ANSI_CONTROL_SEQUENCE_RE = new RegExp(String.raw`(?:\u001b\[[0-?]*[ -/]*[@-~]|\u009b[0-?]*[ -/]*[@-~]|\u001b[@-Z\\-_])`, "g");
|
|
10
10
|
const CONTROL_CHARACTER_RE = new RegExp(String.raw`[\u0000-\u001f\u007f-\u009f]+`, "g");
|
|
@@ -23,11 +23,16 @@ function codexApprovalTimeoutText(kind) {
|
|
|
23
23
|
async function requestPluginApproval(params) {
|
|
24
24
|
const timeoutMs = DEFAULT_CODEX_APPROVAL_TIMEOUT_MS;
|
|
25
25
|
return params.hostCapabilities.requestApproval({
|
|
26
|
+
signal: params.signal,
|
|
26
27
|
title: truncateCodexApprovalDisplayText(params.title, MAX_PLUGIN_APPROVAL_TITLE_LENGTH),
|
|
27
28
|
description: truncateCodexApprovalDisplayText(params.description, MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH),
|
|
28
29
|
severity: params.severity,
|
|
29
30
|
toolName: params.toolName,
|
|
30
31
|
toolCallId: params.toolCallId,
|
|
32
|
+
...params.mcpTool ? {
|
|
33
|
+
mcpTool: params.mcpTool,
|
|
34
|
+
isMcpToolApprovalActive: params.isMcpToolApprovalActive
|
|
35
|
+
} : {},
|
|
31
36
|
timeoutMs,
|
|
32
37
|
transportTimeoutMs: resolveCodexGatewayTimeoutWithGraceMs(timeoutMs),
|
|
33
38
|
...params.allowedDecisions ? { allowedDecisions: params.allowedDecisions } : {}
|
|
@@ -81,6 +86,28 @@ function mapExecDecisionToOutcome(decision) {
|
|
|
81
86
|
default: return "unavailable";
|
|
82
87
|
}
|
|
83
88
|
}
|
|
89
|
+
/** Runs one complete host approval request and maps transport failures to a closed outcome. */
|
|
90
|
+
async function requestPluginApprovalOutcome(params) {
|
|
91
|
+
try {
|
|
92
|
+
const requestResult = await requestPluginApproval({
|
|
93
|
+
...params,
|
|
94
|
+
severity: "warning"
|
|
95
|
+
});
|
|
96
|
+
const approvalId = requestResult?.id;
|
|
97
|
+
if (!approvalId) return "unavailable";
|
|
98
|
+
const approvalResult = approvalRequestExplicitlyUnavailable(requestResult) ? void 0 : await waitForPluginApprovalDecision({
|
|
99
|
+
hostCapabilities: params.hostCapabilities,
|
|
100
|
+
approvalId,
|
|
101
|
+
signal: params.signal
|
|
102
|
+
});
|
|
103
|
+
if (params.signal?.aborted) return "cancelled";
|
|
104
|
+
if (approvalResult?.terminalReason === "timeout") return "timed-out";
|
|
105
|
+
const decision = approvalResult?.decision;
|
|
106
|
+
return mapExecDecisionToOutcome(decision === "allow-always" && params.allowedDecisions?.includes("allow-always") === false ? "allow-once" : decision);
|
|
107
|
+
} catch {
|
|
108
|
+
return params.signal?.aborted ? "cancelled" : "denied";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
84
111
|
function truncateCodexApprovalDisplayText(value, maxLength) {
|
|
85
112
|
return value.length <= maxLength ? value : `${truncateUtf16Safe(value, maxLength - 3)}...`;
|
|
86
113
|
}
|
|
@@ -92,4 +119,4 @@ function sanitizeCodexApprovalVisibleText(value, options = {}) {
|
|
|
92
119
|
return (options.stripDanglingTerminalSequence ? stripDanglingCodexApprovalTerminalSequence(terminalSafe) : terminalSafe).replace(INVISIBLE_FORMATTING_CONTROL_RE, " ").replace(CONTROL_CHARACTER_RE, " ").replace(/\s+/g, " ").trim();
|
|
93
120
|
}
|
|
94
121
|
//#endregion
|
|
95
|
-
export {
|
|
122
|
+
export { requestPluginApprovalOutcome as a, truncateCodexApprovalDisplayText as c, requestPluginApproval as i, waitForPluginApprovalDecision as l, codexApprovalTimeoutText as n, sanitizeCodexApprovalVisibleText as o, mapExecDecisionToOutcome as r, stripDanglingCodexApprovalTerminalSequence as s, approvalRequestExplicitlyUnavailable as t };
|
package/dist/{plugin-marketplace-discovery-B9DvaAG-.js → plugin-marketplace-discovery-CfFlKqDl.js}
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { o as isCodexAppServerNativeAuthProfile, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-
|
|
1
|
+
import { c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-DxcfF9KX.js";
|
|
2
|
+
import { A as isCodexFastServiceTier } from "./config-BhmfC1s6.js";
|
|
3
|
+
import { o as isCodexAppServerNativeAuthProfile, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-BHuTCRZQ.js";
|
|
4
|
+
import { E as resolveCodexAppServerRequestModelSelection, O as resolveCodexBindingModelProviderFallback } from "./thread-lifecycle-DAcEJ_Om.js";
|
|
5
|
+
import { a as formatCodexDisplayText } from "./command-formatters-CLHhEB1Q.js";
|
|
6
|
+
import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-E6uDsPlx.js";
|
|
7
7
|
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
8
8
|
import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
|
9
9
|
import { getSessionEntry, patchSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
@@ -127,15 +127,16 @@ async function setCodexConversationModel(params) {
|
|
|
127
127
|
const lookup = buildBindingLookup(params);
|
|
128
128
|
const binding = await requireThreadBinding(params.bindingStore, params.identity);
|
|
129
129
|
if (binding.connectionScope === "supervision") throw new ModelSelectionLockedError();
|
|
130
|
+
const modelProvider = resolveConversationControlModelProvider({
|
|
131
|
+
authProfileId: binding.authProfileId,
|
|
132
|
+
bindingModel: binding.model,
|
|
133
|
+
bindingModelProvider: binding.modelProvider,
|
|
134
|
+
currentModel: model,
|
|
135
|
+
...lookup
|
|
136
|
+
});
|
|
130
137
|
const modelSelection = resolveCodexAppServerRequestModelSelection({
|
|
131
138
|
model,
|
|
132
|
-
modelProvider
|
|
133
|
-
authProfileId: binding.authProfileId,
|
|
134
|
-
bindingModel: binding.model,
|
|
135
|
-
bindingModelProvider: binding.modelProvider,
|
|
136
|
-
currentModel: model,
|
|
137
|
-
...lookup
|
|
138
|
-
}),
|
|
139
|
+
modelProvider,
|
|
139
140
|
authProfileId: binding.authProfileId,
|
|
140
141
|
...lookup
|
|
141
142
|
});
|
|
@@ -214,7 +215,7 @@ async function setCodexConversationPermissions(params) {
|
|
|
214
215
|
return entry;
|
|
215
216
|
}
|
|
216
217
|
})) throw new Error("Codex session changed while applying the permission mode.");
|
|
217
|
-
return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "
|
|
218
|
+
return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "guarded"}.`;
|
|
218
219
|
}
|
|
219
220
|
function parseCodexFastModeArg(arg) {
|
|
220
221
|
const normalized = arg?.trim().toLowerCase();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { B as isCodexAppServerIndeterminateRequestCancellationError, D as acquireCodexNativeConfigFence, Gt as resolveCodexManagedBundledMarketplacePath, Kt as assertNotSymlink, Lt as reconcileCodexComputerUseStartArtifacts, S as waitForCodexAppServerClientDesktopGenerationDrain, V as isCodexAppServerIndeterminateTransportError, c as getLeasedSharedCodexAppServerClient, d as readCodexAppServerClientDesktopGeneration, g as resolveCodexNativeConfigFenceKey, h as releaseLeasedSharedCodexAppServerClient, p as readCodexAppServerClientProcessIdentity, t as assertCodexAppServerClientStartSelectionCurrent, u as isCodexAppServerStartSelectionChangedError, z as isCodexAppServerConnectionClosedError } from "./shared-client-DxcfF9KX.js";
|
|
2
|
+
import { F as resolveCodexAppServerHomeDir, i as resolveCodexAppServerRuntimeOptions, o as resolveCodexComputerUseConfig } from "./config-BhmfC1s6.js";
|
|
3
|
+
import { c as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, t as isManagedCodexDesktopCommand, u as resolveMacOSDesktopCodexBundledMarketplaceCandidates } from "./managed-binary-4-Vjz5GH.js";
|
|
4
|
+
import { i as requestCodexAppServerJson } from "./request-DYAI5FQE.js";
|
|
5
|
+
import { n as describeControlFailure } from "./capabilities-dIjNVCYH.js";
|
|
6
6
|
import fs from "node:fs/promises";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { existsSync } from "node:fs";
|
|
@@ -721,7 +721,7 @@ function resolveComputerUseConfig(params) {
|
|
|
721
721
|
}
|
|
722
722
|
//#endregion
|
|
723
723
|
//#region extensions/codex/src/app-server/plugin-metadata-cache.ts
|
|
724
|
-
const CODEX_PLUGIN_METADATA_CACHE_TTL_MS =
|
|
724
|
+
const CODEX_PLUGIN_METADATA_CACHE_TTL_MS = 36e5;
|
|
725
725
|
/** Process-local plugin metadata cache with coalesced loads per query. */
|
|
726
726
|
var CodexPluginMetadataCache = class {
|
|
727
727
|
constructor(nowMs = Date.now) {
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-DxcfF9KX.js";
|
|
2
|
+
import { ut as normalizeCodexDynamicToolName } from "./thread-lifecycle-DAcEJ_Om.js";
|
|
3
|
+
import { pinExecToolTarget } from "openclaw/plugin-sdk/codex-mcp-projection";
|
|
4
|
+
import { loadNodeExecAvailability } from "openclaw/plugin-sdk/node-selection-runtime";
|
|
5
|
+
//#region extensions/codex/src/app-server/shell-dynamic-tools.ts
|
|
6
|
+
const CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME = "node_exec";
|
|
7
|
+
const CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME = "gateway_exec";
|
|
8
|
+
const CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME = "gateway_process";
|
|
9
|
+
const PROCESS_FOLLOWUP_TEXT = "Use process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up.";
|
|
10
|
+
/** Returns true when plugin config explicitly removes any named dynamic tool. */
|
|
11
|
+
function isCodexDynamicToolExcluded(config, names) {
|
|
12
|
+
const normalizedNames = new Set(names.map((name) => normalizeCodexDynamicToolName(name)));
|
|
13
|
+
return (config.codexDynamicToolsExclude ?? []).some((name) => normalizedNames.has(normalizeCodexDynamicToolName(name)));
|
|
14
|
+
}
|
|
15
|
+
async function createNodeExecAliasDynamicTool(execTool, node, discoverySignal, availabilityRef) {
|
|
16
|
+
const pinnedNode = node?.trim();
|
|
17
|
+
const availability = await (availabilityRef ? availabilityRef.current ??= loadNodeExecAvailability(discoverySignal) : loadNodeExecAvailability(discoverySignal));
|
|
18
|
+
discoverySignal?.throwIfAborted();
|
|
19
|
+
if (!availability.isAvailable(pinnedNode)) return;
|
|
20
|
+
const pinnedTool = pinExecToolTarget(execTool, {
|
|
21
|
+
host: "node",
|
|
22
|
+
...pinnedNode ? { node: pinnedNode } : {}
|
|
23
|
+
});
|
|
24
|
+
const execute = async (toolCallId, args, signal, onUpdate) => {
|
|
25
|
+
const result = await pinnedTool.execute(toolCallId, args, signal, onUpdate);
|
|
26
|
+
return {
|
|
27
|
+
...result,
|
|
28
|
+
content: result.content.map((item) => item.type === "text" ? Object.assign({}, item, { text: item.text.replace(PROCESS_FOLLOWUP_TEXT, "Remote-node background follow-up is unavailable. Wait for the command to complete.") }) : item)
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
...pinnedTool,
|
|
33
|
+
name: CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME,
|
|
34
|
+
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.",
|
|
35
|
+
execute
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function createGatewayExecProjection(createProjection, execTool, params) {
|
|
39
|
+
return createProjection(execTool, {
|
|
40
|
+
kind: "exec",
|
|
41
|
+
name: CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME,
|
|
42
|
+
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.",
|
|
43
|
+
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.",
|
|
44
|
+
...params.ask ? { ask: params.ask } : {}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function createGatewayProcessProjection(createProjection, processTool) {
|
|
48
|
+
return createProjection(processTool, {
|
|
49
|
+
kind: "process",
|
|
50
|
+
name: CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME,
|
|
51
|
+
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."
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region extensions/codex/src/app-server/provider-capabilities.ts
|
|
56
|
+
function resolveOverriddenProviderWebSearchSupport(modelProviderOverride) {
|
|
57
|
+
const provider = modelProviderOverride?.trim().toLowerCase();
|
|
58
|
+
if (!provider) return;
|
|
59
|
+
return provider === "openai" ? "supported" : "unsupported";
|
|
60
|
+
}
|
|
61
|
+
async function readConfiguredProviderWebSearchSupport(params) {
|
|
62
|
+
return (await params.client.request("modelProvider/capabilities/read", {}, {
|
|
63
|
+
timeoutMs: params.timeoutMs,
|
|
64
|
+
signal: params.signal
|
|
65
|
+
})).webSearch ? "supported" : "unsupported";
|
|
66
|
+
}
|
|
67
|
+
async function resolveCodexProviderWebSearchSupportForClient(params) {
|
|
68
|
+
const overrideSupport = resolveOverriddenProviderWebSearchSupport(params.modelProviderOverride);
|
|
69
|
+
if (overrideSupport) return overrideSupport;
|
|
70
|
+
try {
|
|
71
|
+
return await readConfiguredProviderWebSearchSupport(params);
|
|
72
|
+
} catch {
|
|
73
|
+
return "unknown";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function resolveCodexProviderWebSearchSupport(params) {
|
|
77
|
+
const overrideSupport = resolveOverriddenProviderWebSearchSupport(params.modelProviderOverride);
|
|
78
|
+
if (overrideSupport) return overrideSupport;
|
|
79
|
+
let client;
|
|
80
|
+
try {
|
|
81
|
+
client = await params.clientFactory({
|
|
82
|
+
startOptions: params.appServer.start,
|
|
83
|
+
...params.preparedAuth ? { preparedAuth: params.preparedAuth } : { authProfileId: params.authProfileId },
|
|
84
|
+
agentDir: params.agentDir,
|
|
85
|
+
config: params.config,
|
|
86
|
+
timeoutMs: params.appServer.requestTimeoutMs
|
|
87
|
+
});
|
|
88
|
+
return await resolveCodexProviderWebSearchSupportForClient({
|
|
89
|
+
client,
|
|
90
|
+
timeoutMs: params.appServer.requestTimeoutMs,
|
|
91
|
+
modelProviderOverride: params.modelProviderOverride,
|
|
92
|
+
signal: params.signal
|
|
93
|
+
});
|
|
94
|
+
} catch {
|
|
95
|
+
return "unknown";
|
|
96
|
+
} finally {
|
|
97
|
+
if (client) releaseLeasedSharedCodexAppServerClient(client);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME as a, createNodeExecAliasDynamicTool as c, CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME as i, isCodexDynamicToolExcluded as l, resolveCodexProviderWebSearchSupportForClient as n, createGatewayExecProjection as o, CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME as r, createGatewayProcessProjection as s, resolveCodexProviderWebSearchSupport as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $t as isJsonObject } from "./shared-client-DxcfF9KX.js";
|
|
2
2
|
import { asBoolean, asFiniteNumber, normalizeOptionalString, parseStrictFiniteNumber } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
3
|
import { MAX_DATE_TIMESTAMP_MS, resolveExpiresAtMsFromEpochSeconds } from "openclaw/plugin-sdk/number-runtime";
|
|
4
4
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
@@ -186,8 +186,9 @@ function isRateLimitSnapshot(value) {
|
|
|
186
186
|
function readRateLimitWindow(snapshot, key) {
|
|
187
187
|
const window = snapshot[key];
|
|
188
188
|
if (!isJsonObject(window)) return;
|
|
189
|
+
const resetsAt = asFiniteNumber(window.resetsAt) ?? asFiniteNumber(window.resets_at);
|
|
189
190
|
return {
|
|
190
|
-
resetsAtMs: resolveExpiresAtMsFromEpochSeconds(
|
|
191
|
+
resetsAtMs: resolveExpiresAtMsFromEpochSeconds(resetsAt, { maxMs: MAX_DATE_TIMESTAMP_MS }) ?? 0,
|
|
191
192
|
...readOptionalNumberField(window, "usedPercent", "used_percent"),
|
|
192
193
|
...readOptionalNumberField(window, "windowDurationMins", "window_duration_mins", "windowMinutes", "window_minutes")
|
|
193
194
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
+
import { Nt as withTimeout, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, s as createIsolatedCodexAppServerClient, u as isCodexAppServerStartSelectionChangedError, y as retireSharedCodexAppServerClientIfCurrent } from "./shared-client-DxcfF9KX.js";
|
|
3
|
+
import { w as isCodexRemoteExecPlacementSandbox } from "./config-BhmfC1s6.js";
|
|
2
4
|
import { resolveAgentConfig, tryResolveDefaultAgentId } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
3
5
|
import { getSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
|
4
6
|
import { normalizeAgentId, parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
|
@@ -279,4 +281,195 @@ function resolveCodexNativeNodeExecBlock(params) {
|
|
|
279
281
|
});
|
|
280
282
|
}
|
|
281
283
|
//#endregion
|
|
282
|
-
|
|
284
|
+
//#region extensions/codex/src/app-server/request.ts
|
|
285
|
+
var request_exports = /* @__PURE__ */ __exportAll({
|
|
286
|
+
CodexAppServerScopedRequestRejectedError: () => CodexAppServerScopedRequestRejectedError,
|
|
287
|
+
readCodexAppServerUsage: () => readCodexAppServerUsage,
|
|
288
|
+
requestCodexAppServerClientJson: () => requestCodexAppServerClientJson,
|
|
289
|
+
requestCodexAppServerJson: () => requestCodexAppServerJson,
|
|
290
|
+
withCodexAppServerJsonClient: () => withCodexAppServerJsonClient
|
|
291
|
+
});
|
|
292
|
+
/** Sends one guarded request over a client lease owned by the caller. */
|
|
293
|
+
async function requestCodexAppServerClientJson(params) {
|
|
294
|
+
const sandboxBlock = resolveCodexAppServerDirectSandboxBypassBlock({
|
|
295
|
+
method: params.method,
|
|
296
|
+
requestParams: params.requestParams,
|
|
297
|
+
config: params.config,
|
|
298
|
+
sessionKey: params.sessionKey,
|
|
299
|
+
sessionId: params.sessionId
|
|
300
|
+
});
|
|
301
|
+
if (sandboxBlock) throw new Error(sandboxBlock);
|
|
302
|
+
const timeoutMs = params.timeoutMs ?? 6e4;
|
|
303
|
+
return await withTimeout(params.client.request(params.method, params.requestParams, {
|
|
304
|
+
timeoutMs,
|
|
305
|
+
signal: params.signal,
|
|
306
|
+
...params.assertCurrent ? { assertCurrent: () => assertRequestOwnerCurrent(params.assertCurrent) } : {}
|
|
307
|
+
}), timeoutMs, `codex app-server ${params.method} timed out`);
|
|
308
|
+
}
|
|
309
|
+
async function requestCodexAppServerJson(params) {
|
|
310
|
+
const sandboxBlock = resolveCodexAppServerDirectSandboxBypassBlock({
|
|
311
|
+
method: params.method,
|
|
312
|
+
requestParams: params.requestParams,
|
|
313
|
+
config: params.config,
|
|
314
|
+
sessionKey: params.sessionKey,
|
|
315
|
+
sessionId: params.sessionId
|
|
316
|
+
});
|
|
317
|
+
if (sandboxBlock) throw new Error(sandboxBlock);
|
|
318
|
+
return await withCodexAppServerJsonClient({
|
|
319
|
+
...params,
|
|
320
|
+
timeoutMessage: `codex app-server ${params.method} timed out`
|
|
321
|
+
}, async (request) => await request({
|
|
322
|
+
method: params.method,
|
|
323
|
+
requestParams: params.requestParams
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
/** A scoped guard rejected the request before a physical write. */
|
|
327
|
+
var CodexAppServerScopedRequestRejectedError = class extends Error {
|
|
328
|
+
constructor(message, options) {
|
|
329
|
+
super(message, options);
|
|
330
|
+
this.name = "CodexAppServerScopedRequestRejectedError";
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
function assertRequestOwnerCurrent(assertCurrent) {
|
|
334
|
+
try {
|
|
335
|
+
assertCurrent?.();
|
|
336
|
+
} catch (cause) {
|
|
337
|
+
throw new CodexAppServerScopedRequestRejectedError(cause instanceof Error ? cause.message : String(cause), { cause });
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
const CODEX_USAGE_ISOLATED_SHUTDOWN = {
|
|
341
|
+
forceKillDelayMs: 200,
|
|
342
|
+
exitTimeoutMs: 300
|
|
343
|
+
};
|
|
344
|
+
const CODEX_ACCOUNT_READ_MAX_TIMEOUT_MS = 4e3;
|
|
345
|
+
const CODEX_USAGE_DEADLINE_RESERVE_MS = CODEX_USAGE_ISOLATED_SHUTDOWN.forceKillDelayMs + CODEX_USAGE_ISOLATED_SHUTDOWN.exitTimeoutMs + 250;
|
|
346
|
+
/** Reads rate limits and best-effort account identity from one isolated app-server session. */
|
|
347
|
+
async function readCodexAppServerUsage(options) {
|
|
348
|
+
const deadline = Date.now() + options.timeoutMs;
|
|
349
|
+
return await withCodexAppServerJsonClient({
|
|
350
|
+
timeoutMs: options.timeoutMs,
|
|
351
|
+
timeoutMessage: "codex app-server usage read timed out",
|
|
352
|
+
agentDir: options.agentDir,
|
|
353
|
+
...options.authProfileId ? { authProfileId: options.authProfileId } : {},
|
|
354
|
+
config: options.config,
|
|
355
|
+
startOptions: options.startOptions,
|
|
356
|
+
isolated: true,
|
|
357
|
+
isolatedShutdown: CODEX_USAGE_ISOLATED_SHUTDOWN
|
|
358
|
+
}, async (request) => {
|
|
359
|
+
const rateLimits = await request({ method: "account/rateLimits/read" });
|
|
360
|
+
const accountEmail = await readCodexAccountEmailBestEffort(request, deadline);
|
|
361
|
+
return {
|
|
362
|
+
rateLimits,
|
|
363
|
+
...accountEmail ? { accountEmail } : {}
|
|
364
|
+
};
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
function extractCodexAccountEmail(value) {
|
|
368
|
+
if (!value || typeof value !== "object") return;
|
|
369
|
+
const record = value;
|
|
370
|
+
const account = record.account && typeof record.account === "object" ? record.account : record;
|
|
371
|
+
const email = account.email ?? account.accountEmail;
|
|
372
|
+
return typeof email === "string" && email.trim() ? email.trim() : void 0;
|
|
373
|
+
}
|
|
374
|
+
async function readCodexAccountEmailBestEffort(request, deadline) {
|
|
375
|
+
const boundMs = Math.min(CODEX_ACCOUNT_READ_MAX_TIMEOUT_MS, deadline - Date.now() - CODEX_USAGE_DEADLINE_RESERVE_MS);
|
|
376
|
+
if (boundMs <= 0) return;
|
|
377
|
+
const read = request({
|
|
378
|
+
method: "account/read",
|
|
379
|
+
requestParams: {}
|
|
380
|
+
}).then((account) => extractCodexAccountEmail(account), () => void 0);
|
|
381
|
+
let timer;
|
|
382
|
+
const timeout = new Promise((resolve) => {
|
|
383
|
+
timer = setTimeout(() => resolve(void 0), boundMs);
|
|
384
|
+
timer.unref?.();
|
|
385
|
+
});
|
|
386
|
+
try {
|
|
387
|
+
return await Promise.race([read, timeout]);
|
|
388
|
+
} finally {
|
|
389
|
+
if (timer) clearTimeout(timer);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Runs several guarded requests over one acquired client (shared lease or
|
|
394
|
+
* isolated child) so related reads see the same app-server session. The whole
|
|
395
|
+
* callback re-runs once when the client's start selection changed underneath it.
|
|
396
|
+
*/
|
|
397
|
+
async function withCodexAppServerJsonClient(params, run) {
|
|
398
|
+
const timeoutMs = params.timeoutMs ?? 6e4;
|
|
399
|
+
const timeoutMessage = params.timeoutMessage ?? "codex app-server request timed out";
|
|
400
|
+
const timeoutController = new AbortController();
|
|
401
|
+
const deadline = Number.isFinite(timeoutMs) && timeoutMs > 0 ? Date.now() + timeoutMs : void 0;
|
|
402
|
+
const isPastDeadline = () => deadline !== void 0 && Date.now() >= deadline;
|
|
403
|
+
const throwIfAbandoned = () => {
|
|
404
|
+
if (timeoutController.signal.aborted || isPastDeadline()) throw new CodexAppServerScopedRequestRejectedError(timeoutMessage);
|
|
405
|
+
};
|
|
406
|
+
const remainingTimeoutMs = () => {
|
|
407
|
+
throwIfAbandoned();
|
|
408
|
+
return deadline === void 0 ? timeoutMs : Math.max(1, deadline - Date.now());
|
|
409
|
+
};
|
|
410
|
+
try {
|
|
411
|
+
return await withTimeout((async () => {
|
|
412
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
413
|
+
throwIfAbandoned();
|
|
414
|
+
const client = await (params.isolated ? createIsolatedCodexAppServerClient : getLeasedSharedCodexAppServerClient)({
|
|
415
|
+
startOptions: params.startOptions,
|
|
416
|
+
pluginConfig: params.pluginConfig,
|
|
417
|
+
timeoutMs: remainingTimeoutMs(),
|
|
418
|
+
authProfileId: params.authProfileId,
|
|
419
|
+
authProfileStore: params.authProfileStore,
|
|
420
|
+
authBindingFingerprint: params.authBindingFingerprint,
|
|
421
|
+
preparedAuth: params.preparedAuth,
|
|
422
|
+
authRequirement: params.authRequirement,
|
|
423
|
+
agentDir: params.agentDir,
|
|
424
|
+
config: params.config,
|
|
425
|
+
abandonSignal: timeoutController.signal
|
|
426
|
+
});
|
|
427
|
+
let scopeActive = true;
|
|
428
|
+
const assertCurrent = () => {
|
|
429
|
+
throwIfAbandoned();
|
|
430
|
+
if (!scopeActive) throw new CodexAppServerScopedRequestRejectedError("Codex app-server request scope is closed");
|
|
431
|
+
assertRequestOwnerCurrent(params.assertCurrent);
|
|
432
|
+
};
|
|
433
|
+
try {
|
|
434
|
+
assertCurrent();
|
|
435
|
+
const scopedRequest = async (request) => {
|
|
436
|
+
const sandboxBlock = resolveCodexAppServerDirectSandboxBypassBlock({
|
|
437
|
+
method: request.method,
|
|
438
|
+
requestParams: request.requestParams,
|
|
439
|
+
config: params.config,
|
|
440
|
+
sessionKey: params.sessionKey,
|
|
441
|
+
sessionId: params.sessionId
|
|
442
|
+
});
|
|
443
|
+
if (sandboxBlock) throw new CodexAppServerScopedRequestRejectedError(sandboxBlock);
|
|
444
|
+
assertCurrent();
|
|
445
|
+
return await client.request(request.method, request.requestParams, {
|
|
446
|
+
timeoutMs: remainingTimeoutMs(),
|
|
447
|
+
signal: timeoutController.signal,
|
|
448
|
+
assertCurrent
|
|
449
|
+
});
|
|
450
|
+
};
|
|
451
|
+
return await run(scopedRequest, client, { assertCurrent });
|
|
452
|
+
} catch (error) {
|
|
453
|
+
if (!isCodexAppServerStartSelectionChangedError(error) || attempt > 0) throw error;
|
|
454
|
+
if (!params.isolated) retireSharedCodexAppServerClientIfCurrent(client);
|
|
455
|
+
throwIfAbandoned();
|
|
456
|
+
} finally {
|
|
457
|
+
scopeActive = false;
|
|
458
|
+
if (params.isolated) await client.closeAndWait({
|
|
459
|
+
exitTimeoutMs: params.isolatedShutdown?.exitTimeoutMs ?? 2e3,
|
|
460
|
+
forceKillDelayMs: params.isolatedShutdown?.forceKillDelayMs ?? 250
|
|
461
|
+
});
|
|
462
|
+
else releaseLeasedSharedCodexAppServerClient(client);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
throw new Error("Codex app-server selection retry loop exited unexpectedly");
|
|
466
|
+
})(), timeoutMs, timeoutMessage);
|
|
467
|
+
} catch (error) {
|
|
468
|
+
if (isPastDeadline()) throw new Error(timeoutMessage, { cause: error });
|
|
469
|
+
throw error;
|
|
470
|
+
} finally {
|
|
471
|
+
timeoutController.abort();
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
//#endregion
|
|
475
|
+
export { request_exports as a, resolveCodexNativeSandboxBlock as c, requestCodexAppServerJson as i, resolveCodexNativeExecutionPolicy as l, readCodexAppServerUsage as n, withCodexAppServerJsonClient as o, requestCodexAppServerClientJson as r, resolveCodexNativeExecutionBlock as s, CodexAppServerScopedRequestRejectedError as t, resolveCodexNodeExecToolOverrides as u };
|