@openclaw/codex 2026.6.11 → 2026.6.34

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 (30) hide show
  1. package/dist/{app-server-policy-BPTiVNsW.js → app-server-policy-UdM9fipd.js} +2 -2
  2. package/dist/{attempt-notifications-BYnndyFl.js → attempt-notifications-Bzk6P-cp.js} +1 -1
  3. package/dist/{client-CLrtWgrD.js → client-DsqoRGhJ.js} +1 -1
  4. package/dist/{client-factory-Bm6HsGob.js → client-factory-E-67xUhS.js} +1 -1
  5. package/dist/{command-handlers-DEPTJYk0.js → command-handlers-BH6JevGQ.js} +9 -9
  6. package/dist/{compact-aQJ0ZKhe.js → compact-C-fHdAIB.js} +4 -4
  7. package/dist/{computer-use-ClrJwoFp.js → computer-use-XfHZnTBE.js} +3 -3
  8. package/dist/{config-CszD0vP3.js → config-DfV7hMHu.js} +23 -12
  9. package/dist/{conversation-binding-t0XMLz-j.js → conversation-binding-DrIWS5rX.js} +7 -7
  10. package/dist/harness.js +6 -6
  11. package/dist/index.js +12 -12
  12. package/dist/{media-understanding-provider-ZUQHN7gT.js → media-understanding-provider-5YQx83ng.js} +6 -6
  13. package/dist/media-understanding-provider.js +1 -1
  14. package/dist/{models-CAmfBWRl.js → models-B5oPkfmf.js} +2 -2
  15. package/dist/{plugin-app-cache-key-C9ILt7bl.js → plugin-app-cache-key-D5ckrLBm.js} +3 -3
  16. package/dist/{protocol-validators-B19q5BIX.js → protocol-validators-CB4mtyrs.js} +106 -12
  17. package/dist/{provider-B-OHpbD3.js → provider-CojmGiaW.js} +53 -18
  18. package/dist/{provider-capabilities-D7hnTO76.js → provider-capabilities-Cu8jJpp3.js} +326 -172
  19. package/dist/provider-catalog.js +72 -29
  20. package/dist/provider.js +2 -2
  21. package/dist/{request-Dcd452Nk.js → request-RiBbqNPj.js} +1 -1
  22. package/dist/{run-attempt-CXxtFC9d.js → run-attempt-Do5QKTZ-.js} +203 -325
  23. package/dist/{session-binding-HOuPt-E0.js → session-binding-CP5b8iN1.js} +1 -1
  24. package/dist/{shared-client-Dtx5i7Ez.js → shared-client-Ll9fWpy9.js} +2 -2
  25. package/dist/{side-question-C-DhgJOd.js → side-question-DUp0Z5_n.js} +12 -94
  26. package/dist/{thread-lifecycle-DtT3-ehU.js → thread-lifecycle-BDghpA0C.js} +14 -8
  27. package/dist/{web-search-provider.runtime-CkwxrXQj.js → web-search-provider.runtime-D-v5Y41V.js} +2 -2
  28. package/npm-shrinkwrap.json +30 -30
  29. package/openclaw.plugin.json +1 -1
  30. package/package.json +5 -5
@@ -1,21 +1,21 @@
1
1
  import { n as isJsonObject, t as flattenCodexDynamicToolFunctions } from "./protocol-dh-ETiNd.js";
