@openclaw/codex 2026.9.1 → 2026.9.2

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 (67) hide show
  1. package/dist/api.js +6 -6
  2. package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-Bp1ZOnk2.js} +76 -32
  3. package/dist/{attempt-context-DmQUNWwT.js → attempt-context-CSazkWns.js} +6 -6
  4. package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-DxGJRYbY.js} +46 -45
  5. package/dist/{capabilities-dIjNVCYH.js → capabilities-B1mgvpP8.js} +2 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DSbGMXA0.js} +2 -2
  8. package/dist/{command-handlers-CTGb2csu.js → command-handlers-DOJvGv6-.js} +146 -74
  9. package/dist/{compact-_t0HQrUS.js → compact-Y_xBqrHN.js} +83 -48
  10. package/dist/{config-BhmfC1s6.js → config-CyapYSji.js} +47 -105
  11. package/dist/config-utils-C57JiJrU.js +69 -0
  12. package/dist/doctor-contract-api.js +4 -5
  13. package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-BwpvTxaX.js} +678 -638
  14. package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-CY9Jn4bA.js} +4 -3
  15. package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-B9kp6iGC.js} +11 -2
  16. package/dist/{event-projector-usage-C5mcrGjp.js → event-projector-usage-ZqEVbAEY.js} +30 -13
  17. package/dist/{harness-DXVZ5II5.js → harness-Czh2Sdoc.js} +36 -13
  18. package/dist/harness.js +1 -1
  19. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  20. package/dist/index.js +68 -84
  21. package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-CRh-51AK.js} +9 -21
  22. package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DcpnJF9x.js} +105 -73
  23. package/dist/media-understanding-provider.js +1 -1
  24. package/dist/{model-catalog-CUM68Hkl.js → model-catalog-DT5vo6qo.js} +5 -5
  25. package/dist/{models-sYnEc0gd.js → models-CcrgSMQR.js} +4 -4
  26. package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-B3bvQGcg.js} +12 -11
  27. package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-nfbUOtUB.js} +3 -3
  28. package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-aQVdyL5g.js} +1 -1
  29. package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → plugin-marketplace-discovery-B7gHXJ3d.js} +35 -22
  30. package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-BwCLTY_U.js} +5 -5
  31. package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-BpG9Ltc5.js} +2 -2
  32. package/dist/{rate-limits-CawQJfUS.js → rate-limits-Fx_l4eNa.js} +1 -1
  33. package/dist/{request-DYAI5FQE.js → request-C8H22rPi.js} +2 -2
  34. package/dist/{run-attempt-D1hJO4fX.js → run-attempt-BzthFQSM.js} +977 -723
  35. package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-Bh_gf6-t.js} +3 -3
  36. package/dist/{session-binding-BHuTCRZQ.js → session-binding-4Ki04sW-.js} +94 -282
  37. package/dist/session-binding-record-CyaXZvTe.js +270 -0
  38. package/dist/{session-catalog-yyvTWFOw.js → session-catalog-B47uwekb.js} +266 -114
  39. package/dist/{session-cli-CmFEXMAM.js → session-cli-BjLhpmS1.js} +1 -1
  40. package/dist/session-history-DWmMqiqW.js +93 -0
  41. package/dist/session-history-read-LHldwvyh.js +36 -0
  42. package/dist/session-history-worker-runtime.js +48 -0
  43. package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-zZVcx0ME.js} +30 -31
  44. package/dist/session-history.worker.js +2 -0
  45. package/dist/{session-initialization-BeWzjGiR.js → session-initialization-BCFVnLL4.js} +2 -1
  46. package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-BaueHmSj.js} +1 -1
  47. package/dist/{session-retirement-BujDjXVF.js → session-retirement-DNdmYdFc.js} +7 -7
  48. package/dist/{session-upstream-marker-C351-5Qw.js → session-upstream-marker-DReTpGz6.js} +4 -3
  49. package/dist/settled-turn-context-BOM3Y1pl.js +45 -0
  50. package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BI-b1sry.js} +53 -42
  51. package/dist/{shared-client-DxcfF9KX.js → shared-client-CKhX2kFt.js} +279 -268
  52. package/dist/{side-question-BTZAII4l.js → side-question-B6DWAw1A.js} +85 -36
  53. package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-DPK30jad.js} +382 -388
  54. package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-CbucAmmp.js} +5 -5
  55. package/dist/thread-policy-CTalhWFy.js +105 -0
  56. package/dist/{thread-resume-C7pyVKeW.js → thread-resume-BLgqkUc1.js} +7 -7
  57. package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-_njEB84z.js} +67 -125
  58. package/dist/transcript-mirror-attestation-Byl34PC-.js +76 -0
  59. package/dist/{transport-stdio-CyPldczm.js → transport-stdio-CzTngV0j.js} +10 -8
  60. package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-1fwbNKzQ.js} +85 -165
  61. package/dist/{usage-Bj-rrzkR.js → usage-i9fv5-4m.js} +3 -3
  62. package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-DKQn67A7.js} +3 -3
  63. package/package.json +6 -6
  64. package/dist/binding-connection-E6uDsPlx.js +0 -45
  65. package/dist/launch-args-RXQwn8zV.js +0 -90
  66. package/dist/session-history-C5J1AKzG.js +0 -87
  67. package/dist/thread-policy-g4KbJPzp.js +0 -54
