@openclaw/codex 2026.7.2-beta.5 → 2026.8.1-beta.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 (59) hide show
  1. package/README.md +2 -0
  2. package/dist/{app-server-policy-BmDgseo_.js → app-server-policy-zcBDc1JU.js} +1 -1
  3. package/dist/attempt-client-cleanup-DMLXUfa8.js +735 -0
  4. package/dist/binding-connection-I5Bo-AsX.js +33 -0
  5. package/dist/{bounded-turn-FEbUXoYT.js → bounded-turn-qgZmzy_4.js} +71 -63
  6. package/dist/{capabilities-BHRSI6Cn.js → capabilities-CybGI1oz.js} +8 -2
  7. package/dist/cli-metadata.js +1 -1
  8. package/dist/{command-formatters-ico4ZFnk.js → command-formatters-B1AEz8ZA.js} +18 -18
  9. package/dist/{command-handlers-CRmnwI2N.js → command-handlers-Db8pu_ds.js} +484 -95
  10. package/dist/{compact-dEN49UH6.js → compact-LspQaGfl.js} +213 -199
  11. package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
  12. package/dist/doctor-contract-api.js +40 -43
  13. package/dist/{dynamic-tools-LIt9ojep.js → dynamic-tools-BVdyWkUD.js} +2984 -1221
  14. package/dist/effective-mcp-catalog-DIIhAtOZ.js +119 -0
  15. package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
  16. package/dist/{attempt-notifications-CMR2_fmR.js → event-projector-usage-e5huIQWu.js} +113 -29
  17. package/dist/harness.js +83 -13
  18. package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
  19. package/dist/index.js +703 -329
  20. package/dist/isolated-completion-C58NbL40.js +75 -0
  21. package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
  22. package/dist/media-understanding-provider.js +5 -5
  23. package/dist/{models-BA01NEez.js → models-BFlpn1Ex.js} +12 -17
  24. package/dist/native-subagent-monitor-DyTGmTUx.js +3111 -0
  25. package/dist/{plugin-app-cache-key-DSXX-rXO.js → plugin-app-cache-key-C3H2CVp6.js} +135 -42
  26. package/dist/plugin-marketplace-discovery-CzrGJdCR.js +385 -0
  27. package/dist/{computer-use-BjGylO-E.js → plugin-metadata-cache-CNJPj4_b.js} +211 -113
  28. package/dist/protocol-validators-B4F7L8Rf.js +2346 -0
  29. package/dist/{rate-limits-S_PXs0ul.js → rate-limits-DZXmOL8-.js} +17 -35
  30. package/dist/{request-CXpPennK.js → request-BRl5_UfX.js} +4 -4
  31. package/dist/{run-attempt-C5GTPJOE.js → run-attempt-P8BdxC1I.js} +1996 -5728
  32. package/dist/{runtime-artifact-C2ITXdhM.js → runtime-artifact-BVSPdd6g.js} +91 -40
  33. package/dist/{sandbox-guard-D1Wky__S.js → sandbox-guard-Cmwc9eIk.js} +10 -13
  34. package/dist/{session-binding-DlVQ-Pxs.js → session-binding-DPxIvMgE.js} +305 -271
  35. package/dist/{session-catalog-CP2oCcEb.js → session-catalog-xwNi_SDM.js} +418 -144
  36. package/dist/{session-cli-CqZ0Fp2a.js → session-cli-7hgXZDV7.js} +1 -1
  37. package/dist/session-retirement-DoMMJFKm.js +36 -0
  38. package/dist/{session-upstream-marker-QE-m5QFG.js → session-upstream-marker-CrIFX06J.js} +1 -1
  39. package/dist/{settled-turn-finalizer-CA_2QXIE.js → settled-turn-finalizer-BRWBO4MO.js} +36 -15
  40. package/dist/{shared-client-BVKE40c-.js → shared-client-kIBbGjk4.js} +721 -240
  41. package/dist/{side-question-CO12sHxo.js → side-question-9HAL26l9.js} +102 -53
  42. package/dist/{thread-lifecycle-DRg_FdzC.js → thread-lifecycle-Bu1BTDXr.js} +1355 -660
  43. package/dist/thread-ownership-6kOQHlyC.js +92 -0
  44. package/dist/thread-resume-CPrJNQVM.js +30 -0
  45. package/dist/{transcript-mirror-uKA-A4tB.js → transcript-mirror-B9gGgnJS.js} +202 -182
  46. package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DIImwDVS.js} +11 -0
  47. package/dist/upstream-prompt-provenance-ClRBije0.js +41 -0
  48. package/dist/{upstream-session-fork-_Vrz4WJr.js → upstream-session-fork-CE-_LdnP.js} +5 -5
  49. package/dist/{usage-UpVbdX5G.js → usage-CHlV0e-o.js} +3 -3
  50. package/dist/{web-search-provider.runtime-CaQMYDbp.js → web-search-provider.runtime-DRw2Vl42.js} +8 -9
  51. package/openclaw.plugin.json +18 -3
  52. package/package.json +6 -7
  53. package/dist/attempt-client-cleanup-Ia52yRWc.js +0 -127
  54. package/dist/conversation-control-DE7d9DOj.js +0 -287
  55. package/dist/event-projector-usage-tvgb1NCX.js +0 -69
  56. package/dist/notification-correlation-Bj_Ak_jI.js +0 -67
  57. package/dist/protocol-validators-Dm4eXZmt.js +0 -6337
  58. package/dist/realtime-voice-api-BPcA1uN9.js +0 -494
  59. package/dist/realtime-voice-api.js +0 -2