2
- import { A as resolveCodexContextEngineProjectionReserveTokens, D as fitCodexProjectedContextForTurnStart, E as resolveCodexDynamicToolsLoadingForRuntime, H as readCodexNotificationTurnId, M as buildCodexPluginThreadConfigInputFingerprint, N as mergeCodexThreadConfigs, O as projectContextEngineAssemblyForCodex, P as shouldBuildCodexPluginThreadConfig, R as defaultCodexAppInventoryCache, V as readCodexNotificationThreadId, _ as resolveCodexWebSearchPlan, a as buildDeveloperInstructions, b as sanitizeCodexHistoryImagePayloads, c as codexDynamicToolsFingerprint, f as resolveCodexAppServerThreadModelSelection, h as startOrResumeThread, i as buildContextEngineBinding, j as buildCodexPluginThreadConfig, k as resolveCodexContextEngineProjectionMaxChars, l as isContextEngineBindingCompatible, n as areCodexDynamicToolFingerprintsCompatible, o as buildTurnCollaborationMode, s as buildTurnStartParams, v as isCodexAppServerProfilerEnabled, z as describeCodexNotificationCorrelation } from "./thread-lifecycle-DtT3-ehU.js";
3
- import { C as readCodexNotificationItem, D as updateActiveTurnItemIds, E as shouldDisarmAssistantCompletionIdleWatch, S as isTurnNotification, T as readRawResponseToolCallId, _ as isRawToolOutputCompletionNotification, a as isCodexNotificationOutsideActiveRun, b as isRetryableErrorNotification, c as isCurrentThreadOptionalTurnRequestParams, d as isNativeResponseStreamDeltaNotification, f as isNativeToolProgressNotification, g as isRawReasoningCompletionNotification, h as isRawFunctionToolOutputCompletionNotification, i as isAssistantCompletionReleaseNotification, l as isCurrentThreadTurnRequestParams, m as isRawAssistantProgressNotification, n as describeNotificationActivity, o as isCodexTurnAbortMarkerNotification, p as isPendingOpenClawDynamicToolCompletionNotification, r as isAssistantCommentaryCompletionNotification, s as isCurrentApprovalTurnRequestParams, t as codexExecutionToolName, u as isFileChangePatchUpdatedNotification, v as isReasoningItemCompletionNotification, w as readNotificationItemId, x as isTerminalTurnStatus, y as isReasoningProgressNotification } from "./attempt-notifications-BYnndyFl.js";
4
- import { _ as withMcpElicitationsApprovalPolicy, a as isCodexAppServerApprovalPolicyAllowedByRequirements, d as resolveCodexAppServerRuntimeOptions, f as resolveCodexComputerUseConfig, g as shouldAutoApproveCodexAppServerApprovals, h as resolveOpenClawExecPolicyForCodexAppServer, m as resolveCodexPluginsPolicy, p as resolveCodexModelBackedReviewerPolicyContext, s as isCodexSandboxExecServerEnabled, u as readCodexPluginConfig } from "./config-CszD0vP3.js";
5
- import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-B19q5BIX.js";
6
- import { i as formatCodexUsageLimitErrorMessage, o as resolveCodexUsageLimitResetAtMs, s as shouldRefreshCodexRateLimitsForUsageLimitMessage } from "./provider-B-OHpbD3.js";
7
- import { a as isCodexAppServerConnectionClosedError, i as isCodexAppServerApprovalRequest, n as CodexAppServerRpcError, r as compareCodexAppServerVersions, s as MIN_CODEX_SANDBOX_EXEC_SERVER_APP_SERVER_VERSION } from "./client-CLrtWgrD.js";
8
- import { i as isCodexAppServerNativeAuthProfile, l as writeCodexAppServerBinding, n as clearCodexAppServerBinding, o as readCodexAppServerBinding, r as clearCodexAppServerBindingForThread } from "./session-binding-HOuPt-E0.js";
9
- import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS, t as buildCodexAppServerRuntimeFingerprint } from "./plugin-app-cache-key-C9ILt7bl.js";
10
- import { a as formatCodexDisplayText, n as resolveCodexAppServerForOpenClawToolPolicy, t as resolveCodexAppServerForModelProvider } from "./app-server-policy-BPTiVNsW.js";
11
- import { d as resolveCodexAppServerAuthAccountCacheKey, f as resolveCodexAppServerAuthProfileId, h as resolveCodexAppServerHomeDir, m as resolveCodexAppServerFallbackApiKeyCacheKey, n as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, o as releaseLeasedSharedCodexAppServerClient, p as resolveCodexAppServerAuthProfileIdForAgent, s as retireSharedCodexAppServerClientIfCurrent, t as clearSharedCodexAppServerClientIfCurrent, u as refreshCodexAppServerAuthTokens } from "./shared-client-Dtx5i7Ez.js";
12
- import { t as defaultLeasedCodexAppServerClientFactory } from "./client-factory-Bm6HsGob.js";
13
- import { A as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, C as resolveCodexMessageToolProvider, D as shouldWarnCodexDynamicToolBuildStageSummary, E as shouldRequireCodexSandboxExecServerEnvironment, F as resolveCodexTurnTerminalIdleTimeoutMs, I as withCodexStartupTimeout, M as resolveCodexStartupTimeoutMs, N as resolveCodexTurnAssistantCompletionIdleTimeoutMs, P as resolveCodexTurnCompletionIdleTimeoutMs, S as resolveCodexExternalSandboxPolicyForOpenClawSandbox, T as shouldEnableCodexAppServerNativeToolSurface, _ as createCodexDynamicToolBuildStageTracker, a as buildCodexNativeHookRelayConfig, b as resolveCodexAppServerExecutionCwd, c as resolveCodexNativeHookRelayEvents, d as handleCodexAppServerElicitationRequest, f as createCodexDynamicToolBridge, g as buildDynamicTools, h as emitDynamicToolTerminalDiagnostic, i as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, j as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, k as handleCodexAppServerApprovalRequest, l as resolveCodexNativeHookRelayTtlMs, m as emitDynamicToolStartedDiagnostic, o as buildCodexNativeHookRelayDisabledConfig, p as emitDynamicToolErrorDiagnostic, s as createCodexNativeHookRelay, t as resolveCodexProviderWebSearchSupport, u as scheduleCodexNativeHookRelayUnregister, v as disableCodexPluginThreadConfig, w as resolveCodexSandboxEnvironmentSelection, x as resolveCodexAppServerHookChannelId, y as formatCodexDynamicToolBuildStageSummary } from "./provider-capabilities-D7hnTO76.js";
14
- import { t as ensureCodexComputerUse } from "./computer-use-ClrJwoFp.js";
2
+ import { A as resolveCodexContextEngineProjectionReserveTokens, D as fitCodexProjectedContextForTurnStart, E as resolveCodexDynamicToolsLoadingForRuntime, H as readCodexNotificationTurnId, M as buildCodexPluginThreadConfigInputFingerprint, N as mergeCodexThreadConfigs, O as projectContextEngineAssemblyForCodex, P as shouldBuildCodexPluginThreadConfig, R as defaultCodexAppInventoryCache, V as readCodexNotificationThreadId, _ as resolveCodexWebSearchPlan, a as buildDeveloperInstructions, b as sanitizeCodexHistoryImagePayloads, c as codexDynamicToolsFingerprint, f as resolveCodexAppServerThreadModelSelection, h as startOrResumeThread, i as buildContextEngineBinding, j as buildCodexPluginThreadConfig, k as resolveCodexContextEngineProjectionMaxChars, l as isContextEngineBindingCompatible, n as areCodexDynamicToolFingerprintsCompatible, o as buildTurnCollaborationMode, s as buildTurnStartParams, v as isCodexAppServerProfilerEnabled, z as describeCodexNotificationCorrelation } from "./thread-lifecycle-BDghpA0C.js";
3
+ import { C as readCodexNotificationItem, D as updateActiveTurnItemIds, E as shouldDisarmAssistantCompletionIdleWatch, S as isTurnNotification, T as readRawResponseToolCallId, _ as isRawToolOutputCompletionNotification, a as isCodexNotificationOutsideActiveRun, b as isRetryableErrorNotification, c as isCurrentThreadOptionalTurnRequestParams, d as isNativeResponseStreamDeltaNotification, f as isNativeToolProgressNotification, g as isRawReasoningCompletionNotification, h as isRawFunctionToolOutputCompletionNotification, i as isAssistantCompletionReleaseNotification, l as isCurrentThreadTurnRequestParams, m as isRawAssistantProgressNotification, n as describeNotificationActivity, o as isCodexTurnAbortMarkerNotification, p as isPendingOpenClawDynamicToolCompletionNotification, r as isAssistantCommentaryCompletionNotification, s as isCurrentApprovalTurnRequestParams, t as codexExecutionToolName, u as isFileChangePatchUpdatedNotification, v as isReasoningItemCompletionNotification, w as readNotificationItemId, x as isTerminalTurnStatus, y as isReasoningProgressNotification } from "./attempt-notifications-Bzk6P-cp.js";
4
+ import { a as isCodexAppServerApprovalPolicyAllowedByRequirements, d as resolveCodexComputerUseConfig, f as resolveCodexModelBackedReviewerPolicyContext, g as withMcpElicitationsApprovalPolicy, h as shouldAutoApproveCodexAppServerApprovals, l as readCodexPluginConfig, m as resolveOpenClawExecPolicyForCodexAppServer, p as resolveCodexPluginsPolicy, s as isCodexSandboxExecServerEnabled, u as resolveCodexAppServerRuntimeOptions } from "./config-DfV7hMHu.js";
5
+ import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-CB4mtyrs.js";
6
+ import { l as resolveCodexUsageLimitResetAtMs, s as formatCodexUsageLimitErrorMessage, u as shouldRefreshCodexRateLimitsForUsageLimitMessage } from "./provider-CojmGiaW.js";
7
+ import { a as isCodexAppServerConnectionClosedError, i as isCodexAppServerApprovalRequest, n as CodexAppServerRpcError, r as compareCodexAppServerVersions, s as MIN_CODEX_SANDBOX_EXEC_SERVER_APP_SERVER_VERSION } from "./client-DsqoRGhJ.js";
8
+ import { i as isCodexAppServerNativeAuthProfile, l as writeCodexAppServerBinding, n as clearCodexAppServerBinding, o as readCodexAppServerBinding, r as clearCodexAppServerBindingForThread } from "./session-binding-CP5b8iN1.js";
9
+ import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS, t as buildCodexAppServerRuntimeFingerprint } from "./plugin-app-cache-key-D5ckrLBm.js";
10
+ import { a as formatCodexDisplayText, n as resolveCodexAppServerForOpenClawToolPolicy, t as resolveCodexAppServerForModelProvider } from "./app-server-policy-UdM9fipd.js";
11
+ import { d as resolveCodexAppServerAuthAccountCacheKey, f as resolveCodexAppServerAuthProfileId, h as resolveCodexAppServerHomeDir, m as resolveCodexAppServerFallbackApiKeyCacheKey, n as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, o as releaseLeasedSharedCodexAppServerClient, p as resolveCodexAppServerAuthProfileIdForAgent, s as retireSharedCodexAppServerClientIfCurrent, t as clearSharedCodexAppServerClientIfCurrent, u as refreshCodexAppServerAuthTokens } from "./shared-client-Ll9fWpy9.js";
12
+ import { t as defaultLeasedCodexAppServerClientFactory } from "./client-factory-E-67xUhS.js";
13
+ import { A as resolveCodexAppServerExecutionCwd, B as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, C as emitDynamicToolErrorDiagnostic, D as createCodexDynamicToolBuildStageTracker, E as buildDynamicTools, F as shouldEnableCodexAppServerNativeToolSurface, G as resolveCodexTurnTerminalIdleTimeoutMs, H as resolveCodexStartupTimeoutMs, I as shouldRequireCodexSandboxExecServerEnvironment, K as withCodexStartupTimeout, L as shouldWarnCodexDynamicToolBuildStageSummary, M as resolveCodexExternalSandboxPolicyForOpenClawSandbox, N as resolveCodexMessageToolProvider, O as disableCodexPluginThreadConfig, P as resolveCodexSandboxEnvironmentSelection, S as toCodexDynamicToolProtocolResponse, T as emitDynamicToolTerminalDiagnostic, U as resolveCodexTurnAssistantCompletionIdleTimeoutMs, V as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, W as resolveCodexTurnCompletionIdleTimeoutMs, _ as resolveDynamicToolCallTimeoutMs, a as buildCodexNativeHookRelayConfig, b as shouldReleaseTurnAfterTerminalDynamicTool, c as resolveCodexNativeHookRelayEvents, d as handleCodexAppServerElicitationRequest, f as createCodexDynamicToolBridge, g as isMatchingDynamicToolTerminalDiagnostic, h as isDynamicToolTerminalDiagnosticEvent, i as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, j as resolveCodexAppServerHookChannelId, k as formatCodexDynamicToolBuildStageSummary, l as resolveCodexNativeHookRelayTtlMs, m as hasPendingDynamicToolTerminalDiagnostic, o as buildCodexNativeHookRelayDisabledConfig, p as handleDynamicToolCallWithTimeout, s as createCodexNativeHookRelay, t as resolveCodexProviderWebSearchSupport, u as scheduleCodexNativeHookRelayUnregister, v as resolveTerminalDynamicToolBatchAction, w as emitDynamicToolStartedDiagnostic, x as toCodexDynamicToolProgressResponse, y as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, z as handleCodexAppServerApprovalRequest } from "./provider-capabilities-Cu8jJpp3.js";
14
+ import { t as ensureCodexComputerUse } from "./computer-use-XfHZnTBE.js";
15
15
  import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-C7qmZ0Jh.js";
