@openclaw/codex 2026.8.1-beta.2 → 2026.9.1-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.
Files changed (60) hide show
  1. package/dist/api.js +147 -0
  2. package/dist/{attempt-client-cleanup-DMLXUfa8.js → attempt-client-cleanup-bfsmcQ6m.js} +21 -2
  3. package/dist/{binding-connection-I5Bo-AsX.js → binding-connection-BMvPX73o.js} +15 -3
  4. package/dist/{bounded-turn-qgZmzy_4.js → bounded-turn-B7iBUcuP.js} +22 -16
  5. package/dist/{capabilities-CybGI1oz.js → capabilities-BRMh0aIq.js} +1 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-B1AEz8ZA.js → command-formatters-DEsIufkt.js} +2 -2
  8. package/dist/{command-handlers-Db8pu_ds.js → command-handlers-D_-1_qRp.js} +65 -37
  9. package/dist/command-rpc-CCeCkf_v.js +90 -0
  10. package/dist/{compact-LspQaGfl.js → compact-BglNFZrQ.js} +35 -29
  11. package/dist/{session-binding-DPxIvMgE.js → config-giW8X0QA.js} +108 -914
  12. package/dist/context-compaction-activity-BOeJf7yo.js +58 -0
  13. package/dist/doctor-contract-api.js +23 -21
  14. package/dist/{dynamic-tools-BVdyWkUD.js → dynamic-tools-Dnlfa--w.js} +1345 -1424
  15. package/dist/{effective-mcp-catalog-DIIhAtOZ.js → effective-mcp-catalog-CTeGrnfO.js} +2 -2
  16. package/dist/elicitation-input-DMkeki8d.js +71 -0
  17. package/dist/{event-projector-assistant-message-BwxV4d6N.js → event-projector-assistant-message-C5-Ds8mA.js} +18 -1
  18. package/dist/{event-projector-usage-e5huIQWu.js → event-projector-usage-Bk1I90Bg.js} +18 -18
  19. package/dist/harness-Csz0F-DK.js +258 -0
  20. package/dist/harness.js +2 -226
  21. package/dist/index.js +262 -181
  22. package/dist/{isolated-completion-C58NbL40.js → isolated-completion-Cv6FqygM.js} +4 -4
  23. package/dist/managed-binary-DFYK4DWq.js +248 -0
  24. package/dist/media-understanding-provider.js +2 -2
  25. package/dist/model-catalog-i9rNBthX.js +48 -0
  26. package/dist/{models-BFlpn1Ex.js → models-TS3HBU-q.js} +4 -3
  27. package/dist/{native-subagent-monitor-DyTGmTUx.js → native-subagent-monitor-4Mfq2HDs.js} +354 -83
  28. package/dist/node-exec-server.runtime-BpWqJO1V.js +192 -0
  29. package/dist/{plugin-app-cache-key-C3H2CVp6.js → plugin-app-cache-key-C1CAdfcP.js} +19 -4
  30. package/dist/plugin-approval-roundtrip-bUm777tR.js +95 -0
  31. package/dist/{plugin-marketplace-discovery-CzrGJdCR.js → plugin-marketplace-discovery-B9DvaAG-.js} +59 -54
  32. package/dist/{plugin-metadata-cache-CNJPj4_b.js → plugin-metadata-cache-CTCT3w5L.js} +164 -134
  33. package/dist/{protocol-validators-B4F7L8Rf.js → protocol-validators-VeJxxJ0U.js} +80 -5
  34. package/dist/{rate-limits-DZXmOL8-.js → rate-limits-C5_D8Gmb.js} +1 -1
  35. package/dist/{request-BRl5_UfX.js → request-DXXGHko0.js} +2 -2
  36. package/dist/{run-attempt-P8BdxC1I.js → run-attempt-DYc0QCBF.js} +1276 -765
  37. package/dist/{runtime-artifact-BVSPdd6g.js → runtime-artifact-BvyT1uyd.js} +4 -7
  38. package/dist/{sandbox-guard-Cmwc9eIk.js → sandbox-guard-kuWTn9C5.js} +25 -19
  39. package/dist/session-binding-Bcynfd-_.js +874 -0
  40. package/dist/{session-catalog-xwNi_SDM.js → session-catalog-DaLKVtpH.js} +1534 -1288
  41. package/dist/session-catalog-home-id-BNwAJ9D7.js +18 -0
  42. package/dist/{session-cli-7hgXZDV7.js → session-cli-DMc4oS2w.js} +20 -7
  43. package/dist/session-permission-policy-BrNH1bjy.js +160 -0
  44. package/dist/{session-retirement-DoMMJFKm.js → session-retirement-CcNC3YSY.js} +3 -3
  45. package/dist/{session-upstream-marker-CrIFX06J.js → session-upstream-marker-BIkusb95.js} +1 -1
  46. package/dist/{settled-turn-finalizer-BRWBO4MO.js → settled-turn-finalizer-Dc3ApjU4.js} +24 -20
  47. package/dist/{shared-client-kIBbGjk4.js → shared-client-DKz23hHY.js} +1632 -372
  48. package/dist/{side-question-9HAL26l9.js → side-question-DjA_jsNe.js} +105 -54
  49. package/dist/{thread-lifecycle-Bu1BTDXr.js → thread-lifecycle-L7oEkTlq.js} +1147 -114
  50. package/dist/{thread-ownership-6kOQHlyC.js → thread-ownership-DZeuKH1j.js} +2 -2
  51. package/dist/{thread-resume-CPrJNQVM.js → thread-resume-BE9qNEW0.js} +3 -3
  52. package/dist/{transcript-mirror-B9gGgnJS.js → transcript-mirror-DsCMWBca.js} +137 -38
  53. package/dist/{transport-stdio-DIImwDVS.js → transport-stdio-DhoGy33Z.js} +2 -2
  54. package/dist/{upstream-prompt-provenance-ClRBije0.js → upstream-prompt-provenance-CFmsKwr9.js} +12 -14
  55. package/dist/{upstream-session-fork-CE-_LdnP.js → upstream-session-fork-DlaHxSLC.js} +12 -6
  56. package/dist/{usage-CHlV0e-o.js → usage-ROIaW3wo.js} +3 -3
  57. package/dist/{web-search-provider.runtime-DRw2Vl42.js → web-search-provider.runtime-ClaNPV7N.js} +3 -3
  58. package/openclaw.plugin.json +49 -2
  59. package/package.json +9 -8
  60. package/dist/app-server-policy-zcBDc1JU.js +0 -49