@@ -1,21 +1,21 @@
1
- import { $t as isJsonObject, B as isCodexAppServerIndeterminateRequestCancellationError, C as withLeasedCodexAppServerClientStartSelectionRetry, Ct as ensureCodexAppServerClientRuntime, Ft as readRecentCodexRateLimits, L as isCodexAppServerApprovalRequest, Q as assertCodexThreadForkResponse, Wt as resolveCodexAppServerPreparedAuthHandoff, _t as resolveCodexToolAbortTerminalReason, c as getLeasedSharedCodexAppServerClient, dt as resolveDynamicToolCallTimeoutMs, it as readCodexTurn, m as releaseCodexAppServerClientLease, nt as readCodexDynamicToolCallParams, ot as createCodexElicitationResponse, st as handleDynamicToolCallWithTimeout, tt as assertCodexTurnStartResponse } from "./shared-client-DxcfF9KX.js";
2
- import { C as isCodexPairedNodeRemoteExecPlacementSandbox, E as readCodexPluginConfig, O as resolveOpenClawExecPolicyForCodexAppServer, T as isCodexSandboxExecServerEnabled, d as shouldAutoApproveCodexAppServerApprovals, f as withMcpElicitationsApprovalPolicy, h as resolveCodexModelBackedReviewerPolicyContext, l as hasCodexMcpToolApprovalOverrides, m as canUseCodexModelBackedApprovalsReviewerForModel, r as resolveCodexAppServerHomeScope, w as isCodexRemoteExecPlacementSandbox, y as readCodexRequirementsToml } from "./config-BhmfC1s6.js";
3
- import { d as sessionBindingIdentity } from "./session-binding-BHuTCRZQ.js";
4
- import { d as unsubscribeCodexThreadBestEffort, h as isCodexNotificationForTurn, l as retireUnsafeCodexTurnClientBestEffort, s as isCodexAlreadyTerminalInterruptError } from "./attempt-client-cleanup-DYHcRQAa.js";
5
- import { B as emitCodexNativePreToolUseFailureDiagnostic, Dt as mergeCodexThreadConfigs, E as resolveCodexAppServerRequestModelSelection, I as buildCodexNativeHookRelayConfig, L as buildCodexNativeHookRelayDisabledConfig, N as CODEX_NATIVE_HOOK_RELAY_EVENTS, O as resolveCodexBindingModelProviderFallback, S as resolveCodexWebSearchPlan, St as buildCodexPluginAppsConfigPatchFromPolicyContext, T as resolveCodexAppServerModelProvider, a as readCodexSupportedReasoningEfforts, at as filterCodexDynamicTools, dt as resolveCodexDynamicToolsLoading, o as resolveCodexAppServerReasoningEffort, t as buildCodexTemporalAdditionalContext, v as buildCodexRuntimeThreadConfig, w as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-lifecycle-DAcEJ_Om.js";
6
- import { s as resolveCodexNativeExecutionBlock } from "./request-DYAI5FQE.js";
7
- import { i as refreshCodexThreadPolicy, n as CodexThreadPolicyHandoffError, r as assertCodexSupervisionThreadLineage } from "./thread-policy-g4KbJPzp.js";
8
- import { n as formatCodexUsageLimitErrorMessage } from "./rate-limits-CawQJfUS.js";
9
- import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy, t as CODEX_SESSION_PERMISSION_EXEC_MODES } from "./session-permission-policy-DeWVTCMj.js";
10
- import { n as resolveCodexBindingAppServerConnection, t as requireCodexSupervisionModelSelection } from "./binding-connection-E6uDsPlx.js";
11
- import { C as filterCodexVisionTools, T as CodexNativeToolLifecycleProjector, _ as resolveCodexMessageToolProvider, a as emitDynamicToolStartedDiagnostic, b as shouldEnableCodexAppServerNativeToolSurface, c as ensureCodexSandboxExecServerEnvironment, g as resolveCodexExternalSandboxPolicyForOpenClawSandbox, i as emitDynamicToolErrorDiagnostic, l as releaseCodexSandboxExecServerEnvironment, o as emitDynamicToolTerminalDiagnostic, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, v as resolveCodexNodePlacementToolConstructionPlan, x as shouldRequireCodexSandboxExecServerEnvironment, y as resolveCodexSandboxEnvironmentSelection } from "./dynamic-tools-BU9tmlYm.js";
12
- import { n as resolveCodexProviderWebSearchSupportForClient } from "./provider-capabilities-DW5p4k9w.js";
1
+ import { l as sessionBindingIdentity } from "./session-binding-record-CyaXZvTe.js";
2
+ import { A as resolveOpenClawExecPolicyForCodexAppServer, B as isJsonObject, D as isCodexSandboxExecServerEnabled, E as isCodexRemoteExecPlacementSandbox, O as readCodexPluginConfig, T as isCodexPairedNodeRemoteExecPlacementSandbox, d as shouldAutoApproveCodexAppServerApprovals, f as withMcpElicitationsApprovalPolicy, h as resolveCodexModelBackedReviewerPolicyContext, l as hasCodexMcpToolApprovalOverrides, m as canUseCodexModelBackedApprovalsReviewerForModel, r as resolveCodexAppServerHomeScope, y as readCodexRequirementsToml } from "./config-CyapYSji.js";
3
+ import { B as isCodexAppServerIndeterminateRequestCancellationError, C as withLeasedCodexAppServerClientStartSelectionRetry, Kt as resolveCodexAppServerPreparedAuthHandoff, L as isCodexAppServerApprovalRequest, Lt as readRecentCodexRateLimits, Tt as ensureCodexAppServerClientRuntime, c as getLeasedSharedCodexAppServerClient, ct as createCodexElicitationResponse, et as assertCodexThreadForkResponse, it as readCodexDynamicToolCallParams, lt as handleDynamicToolCallWithTimeout, m as releaseCodexAppServerClientLease, ot as readCodexTurn, pt as resolveDynamicToolCallTimeoutMs, rt as assertCodexTurnStartResponse, yt as resolveCodexToolAbortTerminalReason } from "./shared-client-CKhX2kFt.js";
4
+ import { l as resolveCodexSessionBinding } from "./session-binding-4Ki04sW-.js";
5
+ import { d as unsubscribeCodexThreadBestEffort, h as isCodexNotificationForTurn, l as retireUnsafeCodexTurnClientBestEffort, o as interruptCodexTurnAndWaitBestEffort } from "./attempt-client-cleanup-Bp1ZOnk2.js";
6
+ import { B as emitCodexNativePreToolUseFailureDiagnostic, Dt as refreshCodexPluginAppApprovalPolicy, E as resolveCodexAppServerRequestModelSelection, Et as mergeCodexThreadConfigs, I as buildCodexNativeHookRelayConfig, L as buildCodexNativeHookRelayDisabledConfig, N as CODEX_NATIVE_HOOK_RELAY_EVENTS, O as resolveCodexBindingModelProviderFallback, S as resolveCodexWebSearchPlan, T as resolveCodexAppServerModelProvider, a as readCodexSupportedReasoningEfforts, at as filterCodexDynamicTools, dt as resolveCodexDynamicToolsLoading, o as resolveCodexAppServerReasoningEffort, t as buildCodexTemporalAdditionalContext, v as buildCodexRuntimeThreadConfig, w as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-lifecycle-DPK30jad.js";
7
+ import { i as refreshCodexThreadPolicy, n as CodexThreadPolicyHandoffError, o as requireCodexSupervisionModelSelection, r as assertCodexSupervisionThreadLineage, s as resolveCodexBindingAppServerConnection } from "./thread-policy-CTalhWFy.js";
8
+ import { s as resolveCodexNativeExecutionBlock } from "./request-C8H22rPi.js";
9
+ import { n as formatCodexUsageLimitErrorMessage } from "./rate-limits-Fx_l4eNa.js";
10
+ import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy, t as CODEX_SESSION_PERMISSION_EXEC_MODES } from "./session-permission-policy-BaueHmSj.js";
11
+ import { C as shouldRequireCodexSandboxExecServerEnvironment, S as shouldEnableCodexAppServerNativeToolSurface, T as filterCodexVisionTools, a as emitDynamicToolStartedDiagnostic, b as resolveCodexNodePlacementToolConstructionPlan, c as ensureCodexSandboxExecServerEnvironment, d as CodexNativeToolLifecycleProjector, i as emitDynamicToolErrorDiagnostic, l as releaseCodexSandboxExecServerEnvironment, o as emitDynamicToolTerminalDiagnostic, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, v as resolveCodexExternalSandboxPolicyForOpenClawSandbox, x as resolveCodexSandboxEnvironmentSelection, y as resolveCodexMessageToolProvider } from "./dynamic-tools-BwpvTxaX.js";
12
+ import { n as resolveCodexProviderWebSearchSupportForClient } from "./provider-capabilities-BpG9Ltc5.js";
13
13
  import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