16
16
  import fs from "node:fs/promises";
17
17
  import path, { posix } from "node:path";
18
- import { asDateTimestampMs, parseStrictNonNegativeInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
18
+ import { asDateTimestampMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
19
19
  import { asFiniteNumber, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
20
20
  import { createHash, randomUUID } from "node:crypto";
21
21
  import fsSync from "node:fs";
@@ -27,7 +27,7 @@ import { spawn } from "node:child_process";
27
27
  import { once } from "node:events";
28
28
  import { WebSocketServer } from "ws";
29
29
  import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
30
- import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, hasPendingInternalDiagnosticEvent, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
30
+ import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
31
31
  import { appendRegularFile, pathExists } from "openclaw/plugin-sdk/security-runtime";
32
32
  import { MESSAGE_TOOL_DELIVERY_HINTS } from "openclaw/plugin-sdk/message-tool-delivery-hints";
33
33
  import { buildSessionContext, migrateSessionEntries, parseSessionEntries } from "openclaw/plugin-sdk/agent-sessions";
@@ -147,6 +147,9 @@ async function retireCodexAppServerClientAfterTimedOutTurn(client, params) {
147
147
  * Reads OpenClaw session history for Codex transcript mirroring and sanitizes
148
148
  * image payloads before replaying messages into the app-server projector.
149
149
  */
150
+ function isMissingFileError(error) {
151
+ return Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
152
+ }
150
153
  /** Returns sanitized session-context messages for a Codex mirrored session file. */
151
154
  async function readCodexMirroredSessionHistoryMessages(target) {
152
155
  try {
@@ -159,7 +162,8 @@ async function readCodexMirroredSessionHistoryMessages(target) {
159
162
  return sanitizeCodexHistoryImagePayloads(buildSessionContext(entries.filter((entry) => {
160
163
  return entry !== null && typeof entry === "object" && !Array.isArray(entry) && entry.type !== "session";
161
164
  })).messages, "codex mirrored history");
162
- } catch {
165
+ } catch (error) {
166
+ if (isMissingFileError(error)) return [];
163
167
  return;
164
168
  }
165
169
  }
@@ -1619,16 +1623,31 @@ async function runStreamingSandboxHttpRequest(execServer, socket, requestId, par
1619
1623
  env: {},
1620
1624
  usePty: false
1621
1625
  });
1622
- const [command, ...args] = execSpec.argv;
1623
- if (!command) throw new Error("OpenClaw sandbox HTTP exec spec did not provide a command.");
1624
- const child = spawn(command, args, {
1625
- env: execSpec.env,
1626
- stdio: [
1627
- "pipe",
1628
- "pipe",
1629
- "pipe"
1630
- ]
1631
- });
1626
+ let child;
1627
+ try {
1628
+ const [command, ...args] = execSpec.argv;
1629
+ if (!command) throw new Error("OpenClaw sandbox HTTP exec spec did not provide a command.");
1630
+ child = spawn(command, args, {
1631
+ env: execSpec.env,
1632
+ stdio: [
1633
+ "pipe",
1634
+ "pipe",
1635
+ "pipe"
1636
+ ]
1637
+ });
1638
+ } catch (error) {
1639
+ try {
1640
+ await backend.finalizeExec?.({
1641
+ status: "failed",
1642
+ exitCode: null,
1643
+ timedOut: false,
1644
+ token: execSpec.finalizeToken
1645
+ });
1646
+ } catch (finalizeError) {
1647
+ embeddedAgentLog.warn("codex sandbox http/request finalize after start failure failed", { error: finalizeError });
1648
+ }
1649
+ throw error;
1650
+ }
1632
1651
  const abortOnSocketClose = () => child.kill("SIGTERM");
1633
1652
  socket.once("close", abortOnSocketClose);
1634
1653
  child.once("close", () => {
@@ -1651,6 +1670,7 @@ function readStreamingSandboxHttpResponse(params) {
1651
1670
  return new Promise((resolve, reject) => {
1652
1671
  let headerResolved = false;
1653
1672
  let failed = false;
1673
+ let childFailure = null;
1654
1674
  let lastBodySeq = 0;
1655
1675
  let stdoutBuffer = "";
1656
1676
  let stderr = "";
@@ -1720,10 +1740,16 @@ function readStreamingSandboxHttpResponse(params) {
1720
1740
  params.child.stderr.on("data", (chunk) => {
1721
1741
  stderr = `${stderr}${chunk.toString("utf8")}`.slice(-4096);
1722
1742
  });
1723
- params.child.once("error", (error) => fail(error.message, null));
1743
+ params.child.once("error", (error) => {
1744
+ childFailure ??= error.message;
1745
+ });
1724
1746
  params.child.once("close", (code) => {
1725
1747
  const exitCode = code ?? 1;
1726
1748
  if (failed) return;
1749
+ if (childFailure) {
1750
+ fail(childFailure, exitCode);
1751
+ return;
1752
+ }
1727
1753
  if (exitCode === 0) {
1728
1754
  finalize("completed", exitCode).catch((error) => {
1729
1755
  embeddedAgentLog.warn("codex sandbox http/request finalize failed", { error });
@@ -2026,29 +2052,37 @@ async function runProcess(execServer, managed, params) {
2026
2052
  });
2027
2053
  managed.finalizeToken = execSpec.finalizeToken;
2028
2054
  managed.finalizeExec = backend.finalizeExec;
2029
- if (managed.abortController.signal.aborted) {
2030
- managed.failure = "process start cancelled";
2031
- await finalizeProcess(managed);
2032
- throw new Error("process start cancelled");
2033
- }
2034
- const [command, ...args] = execSpec.argv;
2035
- if (!command) throw new Error("OpenClaw sandbox exec spec did not provide a command.");
2036
- const child = spawn(command, args, {
2037
- env: execSpec.env,
2038
- stdio: [
2039
- "pipe",
2040
- "pipe",
2041
- "pipe"
2042
- ]
2043
- });
2055
+ let child;
2056
+ try {
2057
+ if (managed.abortController.signal.aborted) throw new Error("process start cancelled");
2058
+ const [command, ...args] = execSpec.argv;
2059
+ if (!command) throw new Error("OpenClaw sandbox exec spec did not provide a command.");
2060
+ child = spawn(command, args, {
2061
+ env: execSpec.env,
2062
+ stdio: [
2063
+ "pipe",
2064
+ "pipe",
2065
+ "pipe"
2066
+ ]
2067
+ });
2068
+ } catch (error) {
2069
+ managed.failure = error instanceof Error ? error.message : String(error);
2070
+ await finalizeProcess(managed).catch((finalizeError) => {
2071
+ embeddedAgentLog.warn("codex sandbox exec-server finalize after start failure failed", {
2072
+ processId: managed.processId,
2073
+ error: finalizeError instanceof Error ? finalizeError.message : String(finalizeError)
2074
+ });
2075
+ });
2076
+ throw error;
2077
+ }
2044
2078
  managed.child = child;
2045
2079
  const abortListener = () => child.kill("SIGTERM");
2046
2080
  managed.abortController.signal.addEventListener("abort", abortListener, { once: true });
2047
2081
  child.stdout.on("data", (chunk) => appendProcessChunk(managed, managed.tty ? "pty" : "stdout", chunk));
2048
2082
  child.stderr.on("data", (chunk) => appendProcessChunk(managed, "stderr", chunk));
2049
2083
  child.once("error", (error) => {
2050
- managed.failure = error.message;
2051
- emitProcessClosed(managed, null);
2084
+ managed.failure ??= error.message;
2085
+ notifyProcessWaiters(managed);
2052
2086
  });
2053
2087
  child.once("close", (code) => {
2054
2088
  managed.abortController.signal.removeEventListener("abort", abortListener);
@@ -3171,263 +3205,6 @@ function createCodexAttemptTurnWatchController(params) {
3171
3205
  clearAllTimers
3172
3206
  };
3173
3207
  }
3174
- /** Hard cap for per-call Codex dynamic tool timeout overrides. */
3175
- const CODEX_DYNAMIC_TOOL_MAX_TIMEOUT_MS = 6e5;
3176
- const CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS = 12e4;
3177
- /** Timeout for message-delivery dynamic tool calls. */
3178
- const CODEX_DYNAMIC_MESSAGE_TOOL_TIMEOUT_MS = 12e4;
3179
- const LOG_FIELD_MAX_LENGTH = 160;
3180
- function normalizeLogField(value) {
3181
- if (typeof value !== "string") return;
3182
- const normalized = value.replaceAll(String.fromCharCode(27), " ").replaceAll("\r", " ").replaceAll("\n", " ").replaceAll(" ", " ").trim();
3183
- if (!normalized) return;
3184
- return normalized.length > LOG_FIELD_MAX_LENGTH ? `${normalized.slice(0, LOG_FIELD_MAX_LENGTH - 3)}...` : normalized;
3185
- }
3186
- function readNumericTimeoutMs(value) {
3187
- if (typeof value === "number" && Number.isFinite(value)) return Math.max(0, Math.floor(value));
3188
- if (typeof value === "string") {
3189
- const parsed = parseStrictNonNegativeInteger(value);
3190
- if (parsed !== void 0) return Math.max(0, Math.floor(parsed));
3191
- }
3192
- }
3193
- function formatDynamicToolTimeoutDetails(params) {
3194
- const tool = normalizeLogField(params.call.tool) ?? "unknown";
3195
- const baseMeta = {
3196
- tool: params.call.tool,
3197
- toolCallId: params.call.callId,
3198
- threadId: params.call.threadId,
3199
- turnId: params.call.turnId,
3200
- timeoutMs: params.timeoutMs,
3201
- timeoutKind: "codex_dynamic_tool_rpc"
3202
- };
3203
- if (tool !== "process" || !isJsonObject(params.call.arguments)) return {
3204
- responseMessage: `OpenClaw dynamic tool call timed out after ${params.timeoutMs}ms while running tool ${tool}.`,
3205
- consoleMessage: `codex dynamic tool timeout: tool=${tool} toolTimeoutMs=${params.timeoutMs}; per-tool-call watchdog, not session idle`,
3206
- meta: baseMeta
3207
- };
3208
- const action = normalizeLogField(params.call.arguments.action);
3209
- const sessionId = normalizeLogField(params.call.arguments.sessionId);
3210
- const requestedTimeoutMs = readNumericTimeoutMs(params.call.arguments.timeout);
3211
- const actionPart = action ? ` action=${action}` : "";
3212
- const sessionPart = sessionId ? ` sessionId=${sessionId}` : "";
3213
- const requestedPart = requestedTimeoutMs === void 0 ? "" : ` requestedWaitMs=${requestedTimeoutMs}`;
3214
- const retryHint = action === "poll" ? "; repeated lines usually mean process-poll retry churn, not model progress" : "";
3215
- const responseTarget = action || sessionId ? ` while waiting for process${actionPart}${sessionPart}` : " while waiting for the process tool";
3216
- return {
3217
- responseMessage: `OpenClaw dynamic tool call timed out after ${params.timeoutMs}ms${responseTarget}. This is a tool RPC timeout, not a session idle timeout.`,
3218
- consoleMessage: `codex process tool timeout:${actionPart}${sessionPart} toolTimeoutMs=${params.timeoutMs}${requestedPart}; per-tool-call watchdog, not session idle${retryHint}`,
3219
- meta: {
3220
- ...baseMeta,
3221
- processAction: action,
3222
- processSessionId: sessionId,
3223
- processRequestedTimeoutMs: requestedTimeoutMs
3224
- }
3225
- };
3226
- }
3227
- /**
3228
- * Runs a dynamic tool call with run-abort and per-call timeout handling,
3229
- * returning a Codex protocol response instead of throwing.
3230
- */
3231
- async function handleDynamicToolCallWithTimeout(params) {
3232
- let didNotifyAgentToolResult = false;
3233
- const notifyAgentToolResult = (event) => {
3234
- if (didNotifyAgentToolResult) return;
3235
- didNotifyAgentToolResult = true;
3236
- try {
3237
- params.onAgentToolResult?.(event);
3238
- } catch (error) {
3239
- embeddedAgentLog.warn(`onAgentToolResult handler failed: tool=${params.call.tool} error=${String(error)}`);
3240
- }
3241
- };
3242
- const notifyFailedToolResult = (message) => {
3243
- notifyAgentToolResult({
3244
- toolName: params.call.tool,
3245
- result: {
3246
- content: [{
3247
- type: "text",
3248
- text: message
3249
- }],
3250
- details: {
3251
- status: "failed",
3252
- error: message
3253
- }
3254
- },
3255
- isError: true
3256
- });
3257
- };
3258
- if (params.signal.aborted) {
3259
- const message = "OpenClaw dynamic tool call aborted before execution.";
3260
- params.onFallbackSelected?.();
3261
- notifyFailedToolResult(message);
3262
- return failedDynamicToolResponse(message);
3263
- }
3264
- const controller = new AbortController();
3265
- let timeout;
3266
- let timedOut = false;
3267
- let resolveAbort;
3268
- const abortFromRun = () => {
3269
- const message = "OpenClaw dynamic tool call aborted.";
3270
- params.onFallbackSelected?.();
3271
- controller.abort(params.signal.reason ?? /* @__PURE__ */ new Error(message));
3272
- notifyFailedToolResult(message);
3273
- resolveAbort?.(failedDynamicToolResponse(message, { sideEffectEvidence: true }));
3274
- };
3275
- const abortPromise = new Promise((resolve) => {
3276
- resolveAbort = resolve;
3277
- });
3278
- const timeoutPromise = new Promise((resolve) => {
3279
- const timeoutMs = clampDynamicToolTimeoutMs(params.timeoutMs);
3280
- timeout = setTimeout(() => {
3281
- timedOut = true;
3282
- const timeoutDetails = formatDynamicToolTimeoutDetails({
3283
- call: params.call,
3284
- timeoutMs
3285
- });
3286
- params.onFallbackSelected?.();
3287
- controller.abort(new Error(timeoutDetails.responseMessage));
3288
- params.onTimeout?.();
3289
- embeddedAgentLog.warn("codex dynamic tool call timed out", {
3290
- ...timeoutDetails.meta,
3291
- consoleMessage: timeoutDetails.consoleMessage
3292
- });
3293
- notifyFailedToolResult(timeoutDetails.responseMessage);
3294
- resolve(failedDynamicToolResponse(timeoutDetails.responseMessage, { sideEffectEvidence: true }));
3295
- }, timeoutMs);
3296
- timeout.unref?.();
3297
- });
3298
- try {
3299
- params.signal.addEventListener("abort", abortFromRun, { once: true });
3300
- if (params.signal.aborted) abortFromRun();
3301
- const response = await Promise.race([
3302
- params.toolBridge.handleToolCall(params.call, {
3303
- signal: controller.signal,
3304
- onAgentToolResult: notifyAgentToolResult,
3305
- toolCallOrdinal: params.toolCallOrdinal
3306
- }),
3307
- abortPromise,
3308
- timeoutPromise
3309
- ]);
3310
- if (!response.success && !didNotifyAgentToolResult) notifyFailedToolResult(readDynamicToolResponseText(response));
3311
- return response;
3312
- } catch (error) {
3313
- const message = error instanceof Error ? error.message : String(error);
3314
- notifyFailedToolResult(message);
3315
- return failedDynamicToolResponse(message, { sideEffectEvidence: true });
3316
- } finally {
3317
- if (timeout) clearTimeout(timeout);
3318
- params.signal.removeEventListener("abort", abortFromRun);
3319
- resolveAbort = void 0;
3320
- if (!timedOut && !controller.signal.aborted) controller.abort(/* @__PURE__ */ new Error("OpenClaw dynamic tool call finished."));
3321
- }
3322
- }
3323
- function readDynamicToolResponseText(response) {
3324
- return response.contentItems.flatMap((item) => item.type === "inputText" && typeof item.text === "string" ? [item.text] : []).join("\n").trim() || "OpenClaw dynamic tool call failed.";
3325
- }
3326
- function failedDynamicToolResponse(message, options) {
3327
- const response = {
3328
- contentItems: [{
3329
- type: "inputText",
3330
- text: message
3331
- }],
3332
- success: false
3333
- };
3334
- Object.defineProperty(response, "diagnosticTerminalType", {
3335
- configurable: true,
3336
- enumerable: false,
3337
- value: "error"
3338
- });
3339
- if (options?.sideEffectEvidence === true) Object.defineProperty(response, "sideEffectEvidence", {
3340
- configurable: true,
3341
- enumerable: false,
3342
- value: true
3343
- });
3344
- return response;
3345
- }
3346
- /** Strips OpenClaw-only metadata before sending a dynamic tool response to Codex. */
3347
- function toCodexDynamicToolProtocolResponse(response) {
3348
- return {
3349
- contentItems: response.contentItems,
3350
- success: response.success
3351
- };
3352
- }
3353
- /** Adds async-started progress details when a tool result continues out of band. */
3354
- function toCodexDynamicToolProgressResponse(response, protocolResponse) {
3355
- if (response.asyncStarted !== true) return protocolResponse;
3356
- return {
3357
- ...protocolResponse,
3358
- details: {
3359
- async: true,
3360
- status: "started"
3361
- }
3362
- };
3363
- }
3364
- /** Decides whether a terminal dynamic tool response can release the Codex turn. */
3365
- function shouldReleaseTurnAfterTerminalDynamicTool(state) {
3366
- return !state.completed && !state.aborted && state.responseSuccess && !state.currentTurnHadNonTerminalDynamicToolResult && state.activeAppServerTurnRequests === 0 && state.activeTurnItemIdsCount === 0 && state.pendingOpenClawDynamicToolCompletionIdsCount === 0;
3367
- }
3368
- /** Returns true when a non-async result should block terminal-release shortcuts. */
3369
- function shouldBlockTerminalReleaseForNonTerminalDynamicToolResult(response) {
3370
- return response.asyncStarted !== true;
3371
- }
3372
- /** Resolves whether terminal diagnostic state should release, wait, or stay idle. */
3373
- function resolveTerminalDynamicToolBatchAction(state) {
3374
- if (state.activeAppServerTurnRequests > 0 || state.activeTurnItemIdsCount > 0 || state.pendingOpenClawDynamicToolCompletionIdsCount > 0) return "wait";
3375
- if (state.currentTurnHadNonTerminalDynamicToolResult) return "clear-nonterminal-batch";
3376
- if (state.hasPendingTerminalDynamicToolRelease) return "release-pending-terminal";
3377
- return "idle";
3378
- }
3379
- /** Returns true for diagnostic events that terminate a dynamic tool call. */
3380
- function isDynamicToolTerminalDiagnosticEvent(event) {
3381
- return event.type === "tool.execution.completed" || event.type === "tool.execution.error" || event.type === "tool.execution.blocked";
3382
- }
3383
- /** Matches terminal diagnostics to a specific dynamic tool call id/name. */
3384
- function isMatchingDynamicToolTerminalDiagnostic(params) {
3385
- if (params.event.toolCallId !== params.call.callId || params.event.toolName !== params.call.tool) return false;
3386
- if (params.runId !== void 0) return params.event.runId === params.runId;
3387
- if (params.sessionId !== void 0) return params.event.sessionId === params.sessionId;
3388
- if (params.sessionKey !== void 0) return params.event.sessionKey === params.sessionKey;
3389
- return params.event.runId === void 0 && params.event.sessionId === void 0 && params.event.sessionKey === void 0;
3390
- }
3391
- /** Checks pending diagnostics for a terminal event matching a tool call. */
3392
- function hasPendingDynamicToolTerminalDiagnostic(params) {
3393
- return hasPendingInternalDiagnosticEvent((event) => {
3394
- if (!isDynamicToolTerminalDiagnosticEvent(event)) return false;
3395
- return isMatchingDynamicToolTerminalDiagnostic({
3396
- event,
3397
- call: params.call,
3398
- runId: params.runId,
3399
- sessionId: params.sessionId,
3400
- sessionKey: params.sessionKey
3401
- });
3402
- });
3403
- }
3404
- /** Resolves per-tool timeout, applying media/message defaults and hard caps. */
3405
- function resolveDynamicToolCallTimeoutMs(params) {
3406
- return clampDynamicToolTimeoutMs(readDynamicToolCallTimeoutMs(params.call.arguments) ?? readConfiguredDynamicToolTimeoutMs(params.call.tool, params.config) ?? 9e4);
3407
- }
3408
- function readDynamicToolCallTimeoutMs(value) {
3409
- if (!isJsonObject(value)) return;
3410
- return readPositiveFiniteTimeoutMs(value.timeoutMs);
3411
- }
3412
- function readConfiguredDynamicToolTimeoutMs(toolName, config) {
3413
- if (toolName === "image_generate") {
3414
- const imageGenerationModel = config?.agents?.defaults?.imageGenerationModel;
3415
- if (!imageGenerationModel || typeof imageGenerationModel !== "object") return CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS;
3416
- return readPositiveFiniteTimeoutMs(imageGenerationModel.timeoutMs) ?? CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS;
3417
- }
3418
- if (toolName === "image") return readTimeoutSecondsAsMs(config?.tools?.media?.image?.timeoutSeconds) ?? 6e4;
3419
- if (toolName === "message") return CODEX_DYNAMIC_MESSAGE_TOOL_TIMEOUT_MS;
3420
- }
3421
- function readTimeoutSecondsAsMs(value) {
3422
- const seconds = readPositiveFiniteTimeoutMs(value);
3423
- return seconds === void 0 ? void 0 : seconds * 1e3;
3424
- }
3425
- function readPositiveFiniteTimeoutMs(value) {
3426
- return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : void 0;
3427
- }
3428
- function clampDynamicToolTimeoutMs(timeoutMs) {
3429
- return Math.max(1, Math.min(CODEX_DYNAMIC_TOOL_MAX_TIMEOUT_MS, Math.floor(timeoutMs)));
3430
- }
3431
3208
  //#endregion
3432
3209
  //#region extensions/codex/src/app-server/local-runtime-attribution.ts
3433
3210
  const OPENAI_PROVIDER_ID = "openai";
@@ -5724,7 +5501,14 @@ var CodexNativeSubagentTaskMirror = class {
5724
5501
  this.handleThreadStatusChanged(params);
5725
5502
  return;
5726
5503
  }
5727
- if (notification.method === "item/started" || notification.method === "item/completed") this.handleCollabAgentItem(params);
5504
+ if (notification.method === "item/started" || notification.method === "item/completed") {
5505
+ const item = isJsonObject(params.item) ? params.item : void 0;
5506
+ if (notification.method === "item/completed" && item && readString$3(item, "type") === "subAgentActivity") {
5507
+ this.handleSubagentActivityItem(params);
5508
+ return;
5509
+ }
5510
+ this.handleCollabAgentItem(params);
5511
+ }
5728
5512
  }
5729
5513
  handleThreadStarted(params) {
5730
5514
  const notification = readThreadStartedNotification(params);
@@ -5838,31 +5622,56 @@ var CodexNativeSubagentTaskMirror = class {
5838
5622
  this.applyCollabAgentStatus(threadId, toolCallStatus, state?.message);
5839
5623
  }
5840
5624
  }
5625
+ handleSubagentActivityItem(params) {
5626
+ const item = isJsonObject(params.item) ? params.item : void 0;
5627
+ if (!item || readString$3(item, "type") !== "subAgentActivity" || readString$3(params, "threadId") !== this.params.parentThreadId) return;
5628
+ const threadId = trimOptional(readString$3(item, "agentThreadId"));
5629
+ if (!threadId || normalizeSubagentActivityKind(readString$3(item, "kind")) !== "started") return;
5630
+ const agentPath = trimOptional(readString$3(item, "agentPath"));
5631
+ const eventAt = this.now();
5632
+ this.createRunningTask({
5633
+ threadId,
5634
+ label: "Codex subagent",
5635
+ task: agentPath ? `Codex native subagent ${agentPath}` : "Codex native subagent",
5636
+ startedAt: eventAt,
5637
+ progressSummary: "Codex native subagent started."
5638
+ });
5639
+ }
5841
5640
  createTaskFromCollabSpawnItem(threadId, item) {
5842
- const normalizedThreadId = threadId.trim();
5843
- if (!normalizedThreadId || this.mirroredThreadIds.has(normalizedThreadId)) return;
5844
- this.mirroredThreadIds.add(normalizedThreadId);
5845
5641
  const prompt = trimOptional(readString$3(item, "prompt"));
5846
- const runId = codexNativeSubagentRunId(normalizedThreadId);
5642
+ const eventAt = this.now();
5643
+ this.createRunningTask({
5644
+ threadId,
5645
+ label: "Codex subagent",
5646
+ task: prompt ?? "Codex native subagent",
5647
+ startedAt: eventAt,
5648
+ progressSummary: "Codex native subagent spawned."
5649
+ });
5650
+ }
5651
+ createRunningTask(params) {
5652
+ const threadId = params.threadId.trim();
5653
+ if (!threadId || this.mirroredThreadIds.has(threadId)) return;
5654
+ this.mirroredThreadIds.add(threadId);
5655
+ const runId = codexNativeSubagentRunId(threadId);
5847
5656
  const createdAt = this.now();
5848
5657
  if (!this.runtime.tryCreateRunningTaskRun({
5849
5658
  sourceId: runId,
5850
5659
  agentId: this.params.agentId,
5851
5660
  runId,
5852
- label: "Codex subagent",
5853
- task: prompt ?? "Codex native subagent",
5661
+ label: params.label,
5662
+ task: params.task,
5854
5663
  notifyPolicy: "silent",
5855
5664
  deliveryStatus: "not_applicable",
5856
5665
  preferMetadata: true,
5857
- startedAt: createdAt,
5666
+ startedAt: params.startedAt,
5858
5667
  lastEventAt: createdAt,
5859
- progressSummary: "Codex native subagent spawned."
5668
+ progressSummary: params.progressSummary
5860
5669
  })) {
5861
- this.mirroredThreadIds.delete(normalizedThreadId);
5862
- this.failedMirrorThreadIds.add(normalizedThreadId);
5670
+ this.mirroredThreadIds.delete(threadId);
5671
+ this.failedMirrorThreadIds.add(threadId);
5863
5672
  return;
5864
5673
  }
5865
- this.failedMirrorThreadIds.delete(normalizedThreadId);
5674
+ this.failedMirrorThreadIds.delete(threadId);
5866
5675
  this.terminalRunIds.delete(runId);
5867
5676
  this.authoritativeRunIds.delete(runId);
5868
5677
  }
@@ -5984,6 +5793,9 @@ function readNullableString(value, key) {
5984
5793
  function normalizeToolName$1(value) {
5985
5794
  return value?.replace(/[^a-z0-9]/giu, "").toLowerCase();
5986
5795
  }
5796
+ function normalizeSubagentActivityKind(value) {
5797
+ return value?.replace(/[^a-z]/giu, "").toLowerCase() === "started" ? "started" : void 0;
5798
+ }
5987
5799
  function normalizeCollabToolCallStatus(value) {
5988
5800
  const key = value?.replace(/[^a-z0-9]/giu, "").toLowerCase();
5989
5801
  if (key === "completed" || key === "succeeded" || key === "success") return "completed";
@@ -6065,6 +5877,7 @@ function registerCodexNativeSubagentMonitor(params) {
6065
5877
  taskRuntimeScope: params.taskRuntimeScope,
6066
5878
  agentId: params.agentId
6067
5879
  });
5880
+ return monitor;
6068
5881
  }
6069
5882
  /** Tracks native subagent thread notifications, transcript completions, and task delivery. */
6070
5883
  var CodexNativeSubagentMonitor = class {
@@ -6091,6 +5904,13 @@ var CodexNativeSubagentMonitor = class {
6091
5904
  this.childThreadIdsByAgentPath.clear();
6092
5905
  this.transcriptPathsByChildThreadId.clear();
6093
5906
  }
5907
+ deferUntilParentSettles(parentThreadId, callback) {
5908
+ const normalizedParentThreadId = parentThreadId.trim();
5909
+ const state = this.parentStates.get(normalizedParentThreadId);
5910
+ if (!state || !this.hasUnsettledChildren(normalizedParentThreadId)) return false;
5911
+ state.deferredSettlement = callback;
5912
+ return true;
5913
+ }
6094
5914
  configure(options) {
6095
5915
  const codexHome = normalizeOptionalString(options.codexHome);
6096
5916
  if (codexHome) this.codexHome = codexHome;
@@ -6128,10 +5948,29 @@ var CodexNativeSubagentMonitor = class {
6128
5948
  error: formatErrorMessage(error)
6129
5949
  });
6130
5950
  }
5951
+ this.markChildTurnStarted(notification);
5952
+ await this.handleChildSystemError(notification);
6131
5953
  this.captureChildAssistantMessage(notification);
6132
5954
  await this.handleChildTurnCompletion(notification);
6133
5955
  await this.handleCompletionNotification(notification);
6134
5956
  }
5957
+ markChildTurnStarted(notification) {
5958
+ if (notification.method !== "turn/started") return;
5959
+ const childThreadId = readString$2(isJsonObject(notification.params) ? notification.params : void 0, "threadId")?.trim();
5960
+ const childState = childThreadId ? this.childStates.get(childThreadId) : void 0;
5961
+ if (childState) childState.settledWithoutCompletion = false;
5962
+ }
5963
+ async handleChildSystemError(notification) {
5964
+ if (notification.method !== "thread/status/changed") return;
5965
+ const params = isJsonObject(notification.params) ? notification.params : void 0;
5966
+ if (readString$2(isJsonObject(params?.status) ? params.status : void 0, "type") !== "systemError") return;
5967
+ const childThreadId = readString$2(params, "threadId")?.trim();
5968
+ const childState = childThreadId ? this.childStates.get(childThreadId) : void 0;
5969
+ if (childState) {
5970
+ childState.settledWithoutCompletion = true;
5971
+ await this.flushDeferredParentSettlements(childState.parentThreadId);
5972
+ }
5973
+ }
6135
5974
  ensureParentTaskRuntime(state) {
6136
5975
  if (state.taskRuntime || !state.requesterSessionKey || !state.taskRuntimeScope) return;
6137
5976
  state.taskRuntime = this.runtime.createAgentHarnessTaskRuntime({
@@ -6168,6 +6007,12 @@ var CodexNativeSubagentMonitor = class {
6168
6007
  const parentThreadId = item ? (readString$2(item, "senderThreadId") ?? readString$2(params, "threadId"))?.trim() : void 0;
6169
6008
  const state = parentThreadId ? this.parentStates.get(parentThreadId) : void 0;
6170
6009
  if (state && parentThreadId) {
6010
+ if (notification.method === "item/completed" && readString$2(item, "type") === "subAgentActivity") {
6011
+ const childThreadId = readString$2(item, "agentThreadId")?.trim();
6012
+ const agentPath = readString$2(item, "agentPath");
6013
+ if (childThreadId) this.registerChildThread(parentThreadId, childThreadId, agentPath === void 0 ? {} : { agentPath });
6014
+ return state;
6015
+ }
6171
6016
  const childThreadIds = normalizeToolName(readString$2(item, "tool")) === "spawnagent" ? new Set([...readStringArray(item?.receiverThreadIds), ...readObjectStringKeys(item?.agentsStates)]) : new Set(readStringArray(item?.receiverThreadIds));
6172
6017
  for (const childThreadId of childThreadIds) this.registerChildThread(parentThreadId, childThreadId);
6173
6018
  }
@@ -6254,6 +6099,8 @@ var CodexNativeSubagentMonitor = class {
6254
6099
  if (childState && turn && readString$2(turn, "status") === "interrupted") {
6255
6100
  const turnId = readString$2(turn, "id");
6256
6101
  if (turnId) childState.assistantMessagesByTurn.delete(turnId);
6102
+ childState.settledWithoutCompletion = true;
6103
+ await this.flushDeferredParentSettlements(childState.parentThreadId);
6257
6104
  return;
6258
6105
  }
6259
6106
  if (childState && turn) this.captureChildTurnAssistantMessages(childState, turn);
@@ -6307,7 +6154,10 @@ var CodexNativeSubagentMonitor = class {
6307
6154
  childState.noFinalCompletionFallbackTimer = void 0;
6308
6155
  }
6309
6156
  }
6310
- if (!state.requesterSessionKey) return;
6157
+ if (!state.requesterSessionKey) {
6158
+ await this.flushDeferredParentSettlements(state.parentThreadId);
6159
+ return;
6160
+ }
6311
6161
  const completionKey = buildCompletionDedupeKey(state.parentThreadId, completion);
6312
6162
  if (state.deliveredCompletionKeys.has(completionKey)) return;
6313
6163
  const deliveryState = childState ?? this.ensureChildState(state.parentThreadId, completion.childThreadId);
@@ -6360,6 +6210,7 @@ var CodexNativeSubagentMonitor = class {
6360
6210
  });
6361
6211
  } finally {
6362
6212
  childState.deliveringCompletionKey = void 0;
6213
+ await this.flushDeferredParentSettlements(state.parentThreadId);
6363
6214
  }
6364
6215
  }
6365
6216
  markCompletionDeliveryPending(completion, error) {
@@ -6392,6 +6243,28 @@ var CodexNativeSubagentMonitor = class {
6392
6243
  }, delayMs);
6393
6244
  unrefTimer(childState.completionDeliveryTimer);
6394
6245
  }
6246
+ hasUnsettledChildren(parentThreadId) {
6247
+ for (const childState of this.childStates.values()) if (childState.parentThreadId === parentThreadId && (childState.pendingCompletion !== void 0 || childState.deliveringCompletionKey !== void 0 || !childState.transcriptTerminal && !childState.settledWithoutCompletion)) return true;
6248
+ return false;
6249
+ }
6250
+ async flushDeferredParentSettlements(parentThreadId) {
6251
+ if (this.hasUnsettledChildren(parentThreadId)) return;
6252
+ const state = this.parentStates.get(parentThreadId);
6253
+ const callback = state?.deferredSettlement;
6254
+ if (!state || !callback) return;
6255
+ state.deferredSettlement = void 0;
6256
+ await this.runDeferredParentSettlement(parentThreadId, callback);
6257
+ }
6258
+ async runDeferredParentSettlement(parentThreadId, callback) {
6259
+ try {
6260
+ await callback();
6261
+ } catch (error) {
6262
+ embeddedAgentLog.warn("Failed to finish deferred Codex app-server cleanup", {
6263
+ parentThreadId,
6264
+ error: formatErrorMessage(error)
6265
+ });
6266
+ }
6267
+ }
6395
6268
  finalizeCompletionTask(completion, eventAt) {
6396
6269
  const taskRuntime = this.getTaskRuntimeForChild(completion.childThreadId);
6397
6270
  if (!taskRuntime) return;
@@ -6432,7 +6305,8 @@ var CodexNativeSubagentMonitor = class {
6432
6305
  assistantMessagesByTurn: /* @__PURE__ */ new Map(),
6433
6306
  transcriptPollAttempt: 0,
6434
6307
  transcriptTerminal: false,
6435
- completionDeliveryAttempt: 0
6308
+ completionDeliveryAttempt: 0,
6309
+ settledWithoutCompletion: false
6436
6310
  };
6437
6311
  this.childStates.set(normalizedChildThreadId, childState);
6438
6312
  }
@@ -8374,6 +8248,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
8374
8248
  trajectoryEndRecorded = true;
8375
8249
  };
8376
8250
  let nativeHookRelay;
8251
+ const nativeSubagentMonitorRef = {};
8377
8252
  let releaseSharedClientLease;
8378
8253
  let sharedCodexClientRetiredForOneShotCleanup = false;
8379
8254
  const releaseSharedClientLeaseOnce = () => {
@@ -8546,7 +8421,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
8546
8421
  const turnCompletionIdleTimeoutMs = resolveCodexTurnCompletionIdleTimeoutMs(options.turnCompletionIdleTimeoutMs ?? appServer.turnCompletionIdleTimeoutMs);
8547
8422
  const turnAssistantCompletionIdleTimeoutMs = resolveCodexTurnAssistantCompletionIdleTimeoutMs(options.turnAssistantCompletionIdleTimeoutMs);
8548
8423
  const postToolRawAssistantCompletionIdleTimeoutMs = resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs(options.postToolRawAssistantCompletionIdleTimeoutMs ?? appServer.postToolRawAssistantCompletionIdleTimeoutMs, turnAssistantCompletionIdleTimeoutMs);
8549
- const turnTerminalIdleTimeoutMs = resolveCodexTurnTerminalIdleTimeoutMs(options.turnTerminalIdleTimeoutMs);
8424
+ const turnTerminalIdleTimeoutMs = resolveCodexTurnTerminalIdleTimeoutMs(options.turnTerminalIdleTimeoutMs, params.runTimeoutOverrideMs);
8550
8425
  const turnAttemptIdleTimeoutMs = Math.max(100, Math.floor(params.timeoutMs));
8551
8426
  let nativeHookRelayLastRenewedAt = 0;
8552
8427
  let activeAppServerTurnRequests = 0;
@@ -8888,7 +8763,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
8888
8763
  return notificationQueue;
8889
8764
  };
8890
8765
  const nativeSubagentCodexHome = appServer.start.transport === "stdio" ? appServer.start.env?.CODEX_HOME ?? resolveCodexAppServerHomeDir(agentDir) : void 0;
8891
- registerCodexNativeSubagentMonitor({
8766
+ nativeSubagentMonitorRef.current = registerCodexNativeSubagentMonitor({
8892
8767
  client,
8893
8768
  parentThreadId: thread.threadId,
8894
8769
  requesterSessionKey: params.sessionKey,
@@ -8955,9 +8830,6 @@ async function runCodexAppServerAttempt(params, options = {}) {
8955
8830
  threadId: thread.threadId,
8956
8831
  turnId,
8957
8832
  nativeHookRelay,
8958
- execPolicy,
8959
- execReviewerAgentId: sessionAgentId,
8960
- internalExecAutoReview: appServer.approvalsReviewer === "user",
8961
8833
  autoApprove: shouldAutoApproveCodexAppServerApprovals(appServer),
8962
8834
  signal: runAbortController.signal
8963
8835
  });
@@ -9506,11 +9378,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
9506
9378
  kind: "embedded",
9507
9379
  queueMessage: async (text, optionsLocal) => activeSteeringQueue.queue(text, optionsLocal),
9508
9380
  isStreaming: () => !completed && !runAbortController.signal.aborted,
9381
+ isAbortable: () => !completed && !runAbortController.signal.aborted,
9509
9382
  isCompacting: () => projectorRef.current?.isCompacting() ?? false,
9510
9383
  sourceReplyDeliveryMode: params.sourceReplyDeliveryMode,
9511
9384
  cancel: () => runAbortController.abort("cancelled"),
9512
9385
  abort: () => runAbortController.abort("aborted")
9513
9386
  };
9387
+ params.replyOperation?.attachBackend(handle);
9514
9388
  setActiveEmbeddedRun(params.sessionId, handle, params.sessionKey);
9515
9389
  const notifyUserMessagePersisted = createCodexAppServerUserMessagePersistenceNotifier(params);
9516
9390
  mirrorPromptAtTurnStartBestEffort({
@@ -9760,7 +9634,14 @@ async function runCodexAppServerAttempt(params, options = {}) {
9760
9634
  }
9761
9635
  });
9762
9636
  if (!timedOut && !runAbortController.signal.aborted) await steeringQueueRef.current?.flushPending();
9763
- if (!timedOut) await unsubscribeCodexThreadBestEffort(client, {
9637
+ const yieldedOneShotCleanupDeferred = !timedOut && params.cleanupBundleMcpOnRunEnd === true && yieldDetected && nativeSubagentMonitorRef.current?.deferUntilParentSettles(thread.threadId, async () => {
9638
+ await unsubscribeCodexThreadBestEffort(client, {
9639
+ threadId: thread.threadId,
9640
+ timeoutMs: 5e3
9641
+ });
9642
+ await releaseSharedClientLeaseAndRetireOneShotClient();
9643
+ });
9644
+ if (!timedOut && !yieldedOneShotCleanupDeferred) await unsubscribeCodexThreadBestEffort(client, {
9764
9645
  threadId: thread.threadId,
9765
9646
  timeoutMs: CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS
9766
9647
  });
@@ -9769,7 +9650,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
9769
9650
  notificationCleanup();
9770
9651
  requestCleanup();
9771
9652
  closeCleanup?.();
9772
- await releaseSharedClientLeaseAndRetireOneShotClient();
9653
+ if (!yieldedOneShotCleanupDeferred) await releaseSharedClientLeaseAndRetireOneShotClient();
9773
9654
  if (nativeHookRelay) if (shouldDelayNativeHookRelayUnregister) scheduleCodexNativeHookRelayUnregister({
9774
9655
  relay: nativeHookRelay,
9775
9656
  hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec
@@ -9892,9 +9773,6 @@ function handleApprovalRequest(params) {
9892
9773
  threadId: params.threadId,
9893
9774
  turnId: params.turnId,
9894
9775
  nativeHookRelay: params.nativeHookRelay,
9895
- execPolicy: params.execPolicy,
9896
- execReviewerAgentId: params.execReviewerAgentId,
9897
- internalExecAutoReview: params.internalExecAutoReview,
9898
9776
  autoApprove: params.autoApprove,
9899
9777
  signal: params.signal
9900
9778
  });