@@ -1,16 +1,18 @@
1
- import { C as isCodexRemoteExecPlacementSandbox, N as resolveOpenClawExecPolicyForCodexAppServer, T as readCodexPluginConfig, d as sessionBindingIdentity, h as resolveCodexAppServerHomeScope, j as resolveCodexModelBackedReviewerPolicyContext, k as canUseCodexModelBackedApprovalsReviewerForModel, w as isCodexSandboxExecServerEnabled, x as shouldAutoApproveCodexAppServerApprovals } from "./session-binding-DPxIvMgE.js";
2
- import { A as isCodexAppServerApprovalRequest, H as ensureCodexAppServerClientRuntime, N as isCodexAppServerIndeterminateRequestCancellationError, X as readRecentCodexRateLimits, a as getLeasedSharedCodexAppServerClient, c as releaseCodexAppServerClientLease, ct as isJsonObject, h as withLeasedCodexAppServerClientStartSelectionRetry, rt as resolveCodexAppServerPreparedAuthHandoff } from "./shared-client-kIBbGjk4.js";
3
- import { d as unsubscribeCodexThreadBestEffort, h as isCodexNotificationForTurn, s as isCodexAlreadyTerminalInterruptError, u as retireUnsafeCodexTurnClientBestEffort } from "./attempt-client-cleanup-DMLXUfa8.js";
4
- import { l as readCodexTurn, o as assertCodexTurnStartResponse, r as assertCodexThreadForkResponse, s as readCodexDynamicToolCallParams } from "./protocol-validators-B4F7L8Rf.js";
5
- import { R as buildCodexPluginAppsConfigPatchFromPolicyContext, W as mergeCodexThreadConfigs, b as readCodexSupportedReasoningEfforts, f as resolveCodexWebSearchPlan, g as resolveCodexAppServerRequestModelSelection, h as resolveCodexAppServerModelProvider, k as resolveCodexDynamicToolsLoading, l as buildCodexRuntimeThreadConfig, m as CODEX_NATIVE_PERSONALITY_NONE, v as resolveCodexBindingModelProviderFallback, w as filterCodexDynamicTools, y as resolveReasoningEffort } from "./thread-lifecycle-Bu1BTDXr.js";
6
- import { n as formatCodexUsageLimitErrorMessage } from "./rate-limits-DZXmOL8-.js";
7
- import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-zcBDc1JU.js";
8
- import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-Cmwc9eIk.js";
9
- import { n as resolveCodexBindingAppServerConnection, t as requireCodexSupervisionModelSelection } from "./binding-connection-I5Bo-AsX.js";
10
- import { A as buildCodexNativeHookRelayDisabledConfig, B as resolveDynamicToolCallTimeoutMs, D as CODEX_NATIVE_HOOK_RELAY_EVENTS, E as CodexNativeToolLifecycleProjector, I as handleDynamicToolCallWithTimeout, K as resolveCodexToolAbortTerminalReason, M as emitCodexNativePreToolUseFailureDiagnostic, S as shouldRequireCodexSandboxExecServerEnvironment, a as emitDynamicToolStartedDiagnostic, b as resolveCodexSandboxEnvironmentSelection, d as releaseCodexSandboxExecServerEnvironment, i as emitDynamicToolErrorDiagnostic, k as buildCodexNativeHookRelayConfig, l as resolveCodexProviderWebSearchSupportForClient, o as emitDynamicToolTerminalDiagnostic, r as handleCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as ensureCodexSandboxExecServerEnvironment, v as resolveCodexExternalSandboxPolicyForOpenClawSandbox, w as filterToolsForVisionInputs, x as shouldEnableCodexAppServerNativeToolSurface, y as resolveCodexMessageToolProvider } from "./dynamic-tools-BVdyWkUD.js";
1
+ import { C as resolveCodexModelBackedReviewerPolicyContext, D as readCodexRequirementsToml, f as isCodexPairedNodeRemoteExecPlacementSandbox, h as readCodexPluginConfig, j as resolveOpenClawExecPolicyForCodexAppServer, m as isCodexSandboxExecServerEnabled, p as isCodexRemoteExecPlacementSandbox, r as resolveCodexAppServerHomeScope, u as shouldAutoApproveCodexAppServerApprovals, x as canUseCodexModelBackedApprovalsReviewerForModel } from "./config-giW8X0QA.js";
2
+ import { F as isCodexAppServerApprovalRequest, K as createCodexElicitationResponse, R as isCodexAppServerIndeterminateRequestCancellationError, Y as ensureCodexAppServerClientRuntime, at as readRecentCodexRateLimits, f as releaseCodexAppServerClientLease, o as getLeasedSharedCodexAppServerClient, pt as resolveCodexAppServerPreparedAuthHandoff, vt as isJsonObject, x as withLeasedCodexAppServerClientStartSelectionRetry } from "./shared-client-DKz23hHY.js";
3
+ import { d as sessionBindingIdentity } from "./session-binding-Bcynfd-_.js";
4
+ import { d as unsubscribeCodexThreadBestEffort, h as isCodexNotificationForTurn, s as isCodexAlreadyTerminalInterruptError, u as retireUnsafeCodexTurnClientBestEffort } from "./attempt-client-cleanup-bfsmcQ6m.js";
5
+ import { l as readCodexTurn, o as assertCodexTurnStartResponse, r as assertCodexThreadForkResponse, s as readCodexDynamicToolCallParams } from "./protocol-validators-VeJxxJ0U.js";
6
+ import { B as resolveCodexAppServerRequestModelSelection, F as resolveCodexWebSearchPlan, H as resolveCodexBindingModelProviderFallback, M as buildCodexRuntimeThreadConfig, R as CODEX_NATIVE_PERSONALITY_NONE, T as resolveCodexToolAbortTerminalReason, U as resolveReasoningEffort, W as readCodexSupportedReasoningEfforts, Z as filterCodexDynamicTools, bt as mergeCodexThreadConfigs, c as buildCodexNativeHookRelayConfig, d as emitCodexNativePreToolUseFailureDiagnostic, h as handleDynamicToolCallWithTimeout, l as buildCodexNativeHookRelayDisabledConfig, mt as buildCodexPluginAppsConfigPatchFromPolicyContext, o as CODEX_NATIVE_HOOK_RELAY_EVENTS, rt as resolveCodexDynamicToolsLoading, y as resolveDynamicToolCallTimeoutMs, z as resolveCodexAppServerModelProvider } from "./thread-lifecycle-L7oEkTlq.js";
7
+ import { n as formatCodexUsageLimitErrorMessage } from "./rate-limits-C5_D8Gmb.js";
8
+ import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy, t as CODEX_SESSION_PERMISSION_EXEC_MODES } from "./session-permission-policy-BrNH1bjy.js";
9
+ import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-kuWTn9C5.js";
10
+ import { n as resolveCodexBindingAppServerConnection, t as requireCodexSupervisionModelSelection } from "./binding-connection-BMvPX73o.js";
11
+ import { C as shouldRequireCodexSandboxExecServerEnvironment, D as CodexNativeToolLifecycleProjector, S as shouldEnableCodexAppServerNativeToolSurface, T as filterCodexVisionTools, a as emitDynamicToolStartedDiagnostic, b as resolveCodexNodePlacementToolConstructionPlan, d as releaseCodexSandboxExecServerEnvironment, i as emitDynamicToolErrorDiagnostic, l as resolveCodexProviderWebSearchSupportForClient, o as emitDynamicToolTerminalDiagnostic, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as ensureCodexSandboxExecServerEnvironment, v as resolveCodexExternalSandboxPolicyForOpenClawSandbox, x as resolveCodexSandboxEnvironmentSelection, y as resolveCodexMessageToolProvider } from "./dynamic-tools-Dnlfa--w.js";
11
12
  import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