14
- import { buildAgentHookContextChannelFields, embeddedAgentLog, formatErrorMessage, registerNativeHookRelay, resolveAgentDir, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
15
14
  import { randomUUID } from "node:crypto";
15
+ import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
16
+ import { buildAgentHookContextChannelFields, embeddedAgentLog, formatErrorMessage, registerNativeHookRelay, resolveAgentDir as resolveAgentDir$1, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
16
17
  import { isDeepStrictEqual } from "node:util";
17
18
  import { resolveAgentWorkspaceDir } from "openclaw/plugin-sdk/agent-runtime";
18
- import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
19
19
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
20
20
  import { loadCodexBundleMcpApprovalConfig, resolveCodexMcpToolOverridesForAgent } from "openclaw/plugin-sdk/codex-mcp-projection";
21
21
  //#region extensions/codex/src/app-server/side-question.ts
@@ -50,7 +50,15 @@ async function runCodexAppServerSideQuestion(params, options) {
50
50
  agentId: params.agentId,
51
51
  config: params.cfg
52
52
  });
53
- const binding = await options.bindingStore.read(bindingIdentity);
53
+ const hostCapabilities = params.hostCapabilities;
54
+ const { binding, assertCurrent } = await resolveCodexSessionBinding({
55
+ bindingStore: options.bindingStore,
56
+ identity: bindingIdentity,
57
+ config: params.cfg,
58
+ storePath: params.storePath,
59
+ assertCurrent: hostCapabilities.assertActive,
60
+ signal: params.opts?.abortSignal
61
+ });
54
62
  if (!binding?.threadId) throw new Error("Codex /btw needs an active Codex thread. Send a normal message first, then try /btw again.");
55
63
  if (isCodexPairedNodeRemoteExecPlacementSandbox(params.sandbox)) throw new Error("Normal Codex turns are supported on nodes, but /btw is not yet bound to the active placement.");
56
64
  const pluginConfig = readCodexPluginConfig(options.pluginConfig);
@@ -262,6 +270,7 @@ async function runCodexAppServerSideQuestion(params, options) {
262
270
  if (params.opts?.abortSignal?.aborted) abortFromUpstream();
263
271
  else params.opts?.abortSignal?.addEventListener("abort", abortFromUpstream, { once: true });
264
272
  let childThreadId;
273
+ let pluginAppPolicyContext = binding.pluginAppPolicyContext;
265
274
  let childClient;
266
275
  let policyWriteUncertain = false;
267
276
  let turnId;
@@ -280,6 +289,7 @@ async function runCodexAppServerSideQuestion(params, options) {
280
289
  const ensureSandboxEnvironment = async (targetClient) => {
281
290
  if (!sandboxEnvironmentRequired || sandboxEnvironmentClient === targetClient) return;
282
291
  await releaseSandboxEnvironment();
292
+ assertCurrent();
283
293
  const environment = await ensureCodexSandboxExecServerEnvironment({
284
294
  client: targetClient,
285
295
  sandbox: params.sandbox ?? null,
@@ -298,6 +308,7 @@ async function runCodexAppServerSideQuestion(params, options) {
298
308
  sandboxEnvironmentClient = targetClient;
299
309
  };
300
310
  try {
311
+ assertCurrent();
301
312
  const autoApproveMcpTools = shouldAutoApproveCodexAppServerApprovals(appServer);
302
313
  const projectedMcpServers = loadCodexBundleMcpApprovalConfig({
303
314
  workspaceDir: agentWorkspaceDir,
@@ -348,7 +359,7 @@ async function runCodexAppServerSideQuestion(params, options) {
348
359
  autoApproveMcpTools,
349
360
  projectedMcpServers,
350
361
  getActiveMcpToolCall: (serverName) => nativeToolLifecycleProjector?.getActiveMcpToolCall(serverName),
351
- pluginAppPolicyContext: binding.pluginAppPolicyContext,
362
+ pluginAppPolicyContext,
352
363
  signal: runAbortController.signal
353
364
  });
354
365
  return approvalResult.kind === "handled" ? approvalResult.response : createCodexElicitationResponse("decline", null, { message: "OpenClaw Codex side questions do not support interactive MCP input." });
@@ -450,6 +461,7 @@ async function runCodexAppServerSideQuestion(params, options) {
450
461
  loopDetectionPreToolUseRelay: appServer.loopDetectionPreToolUseRelay,
451
462
  signal: runAbortController.signal,
452
463
  hostCapabilities: sideRunParams.hostCapabilities,
464
+ assertCurrent,
453
465
  onPreToolUseFailure: (failure) => {
454
466
  if (nativePreToolUseFailureFallbackActive) emitNativePreToolUseFailure(failure);
455
467
  else if (nativeToolLifecycleProjector) nativeToolLifecycleProjector.recordPreToolUseFailure(failure, nativeToolRunWasAbortedBeforeCleanup);
@@ -466,27 +478,54 @@ async function runCodexAppServerSideQuestion(params, options) {
466
478
  nativeCodeModeEnabled: nativeToolSurfaceEnabled,
467
479
  nativeCodeModeOnlyEnabled: appServer.codeModeOnly
468
480
  });
469
- const pluginAppsConfigPatch = binding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(binding.pluginAppPolicyContext) : void 0;
470
- const threadConfig = mergeCodexThreadConfigs(nativeHookRelayConfig, runtimeThreadConfig, pluginAppsConfigPatch, appServer.networkProxy?.configPatch) ?? runtimeThreadConfig;
471
481
  const sideThreadId = await withLeasedCodexAppServerClientStartSelectionRetry({
472
482
  lease: clientLease,
473
483
  options: clientOptions,
474
484
  signal: runAbortController.signal,
475
485
  run: async (forkClient, requestOptions) => options.bindingStore.withLease(bindingIdentity, async () => {
486
+ const assertCurrentBinding = () => {
487
+ assertCurrent();
488
+ runAbortController.signal.throwIfAborted();
489
+ if (!isDeepStrictEqual(options.bindingStore.read(bindingIdentity), binding)) throw new Error("Codex side-question binding changed before fork");
490
+ };
491
+ const currentRequestOptions = () => {
492
+ const scoped = requestOptions();
493
+ return {
494
+ ...scoped,
495
+ assertCurrent: () => {
496
+ scoped.assertCurrent();
497
+ assertCurrentBinding();
498
+ }
499
+ };
500
+ };
501
+ assertCurrentBinding();
476
502
  if (binding.connectionScope === "supervision") {
477
- params.hostCapabilities.assertActive();
478
503
  const { thread } = await forkClient.request("thread/read", {
479
504
  threadId: binding.threadId,
480
505
  includeTurns: false
481
- }, requestOptions());
482
- params.hostCapabilities.assertActive();
483
- if (!isDeepStrictEqual(await options.bindingStore.read(bindingIdentity), binding)) throw new Error("Codex side-question binding changed before fork");
484
- params.hostCapabilities.assertActive();
506
+ }, currentRequestOptions());
507
+ assertCurrentBinding();
485
508
  assertCodexSupervisionThreadLineage(binding, thread);
486
509
  }
487
510
  await ensureSandboxEnvironment(forkClient);
488
- params.hostCapabilities.assertActive();
511
+ assertCurrentBinding();
489
512
  const executionCwd = sandboxEnvironment?.cwd ?? cwd;
513
+ let pluginAppsConfigPatch;
514
+ if (binding.pluginAppPolicyContext) {
515
+ const refreshed = await refreshCodexPluginAppApprovalPolicy({
516
+ policyContext: binding.pluginAppPolicyContext,
517
+ configCwd: executionCwd,
518
+ request: (method, requestParams) => {
519
+ assertCurrentBinding();
520
+ return forkClient.request(method, requestParams, currentRequestOptions());
521
+ }
522
+ }).finally(assertCurrentBinding);
523
+ pluginAppPolicyContext = refreshed.policyContext;
524
+ pluginAppsConfigPatch = refreshed.configPatch;
525
+ for (const diagnostic of refreshed.diagnostics) embeddedAgentLog.warn(diagnostic.message);
526
+ }
527
+ assertCurrentBinding();
528
+ const threadConfig = mergeCodexThreadConfigs(nativeHookRelayConfig, runtimeThreadConfig, pluginAppsConfigPatch, appServer.networkProxy?.configPatch) ?? runtimeThreadConfig;
490
529
  const response = assertCodexThreadForkResponse(await forkCodexSideThread(forkClient, {
491
530
  threadId: binding.threadId,
492
531
  model: modelSelection.model,
@@ -502,7 +541,7 @@ async function runCodexAppServerSideQuestion(params, options) {
502
541
  ephemeral: true,
503
542
  excludeTurns: true,
504
543
  threadSource: "user"
505
- }, requestOptions()));
544
+ }, currentRequestOptions()));
506
545
  if (!response.thread.id.trim() || response.thread.id === binding.threadId) {
507
546
  await retireUnsafeCodexTurnClientBestEffort(forkClient, "unsafe side child identity");
508
547
  throw new Error("Codex side fork returned an unsafe child identity");
@@ -510,6 +549,7 @@ async function runCodexAppServerSideQuestion(params, options) {
510
549
  childThreadId = response.thread.id;
511
550
  childClient = forkClient;
512
551
  try {
552
+ assertCurrentBinding();
513
553
  if (supervisionModelSelection && (response.model !== supervisionModelSelection.model || response.modelProvider !== supervisionModelSelection.modelProvider)) throw new Error("Codex supervised side thread did not preserve its native model and provider");
514
554
  const scoped = requestOptions();
515
555
  await refreshCodexThreadPolicy({
@@ -519,7 +559,7 @@ async function runCodexAppServerSideQuestion(params, options) {
519
559
  ...scoped,
520
560
  signal: runAbortController.signal,
521
561
  assertCurrent: () => {
522
- params.hostCapabilities.assertActive();
562
+ assertCurrent();
523
563
  runAbortController.signal.throwIfAborted();
524
564
  scoped.assertCurrent();
525
565
  }
@@ -566,11 +606,13 @@ async function runCodexAppServerSideQuestion(params, options) {
566
606
  }
567
607
  }, {
568
608
  timeoutMs: appServer.requestTimeoutMs,
569
- signal: runAbortController.signal
609
+ signal: runAbortController.signal,
610
+ assertCurrent
570
611
  }).catch((error) => {
571
612
  if (isCodexAppServerIndeterminateRequestCancellationError(error)) turnId = "";
572
613
  throw error;
573
614
  })).turn.id;
615
+ assertCurrent();
574
616
  collector.setTurn(sideThreadId, turnId);
575
617
  nativeToolLifecycleProjector = new CodexNativeToolLifecycleProjector({
576
618
  ...sideRunParams,
@@ -591,6 +633,7 @@ async function runCodexAppServerSideQuestion(params, options) {
591
633
  throw error;
592
634
  }
593
635
  const trimmed = text.trim();
636
+ assertCurrent();
594
637
  if (!trimmed) throw new Error("Codex /btw completed without an answer.");
595
638
  return { text: trimmed };
596
639
  } finally {
@@ -653,7 +696,7 @@ function registerCodexSideNativeHookRelay(params) {
653
696
  }),
654
697
  signal: params.signal,
655
698
  runBeforeToolCall: params.hostCapabilities.runBeforeToolCall,
656
- assertActive: params.hostCapabilities.assertActive,
699
+ assertActive: params.assertCurrent,
657
700
  onPreToolUseFailure: params.onPreToolUseFailure,
658
701
  command: { timeoutMs: params.options.gatewayTimeoutMs }
659
702
  });
@@ -739,6 +782,13 @@ async function createCodexSideToolBridge(input) {
739
782
  workspaceDir: input.cwd
740
783
  });
741
784
  const toolConstructionPlan = resolveCodexNodePlacementToolConstructionPlan(sandbox, input.nativeToolSurfaceEnabled);
785
+ const publishSideToolResult = input.params.opts?.onToolResult;
786
+ const questionPrompt = publishSideToolResult ? {
787
+ send: async (payload) => {
788
+ await publishSideToolResult(payload);
789
+ },
790
+ ...input.params.messageChannel ? { messageChannel: input.params.messageChannel } : {}
791
+ } : void 0;
742
792
  const allTools = createOpenClawCodingTools({
743
793
  agentId: input.sessionAgentId,
744
794
  requesterThinkingLevel: input.params.resolvedThinkLevel ?? "off",
@@ -748,7 +798,7 @@ async function createCodexSideToolBridge(input) {
748
798
  exec: input.sessionPermissionPolicy && { mode: input.sessionPermissionPolicy.execMode },
749
799
  sessionPermissionPolicy: input.sessionPermissionPolicy,
750
800
  runId: input.runId,
751
- agentDir: input.params.agentDir ?? resolveAgentDir(input.params.cfg ?? {}, input.sessionAgentId),
801
+ agentDir: input.params.agentDir ?? resolveAgentDir$1(input.params.cfg ?? {}, input.sessionAgentId),
752
802
  workspaceDir: input.cwd,
753
803
  spawnWorkspaceDir: resolveAttemptSpawnWorkspaceDir({
754
804
  sandbox,
@@ -794,6 +844,7 @@ async function createCodexSideToolBridge(input) {
794
844
  }).channelId,
795
845
  sandbox,
796
846
  ...toolConstructionPlan ? { toolConstructionPlan } : {},
847
+ ...questionPrompt ? { questionPrompt } : {},
797
848
  emitBeforeToolCallDiagnostics: false,
798
849
  modelHasVision: runtimeModel.input?.includes("image") ?? false,
799
850
  requireExplicitMessageTarget: true
@@ -861,14 +912,12 @@ function isMissingCodexParentThreadError(error) {
861
912
  }
862
913
  async function cleanupCodexSideThread(client, params) {
863
914
  if (!params.threadId) return;
864
- if (params.interrupt && params.turnId !== void 0) try {
865
- await client.request("turn/interrupt", {
915
+ if (params.interrupt && params.turnId !== void 0) {
916
+ if (!await interruptCodexTurnAndWaitBestEffort(client, {
866
917
  threadId: params.threadId,
867
- turnId: params.turnId
868
- }, { timeoutMs: params.timeoutMs });
869
- } catch (error) {
870
- if (!isCodexAlreadyTerminalInterruptError(error)) {
871
- embeddedAgentLog.debug("codex /btw side thread interrupt cleanup failed", { error });
918
+ turnId: params.turnId,
919
+ timeoutMs: params.timeoutMs
920
+ })) {
872
921
  await retireUnsafeCodexTurnClientBestEffort(client, "side turn interrupt");
873
922
  return;
874
923
  }