@@ -1,12 +1,14 @@
1
- import { D as ensureCodexAppServerClientRuntime, I as resolveCodexAppServerPreparedAuthHandoff, V as isJsonObject, a as getLeasedSharedCodexAppServerClient, c as releaseCodexAppServerClientLease, k as readRecentCodexRateLimits, m as withLeasedCodexAppServerClientStartSelectionRetry, y as isCodexAppServerApprovalRequest } from "./shared-client-BVKE40c-.js";
2
- import { D as resolveOpenClawExecPolicyForCodexAppServer, S as resolveCodexModelBackedReviewerPolicyContext, T as readCodexPluginConfig, b as canUseCodexModelBackedApprovalsReviewerForModel, l as sessionBindingIdentity, v as shouldAutoApproveCodexAppServerApprovals } from "./session-binding-DlVQ-Pxs.js";
3
- import { A as resolveCodexDynamicToolsLoading, C as readCodexSupportedReasoningEfforts, G as mergeCodexThreadConfigs, S as resolveReasoningEffort, T as filterCodexDynamicTools, V as buildCodexPluginAppsConfigPatchFromPolicyContext, _ as CODEX_NATIVE_PERSONALITY_NONE, f as buildCodexRuntimeThreadConfig, h as resolveCodexWebSearchPlan, v as resolveCodexAppServerModelProvider, x as resolveCodexBindingModelProviderFallback, y as resolveCodexAppServerRequestModelSelection } from "./thread-lifecycle-DRg_FdzC.js";
4
- import { a as assertCodexTurnStartResponse, l as readCodexTurn, n as assertCodexThreadForkResponse, o as readCodexDynamicToolCallParams } from "./protocol-validators-Dm4eXZmt.js";
5
- import { n as formatCodexUsageLimitErrorMessage } from "./rate-limits-S_PXs0ul.js";
6
- import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-BmDgseo_.js";
7
- import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-D1Wky__S.js";
8
- import { a as resolveCodexBindingAppServerConnection, i as requireCodexSupervisionModelSelection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-Bj_Ak_jI.js";
9
- import { C as CodexNativeToolLifecycleProjector, D as buildCodexNativeHookRelayDisabledConfig, E as buildCodexNativeHookRelayConfig, L as resolveDynamicToolCallTimeoutMs, N as handleDynamicToolCallWithTimeout, S as filterToolsForVisionInputs, U as resolveCodexToolAbortTerminalReason, _ as resolveCodexMessageToolProvider, a as emitDynamicToolStartedDiagnostic, c as resolveCodexProviderWebSearchSupportForClient, i as emitDynamicToolErrorDiagnostic, k as emitCodexNativePreToolUseFailureDiagnostic, n as handleCodexAppServerApprovalRequest, o as emitDynamicToolTerminalDiagnostic, r as handleCodexAppServerElicitationRequest, t as createCodexDynamicToolBridge, w as CODEX_NATIVE_HOOK_RELAY_EVENTS, y as shouldEnableCodexAppServerNativeToolSurface } from "./dynamic-tools-LIt9ojep.js";
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";
11
+ import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
10
12
  import { buildAgentHookContextChannelFields, embeddedAgentLog, formatErrorMessage, registerNativeHookRelay, resolveAgentDir, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
11
13
  import { randomUUID } from "node:crypto";
12
14
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
@@ -78,7 +80,8 @@ async function runCodexAppServerSideQuestion(params, options) {
78
80
  authProfileId: preparedRuntimeAuth.plan.forwardedAuthProfileId,
79
81
  authProfileStore: preparedRuntimeAuth.authProfileStore,
80
82
  agentDir: params.agentDir,
81
- ...pluginConfig.appServer?.homeScope ? { homeScope: pluginConfig.appServer.homeScope } : {},
83
+ homeScope: resolveCodexAppServerHomeScope({ appServer: pluginConfig.appServer }),
84
+ requirePreparedAuth: isCodexRemoteExecPlacementSandbox(params.sandbox),
82
85
  config: params.cfg,
83
86
  subscriptionProfileRequiredError: "Prepared Codex subscription route requires a scoped native OAuth or token profile.",
84
87
  subscriptionProfileUnusableError: `Prepared Codex auth profile "${preparedRuntimeAuth.plan.forwardedAuthProfileId}" is unusable.`
@@ -145,16 +148,25 @@ async function runCodexAppServerSideQuestion(params, options) {
145
148
  const sideRunParams = buildSideRunAttemptParams(effectiveParams, {
146
149
  cwd,
147
150
  authProfileId,
148
- runId
151
+ runId,
152
+ timeoutMs: appServer.requestTimeoutMs
153
+ });
154
+ const sandboxExecServerEnabled = isCodexSandboxExecServerEnabled(pluginConfig, params.sandbox);
155
+ const nativeToolSurfaceEnabled = shouldEnableCodexAppServerNativeToolSurface(sideRunParams, params.sandbox ?? void 0, { sandboxExecServerEnabled });
156
+ const sandboxEnvironmentRequired = shouldRequireCodexSandboxExecServerEnvironment({
157
+ sandbox: params.sandbox ?? void 0,
158
+ nativeToolSurfaceEnabled,
159
+ sandboxExecServerEnabled
149
160
  });
150
161
  const nativeExecutionBlock = resolveCodexNativeExecutionBlock({
151
162
  config: sideRunParams.config,
152
163
  sessionKey: sideRunParams.sandboxSessionKey?.trim() || sideRunParams.sessionKey,
153
164
  sessionId: sideRunParams.sessionId,
165
+ sandbox: params.sandbox,
166
+ sandboxEnvironmentSelected: sandboxEnvironmentRequired,
154
167
  surface: "/btw side-question mode"
155
168
  });
156
169
  if (nativeExecutionBlock) throw new Error(nativeExecutionBlock);
157
- const nativeToolSurfaceEnabled = shouldEnableCodexAppServerNativeToolSurface(sideRunParams);
158
170
  if (!nativeToolSurfaceEnabled) throw new Error("Codex-native /btw side-question mode is unavailable because the effective tool policy restricts Codex native tools for this session.");
159
171
  const clientOptions = {
160
172
  startOptions: appServer.start,
@@ -211,9 +223,31 @@ async function runCodexAppServerSideQuestion(params, options) {
211
223
  else params.opts?.abortSignal?.addEventListener("abort", abortFromUpstream, { once: true });
212
224
  let childThreadId;
213
225
  let turnId;
226
+ let sandboxEnvironment;
227
+ let sandboxEnvironmentClient;
214
228
  let removeRequestHandler;
215
229
  let nativeHookRelay;
216
230
  const activeDynamicToolCalls = /* @__PURE__ */ new Set();
231
+ const releaseSandboxEnvironment = async () => {
232
+ if (!sandboxEnvironment) return;
233
+ sandboxEnvironment = void 0;
234
+ sandboxEnvironmentClient = void 0;
235
+ await releaseCodexSandboxExecServerEnvironment(params.sandbox);
236
+ };
237
+ const ensureSandboxEnvironment = async (targetClient) => {
238
+ if (!sandboxEnvironmentRequired || sandboxEnvironmentClient === targetClient) return;
239
+ await releaseSandboxEnvironment();
240
+ const environment = await ensureCodexSandboxExecServerEnvironment({
241
+ client: targetClient,
242
+ sandbox: params.sandbox ?? null,
243
+ appServerStartOptions: appServer.start,
244
+ timeoutMs: appServer.requestTimeoutMs,
245
+ signal: runAbortController.signal
246
+ });
247
+ if (!environment) throw new Error("Codex app-server did not register an OpenClaw sandbox exec-server environment.");
248
+ sandboxEnvironment = environment;
249
+ sandboxEnvironmentClient = targetClient;
250
+ };
217
251
  try {
218
252
  const modelScopedAppServer = resolveCodexAppServerForModelProvider({
219
253
  appServer,
@@ -367,6 +401,7 @@ async function runCodexAppServerSideQuestion(params, options) {
367
401
  completionTimeoutMs: Math.max(appServer.turnCompletionIdleTimeoutMs, SIDE_QUESTION_COMPLETION_TIMEOUT_MS),
368
402
  loopDetectionPreToolUseRelay: appServer.loopDetectionPreToolUseRelay,
369
403
  signal: runAbortController.signal,
404
+ hostCapabilities: sideRunParams.hostCapabilities,
370
405
  onPreToolUseFailure: (failure) => {
371
406
  if (nativePreToolUseFailureFallbackActive) emitNativePreToolUseFailure(failure);
372
407
  else if (nativeToolLifecycleProjector) nativeToolLifecycleProjector.recordPreToolUseFailure(failure, nativeToolRunWasAbortedBeforeCleanup);
@@ -389,20 +424,24 @@ async function runCodexAppServerSideQuestion(params, options) {
389
424
  lease: clientLease,
390
425
  options: clientOptions,
391
426
  signal: params.opts?.abortSignal,
392
- run: async (forkClient, requestOptions) => await forkCodexSideThread(forkClient, {
393
- threadId: binding.threadId,
394
- model: modelSelection.model,
395
- ...modelSelection.modelProvider ? { modelProvider: modelSelection.modelProvider } : {},
396
- cwd,
397
- approvalPolicy,
398
- approvalsReviewer: modelScopedAppServer.approvalsReviewer,
399
- ...modelScopedAppServer.networkProxy ? {} : { sandbox },
400
- ...serviceTier ? { serviceTier } : {},
401
- config: threadConfig,
402
- developerInstructions: SIDE_DEVELOPER_INSTRUCTIONS,
403
- ephemeral: true,
404
- threadSource: "user"
405
- }, requestOptions),
427
+ run: async (forkClient, requestOptions) => {
428
+ await ensureSandboxEnvironment(forkClient);
429
+ const executionCwd = sandboxEnvironment?.cwd ?? cwd;
430
+ return await forkCodexSideThread(forkClient, {
431
+ threadId: binding.threadId,
432
+ model: modelSelection.model,
433
+ ...modelSelection.modelProvider ? { modelProvider: modelSelection.modelProvider } : {},
434
+ cwd: executionCwd,
435
+ approvalPolicy,
436
+ approvalsReviewer: modelScopedAppServer.approvalsReviewer,
437
+ ...sandboxEnvironment || modelScopedAppServer.networkProxy ? {} : { sandbox },
438
+ ...serviceTier ? { serviceTier } : {},
439
+ config: threadConfig,
440
+ developerInstructions: SIDE_DEVELOPER_INSTRUCTIONS,
441
+ ephemeral: true,
442
+ threadSource: "user"
443
+ }, requestOptions);
444
+ },
406
445
  onClientChange: rebindClientHandlers
407
446
  }));
408
447
  childThreadId = forkResponse.thread.id;
@@ -422,7 +461,11 @@ async function runCodexAppServerSideQuestion(params, options) {
422
461
  text: params.question.trim(),
423
462
  text_elements: []
424
463
  }],
425
- cwd,
464
+ ...sandboxEnvironment ? {
465
+ cwd: sandboxEnvironment.cwd,
466
+ sandboxPolicy: resolveCodexExternalSandboxPolicyForOpenClawSandbox(params.sandbox ?? void 0),
467
+ environments: resolveCodexSandboxEnvironmentSelection(sandboxEnvironment, nativeToolSurfaceEnabled)
468
+ } : { cwd },
426
469
  model: modelSelection.model,
427
470
  ...usesSupervisionConnection ? {} : { personality: CODEX_NATIVE_PERSONALITY_NONE },
428
471
  ...serviceTier ? { serviceTier } : {},
@@ -440,6 +483,9 @@ async function runCodexAppServerSideQuestion(params, options) {
440
483
  }, {
441
484
  timeoutMs: appServer.requestTimeoutMs,
442
485
  signal: params.opts?.abortSignal
486
+ }).catch((error) => {
487
+ if (isCodexAppServerIndeterminateRequestCancellationError(error)) turnId = "";
488
+ throw error;
443
489
  })).turn.id;
444
490
  collector.setTurn(childThreadId, turnId);
445
491
  nativeToolLifecycleProjector = new CodexNativeToolLifecycleProjector({
@@ -488,8 +534,12 @@ async function runCodexAppServerSideQuestion(params, options) {
488
534
  }
489
535
  } finally {
490
536
  flushPendingNativePreToolUseFailures();
491
- releaseCodexAppServerClientLease(clientLease);
492
- nativeHookRelay?.unregister();
537
+ try {
538
+ await releaseSandboxEnvironment();
539
+ } finally {
540
+ releaseCodexAppServerClientLease(clientLease);
541
+ nativeHookRelay?.unregister();
542
+ }
493
543
  }
494
544
  }
495
545
  }
@@ -515,6 +565,8 @@ function registerCodexSideNativeHookRelay(params) {
515
565
  completionTimeoutMs: params.completionTimeoutMs
516
566
  }),
517
567
  signal: params.signal,
568
+ runBeforeToolCall: params.hostCapabilities.runBeforeToolCall,
569
+ assertActive: params.hostCapabilities.assertActive,
518
570
  onPreToolUseFailure: params.onPreToolUseFailure,
519
571
  command: { timeoutMs: params.options.gatewayTimeoutMs }
520
572
  });
@@ -535,6 +587,8 @@ function buildSideRunAttemptParams(params, options) {
535
587
  id: params.model,
536
588
  provider: params.provider
537
589
  },
590
+ prompt: params.question,
591
+ timeoutMs: options.timeoutMs,
538
592
  sessionId: params.sessionId,
539
593
  sessionFile: params.sessionFile,
540
594
  sessionKey: params.sessionKey,
@@ -575,7 +629,9 @@ function buildSideRunAttemptParams(params, options) {
575
629
  if (event.stream === "approval") params.opts?.onApprovalEvent?.(event.data);
576
630
  },
577
631
  onBlockReply: params.opts?.onBlockReply,
578
- onPartialReply: params.opts?.onPartialReply
632
+ onPartialReply: params.opts?.onPartialReply,
633
+ hostCapabilities: params.hostCapabilities,
634
+ sandbox: params.sandbox
579
635
  };
580
636
  }