12
13
  import { buildAgentHookContextChannelFields, embeddedAgentLog, formatErrorMessage, registerNativeHookRelay, resolveAgentDir, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
13
14
  import { randomUUID } from "node:crypto";
15
+ import { resolveAgentWorkspaceDir } from "openclaw/plugin-sdk/agent-runtime";
14
16
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
15
17
  //#region extensions/codex/src/app-server/side-question.ts
16
18
  const SIDE_QUESTION_COMPLETION_TIMEOUT_MS = 6e5;
@@ -56,14 +58,18 @@ async function runCodexAppServerSideQuestion(params, options) {
56
58
  config: params.cfg
57
59
  }));
58
60
  if (!binding?.threadId) throw new Error("Codex /btw needs an active Codex thread. Send a normal message first, then try /btw again.");
61
+ if (isCodexPairedNodeRemoteExecPlacementSandbox(params.sandbox)) throw new Error("Normal Codex turns are supported on nodes, but /btw is not yet bound to the active placement.");
59
62
  const pluginConfig = readCodexPluginConfig(options.pluginConfig);
60
63
  const { sessionAgentId } = resolveSessionAgentIds({
61
64
  sessionKey: params.sessionKey,
62
65
  config: params.cfg,
63
66
  agentId: params.agentId
64
67
  });
68
+ const agentWorkspaceDir = params.workspaceDir?.trim() || resolveAgentWorkspaceDir(params.cfg, sessionAgentId);
65
69
  const execPolicy = resolveOpenClawExecPolicyForCodexAppServer({
66
- approvals: loadExecApprovals(),
70
+ permissionMode: params.sessionEntry.permissionMode,
71
+ execOverrides: params.sessionEntry.permissionMode ? { mode: CODEX_SESSION_PERMISSION_EXEC_MODES[params.sessionEntry.permissionMode] } : void 0,
72
+ approvals: params.sessionEntry.permissionMode === "full" ? void 0 : loadExecApprovals(),
67
73
  config: params.cfg,
68
74
  agentId: sessionAgentId
69
75
  });
@@ -99,7 +105,7 @@ async function runCodexAppServerSideQuestion(params, options) {
99
105
  bindingModelProvider: binding.modelProvider
100
106
  });
101
107
  const modelSelection = resolveCodexAppServerRequestModelSelection({
102
- model: supervisionModelSelection?.model ?? params.model,
108
+ model: supervisionModelSelection?.model ?? options.runtimeModelId ?? params.model,
103
109
  modelProvider,
104
110
  authProfileId,
105
111
  authProfileStore: preparedRuntimeAuth.authProfileStore,
@@ -123,8 +129,41 @@ async function runCodexAppServerSideQuestion(params, options) {
123
129
  config: params.cfg,
124
130
  agentDir: params.agentDir
125
131
  });
126
- const appServer = connection.appServer;
127
- const cwd = binding.cwd || params.workspaceDir || process.cwd();
132
+ const reviewerContext = {
133
+ modelProvider: reviewerPolicyContext.modelProvider,
134
+ model: reviewerPolicyContext.model,
135
+ config: params.cfg,
136
+ env: process.env,
137
+ agentDir: params.agentDir
138
+ };
139
+ const appServer = resolveCodexAppServerForModelProvider({
140
+ appServer: applyCodexSessionPermissionPolicy({
141
+ appServer: connection.appServer,
142
+ permissionMode: params.sessionEntry.permissionMode,
143
+ sessionRoot: params.sessionEntry.sessionRoot,
144
+ defaultRoot: agentWorkspaceDir,
145
+ pluginConfig,
146
+ canUseAutoReview: canUseCodexModelBackedApprovalsReviewerForModel(reviewerContext),
147
+ requirementsToml: readCodexRequirementsToml({}),
148
+ policyLocked: usesSupervisionConnection,
149
+ execMode: execPolicy.mode
150
+ }),
151
+ ...reviewerContext,
152
+ provider: reviewerContext.modelProvider
153
+ });
154
+ const sessionPermissionPolicy = resolveCodexEffectiveSessionPermissionPolicy({
155
+ appServer,
156
+ permissionMode: params.sessionEntry.permissionMode,
157
+ sessionRoot: params.sessionEntry.sessionRoot,
158
+ defaultRoot: agentWorkspaceDir
159
+ });
160
+ const cwd = resolveCodexSessionPermissionCwd({
161
+ permissionMode: params.sessionEntry.permissionMode,
162
+ sessionRoot: params.sessionEntry.sessionRoot,
163
+ defaultRoot: agentWorkspaceDir,
164
+ requestedCwd: binding.cwd,
165
+ fallbackCwd: agentWorkspaceDir
166
+ });
128
167
  const runId = params.opts?.runId ?? randomUUID();
129
168
  const effectiveParams = supervisionModelSelection ? {
130
169
  ...params,
@@ -151,8 +190,14 @@ async function runCodexAppServerSideQuestion(params, options) {
151
190
  runId,
152
191
  timeoutMs: appServer.requestTimeoutMs
153
192
  });
193
+ sideRunParams.permissionMode = sessionPermissionPolicy?.mode;
194
+ sideRunParams.sessionRoot = sessionPermissionPolicy?.root;
195
+ sideRunParams.execOverrides = sessionPermissionPolicy && { mode: sessionPermissionPolicy.execMode };
154
196
  const sandboxExecServerEnabled = isCodexSandboxExecServerEnabled(pluginConfig, params.sandbox);
155
- const nativeToolSurfaceEnabled = shouldEnableCodexAppServerNativeToolSurface(sideRunParams, params.sandbox ?? void 0, { sandboxExecServerEnabled });
197
+ const nativeToolSurfaceEnabled = shouldEnableCodexAppServerNativeToolSurface(sideRunParams, params.sandbox ?? void 0, {
198
+ agentId: sideRunParams.agentId,
199
+ sandboxExecServerEnabled
200
+ });
156
201
  const sandboxEnvironmentRequired = shouldRequireCodexSandboxExecServerEnvironment({
157
202
  sandbox: params.sandbox ?? void 0,
158
203
  nativeToolSurfaceEnabled,
@@ -162,6 +207,7 @@ async function runCodexAppServerSideQuestion(params, options) {
162
207
  config: sideRunParams.config,
163
208
  sessionKey: sideRunParams.sandboxSessionKey?.trim() || sideRunParams.sessionKey,
164
209
  sessionId: sideRunParams.sessionId,
210
+ agentId: sideRunParams.agentId,
165
211
  sandbox: params.sandbox,
166
212
  sandboxEnvironmentSelected: sandboxEnvironmentRequired,
167
213
  surface: "/btw side-question mode"
@@ -230,9 +276,10 @@ async function runCodexAppServerSideQuestion(params, options) {
230
276
  const activeDynamicToolCalls = /* @__PURE__ */ new Set();
231
277
  const releaseSandboxEnvironment = async () => {
232
278
  if (!sandboxEnvironment) return;
279
+ const environment = sandboxEnvironment;
233
280
  sandboxEnvironment = void 0;
234
281
  sandboxEnvironmentClient = void 0;
235
- await releaseCodexSandboxExecServerEnvironment(params.sandbox);
282
+ await releaseCodexSandboxExecServerEnvironment(params.sandbox, environment);
236
283
  };
237
284
  const ensureSandboxEnvironment = async (targetClient) => {
238
285
  if (!sandboxEnvironmentRequired || sandboxEnvironmentClient === targetClient) return;
@@ -240,32 +287,23 @@ async function runCodexAppServerSideQuestion(params, options) {
240
287
  const environment = await ensureCodexSandboxExecServerEnvironment({
241
288
  client: targetClient,
242
289
  sandbox: params.sandbox ?? null,
290
+ runtime: options.runtime,
243
291
  appServerStartOptions: appServer.start,
244
292
  timeoutMs: appServer.requestTimeoutMs,
245
- signal: runAbortController.signal
293
+ signal: runAbortController.signal,
294
+ onExecutionDisconnect: (error) => {
295
+ collector.reject(error);
296
+ embeddedAgentLog.warn(error.message);
297
+ runAbortController.abort("client_closed");
298
+ }
246
299
  });
247
300
  if (!environment) throw new Error("Codex app-server did not register an OpenClaw sandbox exec-server environment.");
248
301
  sandboxEnvironment = environment;
249
302
  sandboxEnvironmentClient = targetClient;
250
303
  };
251
304
  try {
252
- const modelScopedAppServer = resolveCodexAppServerForModelProvider({
253
- appServer,
254
- provider: reviewerPolicyContext.modelProvider,
255
- model: reviewerPolicyContext.model,
256
- config: params.cfg,
257
- env: process.env,
258
- agentDir: params.agentDir
259
- });
260
- const useModelScopedPolicy = !canUseCodexModelBackedApprovalsReviewerForModel({
261
- modelProvider: reviewerPolicyContext.modelProvider,
262
- model: reviewerPolicyContext.model,
263
- config: params.cfg,
264
- env: process.env,
265
- agentDir: params.agentDir
266
- });
267
- const approvalPolicy = useModelScopedPolicy ? modelScopedAppServer.approvalPolicy : binding.approvalPolicy ?? modelScopedAppServer.approvalPolicy;
268
- const sandbox = useModelScopedPolicy ? modelScopedAppServer.sandbox : binding.sandbox ?? modelScopedAppServer.sandbox;
305
+ const approvalPolicy = appServer.approvalPolicy;
306
+ const sandbox = appServer.sandbox;
269
307
  const { toolBridge, webSearchPlan } = await createCodexSideToolBridge({
270
308
  params: effectiveParams,
271
309
  cwd,
@@ -281,6 +319,7 @@ async function runCodexAppServerSideQuestion(params, options) {
281
319
  modelProviderOverride: modelSelection.modelProvider,
282
320
  signal: runAbortController.signal
283
321
  }) : "unsupported",
322
+ sessionPermissionPolicy,
284
323
  runId,
285
324
  signal: runAbortController.signal
286
325
  });
@@ -295,14 +334,17 @@ async function runCodexAppServerSideQuestion(params, options) {
295
334
  });
296
335
  const registerRequestHandler = (targetClient) => targetClient.addRequestHandler(async (request) => {
297
336
  if (!childThreadId || !turnId) return;
298
- if (request.method === "mcpServer/elicitation/request") return handleCodexAppServerElicitationRequest({
299
- requestParams: request.params,
300
- paramsForRun: sideRunParams,
301
- threadId: childThreadId,
302
- turnId,
303
- pluginAppPolicyContext: binding.pluginAppPolicyContext,
304
- signal: runAbortController.signal
305
- });
337
+ if (request.method === "mcpServer/elicitation/request") {
338
+ const approvalResult = await routeCodexAppServerElicitationRequest({
339
+ requestParams: request.params,
340
+ paramsForRun: sideRunParams,
341
+ threadId: childThreadId,
342
+ turnId,
343
+ pluginAppPolicyContext: binding.pluginAppPolicyContext,
344
+ signal: runAbortController.signal
345
+ });
346
+ return approvalResult.kind === "handled" ? approvalResult.response : createCodexElicitationResponse("decline", null, { message: "OpenClaw Codex side questions do not support interactive MCP input." });
347
+ }
306
348
  if (request.method === "item/tool/requestUserInput") return isSideUserInputRequest(request.params, childThreadId, turnId) ? emptySideUserInputResponse() : void 0;
307
349
  if (isCodexAppServerApprovalRequest(request.method)) return handleCodexAppServerApprovalRequest({
308
350
  method: request.method,
@@ -313,7 +355,7 @@ async function runCodexAppServerSideQuestion(params, options) {
313
355
  nativeHookRelay,
314
356
  autoApprove: shouldAutoApproveCodexAppServerApprovals({
315
357
  approvalPolicy,
316
- networkProxy: modelScopedAppServer.networkProxy,
358
+ networkProxy: appServer.networkProxy,
317
359
  sandbox
318
360
  }),
319
361
  signal: runAbortController.signal,
@@ -412,18 +454,17 @@ async function runCodexAppServerSideQuestion(params, options) {
412
454
  relay: nativeHookRelay,
413
455
  events: nativeHookRelayEvents,
414
456
  hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec,
415
- clearOmittedEvents: true,
416
- loopDetectionPreToolUseRelay: appServer.loopDetectionPreToolUseRelay
457
+ clearOmittedEvents: true
417
458
  }) : options.nativeHookRelay?.enabled === false ? buildCodexNativeHookRelayDisabledConfig() : void 0;
418
459
  const runtimeThreadConfig = buildCodexRuntimeThreadConfig(webSearchPlan.threadConfig, {
419
460
  nativeCodeModeEnabled: nativeToolSurfaceEnabled,
420
461
  nativeCodeModeOnlyEnabled: appServer.codeModeOnly
421
462
  });
422
- const threadConfig = mergeCodexThreadConfigs(nativeHookRelayConfig, runtimeThreadConfig, binding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(binding.pluginAppPolicyContext) : void 0, modelScopedAppServer.networkProxy?.configPatch) ?? runtimeThreadConfig;
463
+ const threadConfig = mergeCodexThreadConfigs(nativeHookRelayConfig, runtimeThreadConfig, binding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(binding.pluginAppPolicyContext) : void 0, appServer.networkProxy?.configPatch) ?? runtimeThreadConfig;
423
464
  const forkResponse = assertCodexThreadForkResponse(await withLeasedCodexAppServerClientStartSelectionRetry({
424
465
  lease: clientLease,
425
466
  options: clientOptions,
426
- signal: params.opts?.abortSignal,
467
+ signal: runAbortController.signal,
427
468
  run: async (forkClient, requestOptions) => {
428
469
  await ensureSandboxEnvironment(forkClient);
429
470
  const executionCwd = sandboxEnvironment?.cwd ?? cwd;
@@ -432,9 +473,10 @@ async function runCodexAppServerSideQuestion(params, options) {
432
473
  model: modelSelection.model,
433
474
  ...modelSelection.modelProvider ? { modelProvider: modelSelection.modelProvider } : {},
434
475
  cwd: executionCwd,
476
+ ...sessionPermissionPolicy ? { runtimeWorkspaceRoots: [sessionPermissionPolicy.root] } : {},
435
477
  approvalPolicy,
436
- approvalsReviewer: modelScopedAppServer.approvalsReviewer,
437
- ...sandboxEnvironment || modelScopedAppServer.networkProxy ? {} : { sandbox },
478
+ approvalsReviewer: appServer.approvalsReviewer,
479
+ ...sandboxEnvironment || appServer.networkProxy ? {} : { sandbox },
438
480
  ...serviceTier ? { serviceTier } : {},
439
481
  config: threadConfig,
440
482
  developerInstructions: SIDE_DEVELOPER_INSTRUCTIONS,
@@ -451,7 +493,7 @@ async function runCodexAppServerSideQuestion(params, options) {
451
493
  items: [sideBoundaryPromptItem()]
452
494
  }, {
453
495
  timeoutMs: appServer.requestTimeoutMs,
454
- signal: params.opts?.abortSignal
496
+ signal: runAbortController.signal
455
497
  });
456
498
  const effort = usesSupervisionConnection ? void 0 : resolveReasoningEffort(params.resolvedThinkLevel ?? "off", modelSelection.model, readCodexSupportedReasoningEfforts(params.runtimeModel?.compat));
457
499
  turnId = assertCodexTurnStartResponse(await client.request("turn/start", {
@@ -482,7 +524,7 @@ async function runCodexAppServerSideQuestion(params, options) {
482
524
  }
483
525
  }, {
484
526
  timeoutMs: appServer.requestTimeoutMs,
485
- signal: params.opts?.abortSignal
527
+ signal: runAbortController.signal
486
528
  }).catch((error) => {
487
529
  if (isCodexAppServerIndeterminateRequestCancellationError(error)) turnId = "";
488
530
  throw error;
@@ -499,7 +541,7 @@ async function runCodexAppServerSideQuestion(params, options) {
499
541
  let text;
500
542
  try {
501
543
  text = await collector.wait({
502
- signal: params.opts?.abortSignal,
544
+ signal: runAbortController.signal,
503
545
  timeoutMs: Math.max(appServer.turnCompletionIdleTimeoutMs, SIDE_QUESTION_COMPLETION_TIMEOUT_MS)
504
546
  });
505
547
  } catch (error) {
@@ -622,6 +664,7 @@ function buildSideRunAttemptParams(params, options) {
622
664
  authStorage: params.preparedRuntimeAuth.authStorage,
623
665
  authProfileStore: params.preparedRuntimeAuth.authProfileStore,
624
666
  modelRegistry: params.preparedRuntimeAuth.modelRegistry,
667
+ preparedModelRuntime: params.preparedModelRuntime,
625
668
  ...params.preparedRuntimeAuth.resolvedApiKey ? { resolvedApiKey: params.preparedRuntimeAuth.resolvedApiKey } : {},
626
669
  runId: options.runId,
627
670
  abortSignal: params.opts?.abortSignal,
@@ -641,6 +684,7 @@ async function createCodexSideToolBridge(input) {
641
684
  };
642
685
  const messageToolProvider = resolveCodexMessageToolProvider(input.params);
643
686
  let tools = [];
687
+ const webFetchHostnameAllowlistRef = {};
644
688
  if (supportsModelTools(runtimeModel)) {
645
689
  const createOpenClawCodingTools = (await import("openclaw/plugin-sdk/agent-harness")).createOpenClawCodingTools;
646
690
  const sandboxSessionKey = input.params.sandboxSessionKey?.trim() || input.params.sessionKey?.trim() || input.params.sessionId || input.sessionAgentId;
@@ -649,11 +693,14 @@ async function createCodexSideToolBridge(input) {
649
693
  sessionKey: sandboxSessionKey,
650
694
  workspaceDir: input.cwd
651
695
  });
652
- tools = filterToolsForVisionInputs(filterCodexDynamicTools(createOpenClawCodingTools({
696
+ const toolConstructionPlan = resolveCodexNodePlacementToolConstructionPlan(sandbox, input.nativeToolSurfaceEnabled);
697
+ tools = filterCodexVisionTools(filterCodexDynamicTools(createOpenClawCodingTools({
653
698
  agentId: input.sessionAgentId,
654
699
  sessionKey: sandboxSessionKey,
655
700
  runSessionKey: input.params.sessionKey && input.params.sessionKey !== sandboxSessionKey ? input.params.sessionKey : void 0,
656
701
  sessionId: input.params.sessionId,
702
+ exec: input.sessionPermissionPolicy && { mode: input.sessionPermissionPolicy.execMode },
703
+ sessionPermissionPolicy: input.sessionPermissionPolicy,
657
704
  runId: input.runId,
658
705
  agentDir: input.params.agentDir ?? resolveAgentDir(input.params.cfg ?? {}, input.sessionAgentId),
659
706
  workspaceDir: input.cwd,
@@ -662,6 +709,7 @@ async function createCodexSideToolBridge(input) {
662
709
  resolvedWorkspace: input.params.workspaceDir ?? input.cwd
663
710
  }),
664
711
  config: input.params.cfg,
712
+ preparedModelRuntime: input.params.preparedModelRuntime,
665
713
  abortSignal: input.signal,
666
714
  modelProvider: runtimeModel.provider,
667
715
  modelId: input.params.model,
@@ -670,6 +718,7 @@ async function createCodexSideToolBridge(input) {
670
718
  modelContextWindowTokens: runtimeModel.contextWindow,
671
719
  modelAuthMode: resolveModelAuthMode(runtimeModel.provider, input.params.cfg, void 0, { workspaceDir: input.cwd }),
672
720
  suppressManagedWebSearch: false,
721
+ webFetchHostnameAllowlistRef,
673
722
  ...input.params.messageProvider || input.params.messageChannel ? {
674
723
  messageProvider: messageToolProvider,
675
724
  toolPolicyMessageProvider: input.params.messageProvider ?? input.params.messageChannel
@@ -698,12 +747,13 @@ async function createCodexSideToolBridge(input) {
698
747
  currentChannelId: input.params.currentChannelId
699
748
  }).channelId,
700
749
  sandbox,
750
+ ...toolConstructionPlan ? { toolConstructionPlan } : {},
701
751
  emitBeforeToolCallDiagnostics: false,
702
752
  modelHasVision: runtimeModel.input?.includes("image") ?? false,
703
753
  requireExplicitMessageTarget: true
704
754
  }), input.pluginConfig), {
705
755
  modelHasVision: runtimeModel.input?.includes("image") ?? false,
706
- hasInboundImages: false
756
+ nativeImageInspectionEnabled: input.nativeToolSurfaceEnabled
707
757
  });
708
758
  }
709
759
  const requestedWebSearchPlan = resolveCodexWebSearchPlan({
@@ -712,6 +762,7 @@ async function createCodexSideToolBridge(input) {
712
762
  nativeProviderWebSearchSupport: input.nativeProviderWebSearchSupport,
713
763
  webSearchAllowed: tools.some((tool) => tool.name === "web_search")
714
764
  });
765
+ webFetchHostnameAllowlistRef.value = requestedWebSearchPlan.webFetchHostnameAllowlist;
715
766
  const webSearchPlan = requestedWebSearchPlan.kind === "managed" ? resolveCodexWebSearchPlan({
716
767
  config: input.params.cfg,
717
768
  webSearchAllowed: false