581
637
  async function createCodexSideToolBridge(input) {
@@ -588,7 +644,7 @@ async function createCodexSideToolBridge(input) {
588
644
  if (supportsModelTools(runtimeModel)) {
589
645
  const createOpenClawCodingTools = (await import("openclaw/plugin-sdk/agent-harness")).createOpenClawCodingTools;
590
646
  const sandboxSessionKey = input.params.sandboxSessionKey?.trim() || input.params.sessionKey?.trim() || input.params.sessionId || input.sessionAgentId;
591
- const sandbox = await resolveSandboxContext({
647
+ const sandbox = input.params.sandbox !== void 0 ? input.params.sandbox : await resolveSandboxContext({
592
648
  config: input.params.cfg,
593
649
  sessionKey: sandboxSessionKey,
594
650
  workspaceDir: input.cwd
@@ -660,7 +716,7 @@ async function createCodexSideToolBridge(input) {
660
716
  config: input.params.cfg,
661
717
  webSearchAllowed: false
662
718
  }) : requestedWebSearchPlan;
663
- const exposedTools = tools.filter((tool) => tool.name !== "web_search" && tool.name !== "computer");
719
+ const exposedTools = input.params.hostCapabilities.bindToolSurface(tools.filter((tool) => tool.name !== "web_search" && tool.name !== "computer"), { cwd: input.cwd });
664
720
  const hookChannelFields = buildAgentHookContextChannelFields({
665
721
  sessionKey: input.params.sessionKey,
666
722
  messageChannel: input.params.messageChannel,
@@ -716,19 +772,22 @@ function sideBoundaryPromptItem() {
716
772
  }
717
773
  async function cleanupCodexSideThread(client, params) {
718
774
  if (!params.threadId) return;
719
- if (params.interrupt && params.turnId) try {
775
+ if (params.interrupt && params.turnId !== void 0) try {
720
776
  await client.request("turn/interrupt", {
721
777
  threadId: params.threadId,
722
778
  turnId: params.turnId
723
779
  }, { timeoutMs: params.timeoutMs });
724
780
  } catch (error) {
725
- embeddedAgentLog.debug("codex /btw side thread interrupt cleanup failed", { error });
726
- }
727
- try {
728
- await client.request("thread/unsubscribe", { threadId: params.threadId }, { timeoutMs: params.timeoutMs });
729
- } catch (error) {
730
- embeddedAgentLog.debug("codex /btw side thread unsubscribe cleanup failed", { error });
781
+ if (!isCodexAlreadyTerminalInterruptError(error)) {
782
+ embeddedAgentLog.debug("codex /btw side thread interrupt cleanup failed", { error });
783
+ await retireUnsafeCodexTurnClientBestEffort(client, "side turn interrupt");
784
+ return;
785
+ }
731
786
  }
787
+ if (!await unsubscribeCodexThreadBestEffort(client, {
788
+ threadId: params.threadId,
789
+ timeoutMs: params.timeoutMs
790
+ })) await retireUnsafeCodexTurnClientBestEffort(client, "side thread unsubscribe");
732
791
  }
733
792
  var CodexSideQuestionCollector = class {
734
793
  constructor(params, readRecentRateLimits) {
@@ -753,7 +812,7 @@ var CodexSideQuestionCollector = class {
753
812
  this.pendingNotifications.push(notification);
754
813
  return;
755
814
  }
756
- if (!isNotificationForTurn(params, this.threadId, this.turnId)) return;
815
+ if (!isCodexNotificationForTurn(params, this.threadId, this.turnId)) return;
757
816
  if (notification.method === "item/agentMessage/delta") {
758
817
  this.appendAssistantDelta(params);
759
818
  return;
@@ -802,7 +861,7 @@ var CodexSideQuestionCollector = class {
802
861
  });
803
862
  }
804
863
  async appendAssistantDelta(params) {
805
- const delta = readString(params, "delta") ?? "";
864
+ const delta = readStringField(params, "delta") ?? "";
806
865
  if (!delta) return;
807
866
  if (!this.assistantStarted) {
808
867
  this.assistantStarted = true;
@@ -845,23 +904,13 @@ var CodexSideQuestionCollector = class {
845
904
  function collectAssistantText(turn) {
846
905
  return (turn.items ?? []).filter((item) => item.type === "agentMessage" && typeof item.text === "string").map((item) => item.text.trim()).filter(Boolean).at(-1) ?? "";
847
906
  }
848
- function isNotificationForTurn(params, threadId, turnId) {
849
- return readCodexNotificationThreadId(params) === threadId && readNotificationTurnId(params) === turnId;
850
- }
851
- function readNotificationTurnId(record) {
852
- return readCodexNotificationTurnId(record);
853
- }
854
- function readString(record, key) {
855
- const value = record[key];
856
- return typeof value === "string" ? value : void 0;
857
- }
858
907
  function formatCodexErrorMessage(params, rateLimits) {
859
908
  const error = isJsonObject(params.error) ? params.error : void 0;
860
909
  const message = formatCodexUsageLimitErrorMessage({
861
- message: error ? readString(error, "message") : void 0,
910
+ message: error ? readStringField(error, "message") : void 0,
862
911
  codexErrorInfo: error?.codexErrorInfo,
863
912
  rateLimits
864
- }) ?? (error ? readString(error, "message") ?? readString(error, "error") : void 0) ?? readString(params, "message") ?? "Codex /btw side thread failed.";
913
+ }) ?? (error ? readStringField(error, "message") ?? readStringField(error, "error") : void 0) ?? readStringField(params, "message") ?? "Codex /btw side thread failed.";
865
914
  return new Error(formatErrorMessage(message));
866
915
  }
867
916
  //#endregion