@openclaw/codex 2026.9.3 → 2026.9.5

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 (146) hide show
  1. package/assets/activity.svg +30 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/.setup/account-usage-runtime-C2MOIvfq.mjs +75 -0
  4. package/dist/{apply-B6el6hdO.js → .setup/apply-CJ0ZfmBG.mjs} +12 -13
  5. package/dist/.setup/async-questions-DdhOCwGi.mjs +27 -0
  6. package/dist/{attempt-client-cleanup-D6cR54TV.js → .setup/attempt-client-cleanup-BpYKdTA0.mjs} +30 -211
  7. package/dist/{attempt-context-AO4DSjE0.js → .setup/attempt-context-VXVwTCfS.mjs} +6 -6
  8. package/dist/.setup/attempt-terminal-gZrxQ35N.mjs +5 -0
  9. package/dist/{auth-binding-Co2Vfcf_.js → .setup/auth-binding-DhLWa_7K.mjs} +2 -2
  10. package/dist/{auth-cache-key-Kq6oerr6.js → .setup/auth-cache-key-QirmgiCo.mjs} +3 -3
  11. package/dist/{auth-profile-CwzO4_RG.js → .setup/auth-profile-WqZtZfXN.mjs} +1 -1
  12. package/dist/.setup/binding-connection-Bm38niE8.mjs +50 -0
  13. package/dist/.setup/binding-connection.runtime-CnRMC0ta.mjs +48 -0
  14. package/dist/{bounded-turn-lRpmZHFv.js → .setup/bounded-turn-BtlZcivC.mjs} +19 -14
  15. package/dist/{build-state-6RL6qohz.js → .setup/build-state-Xx9ybZqa.mjs} +1 -1
  16. package/dist/{capabilities-BeqLPbtM.js → .setup/capabilities-_vXcZGSx.mjs} +1 -1
  17. package/dist/{client-BEKu4yDx.js → .setup/client-vXs2929Q.mjs} +355 -164
  18. package/dist/{command-dispatch-CisT9Jqq.js → .setup/command-dispatch-naHIZwwF.mjs} +3 -3
  19. package/dist/{command-formatters-DeTfrapr.js → .setup/command-formatters-CGEkdawF.mjs} +4 -3
  20. package/dist/{command-handlers-BfIsJEuA.js → .setup/command-handlers-BtAJEW1X.mjs} +812 -152
  21. package/dist/{command-rpc-BMqRQOFX.js → .setup/command-rpc-DHFpn4le.mjs} +37 -21
  22. package/dist/{compact-CGJZ2rlb.js → .setup/compact-C3i3qlzj.mjs} +28 -43
  23. package/dist/{config-JDfTI4VI.js → .setup/config-CedDWjM-.mjs} +5 -4
  24. package/dist/{config-options-jnIFvwxD.js → .setup/config-options-BsanJ8QG.mjs} +9 -421
  25. package/dist/{protocol-CAAcVIKF.js → .setup/config-parsing-CcB9iPoq.mjs} +9 -51
  26. package/dist/{config-runtime-BWf6JLWG.js → .setup/config-runtime-CeAhl_h4.mjs} +2 -2
  27. package/dist/.setup/config-security-BRQ2mgW9.mjs +465 -0
  28. package/dist/{config-utils-C57JiJrU.js → .setup/config-utils-DujwEnhg.mjs} +2 -4
  29. package/dist/{conversation-binding-CxOlHiix.js → .setup/conversation-binding-DhzrpTM6.mjs} +60 -47
  30. package/dist/{conversation-binding-data-BiodpIzq.js → .setup/conversation-binding-data-CrcyZk6O.mjs} +1 -1
  31. package/dist/{conversation-control-CUCrSIQI.js → .setup/conversation-control-DN53ns41.mjs} +17 -13
  32. package/dist/.setup/cyber-failover-DYwbmf1o.mjs +123 -0
  33. package/dist/.setup/cyber-failover-notice-e9G3J9-e.mjs +17 -0
  34. package/dist/{dynamic-tools-D-JBoaLt.js → .setup/dynamic-tools-D16lOp67.mjs} +168 -61
  35. package/dist/{effective-mcp-catalog-J_5Ep5Um.js → .setup/effective-mcp-catalog-K6kLCN8X.mjs} +3 -3
  36. package/dist/{ephemeral-turn-DSwzP8YY.js → .setup/ephemeral-turn-R1gA8Sn6.mjs} +4 -5
  37. package/dist/{event-projector-assistant-message-BmBM4qBV.js → .setup/event-projector-assistant-message-DNUR1s0A.mjs} +6 -3
  38. package/dist/.setup/event-projector-items-DyTQ_XqL.mjs +200 -0
  39. package/dist/{attempt-notifications--H8zXR5-.js → .setup/event-projector-usage-C7Ntzs-f.mjs} +102 -9
  40. package/dist/{harness-FR6eQgyO.js → .setup/harness-rxaaoN-o.mjs} +90 -19
  41. package/dist/.setup/inference-context-fulhZuz8.mjs +94 -0
  42. package/dist/.setup/inference-proxy-CC15HuSi.mjs +311 -0
  43. package/dist/{isolated-completion-DHBefrzg.js → .setup/isolated-completion-B6srt48J.mjs} +7 -7
  44. package/dist/{launch-args-RXQwn8zV.js → .setup/launch-args-DnMak49W.mjs} +22 -1
  45. package/dist/{managed-binary-DrjjRRUD.js → .setup/managed-binary-DP6Rib3P.mjs} +11 -2
  46. package/dist/{managed-thread-store-D1t5jh3G.js → .setup/managed-thread-store-BMqgThVL.mjs} +48 -14
  47. package/dist/{model-catalog-B_6M04Wo.js → .setup/model-catalog-DkvUuBey.mjs} +35 -10
  48. package/dist/{models-P9k2qAof.js → .setup/models-BDFgm_G-.mjs} +3 -3
  49. package/dist/.setup/native-auth-BLZGqFjw.mjs +57 -0
  50. package/dist/.setup/native-subagent-history-YXaL6dMd.mjs +135 -0
  51. package/dist/.setup/native-subagent-monitor-B1hxzIOy.mjs +5031 -0
  52. package/dist/.setup/native-subagent-task-ids-DsuOonKv.mjs +411 -0
  53. package/dist/{node-cli-sessions-rj0ysJwM.js → .setup/node-cli-sessions-Cl8b2ZF3.mjs} +1 -1
  54. package/dist/{node-exec-server.runtime-BY_ctYnT.js → .setup/node-exec-server.runtime-BaViBKNz.mjs} +5 -5
  55. package/dist/{plan-BMJdMOEF.js → .setup/plan-xD7WKYTM.mjs} +331 -79
  56. package/dist/{plugin-activation-BQK-f5sV.js → .setup/plugin-activation-r8nq5Jzp.mjs} +24 -19
  57. package/dist/{plugin-app-cache-key-CdSQzWyX.js → .setup/plugin-app-cache-key-BOxKP7db.mjs} +29 -25
  58. package/dist/{plugin-approval-roundtrip-DeW95wB5.js → .setup/plugin-approval-roundtrip-CjfzafAZ.mjs} +1 -1
  59. package/dist/{plugin-inventory-CoRCzWW4.js → .setup/plugin-inventory-DUle8DLz.mjs} +12 -8
  60. package/dist/{plugin-marketplace-discovery-3akBizzF.js → .setup/plugin-marketplace-discovery-P-Vndfqq.mjs} +18 -15
  61. package/dist/{plugin-metadata-cache-DgNfRAGA.js → .setup/plugin-metadata-cache-DsS5buNa.mjs} +33 -14
  62. package/dist/{provider-capabilities-W4tfK5Y5.js → .setup/provider-capabilities-B8J4Dy-O.mjs} +2 -2
  63. package/dist/.setup/provider-fFh_-VR3.mjs +50 -0
  64. package/dist/{rate-limits-Bqnx1N4z.js → .setup/rate-limits-DOEGYRNs.mjs} +90 -46
  65. package/dist/.setup/request-BioXJLYa.mjs +292 -0
  66. package/dist/.setup/run-attempt-lifecycle-B7JbY4-F.mjs +71 -0
  67. package/dist/{run-attempt-DwKds3DN.js → .setup/run-attempt-rlA07pUv.mjs} +644 -491
  68. package/dist/{runtime-artifact-T-NwqeSH.js → .setup/runtime-artifact-Dy38Z5iU.mjs} +2 -2
  69. package/dist/{sandbox-guard-BcT66fWy.js → .setup/sandbox-guard-BBP-RbTf.mjs} +4 -3
  70. package/dist/{session-binding-CKSepwIC.js → .setup/session-binding-_0W_fHRr.mjs} +45 -63
  71. package/dist/{session-binding-record-CaZjYwNS.js → .setup/session-binding-record-TH3xA0zj.mjs} +181 -3
  72. package/dist/.setup/session-binding-sidecars-CKYEcfNn.mjs +543 -0
  73. package/dist/{session-catalog-adoption-BKLtSrwi.js → .setup/session-catalog-adoption-CR_whkEW.mjs} +6 -6
  74. package/dist/{session-catalog-archive-D0i2pGj2.js → .setup/session-catalog-archive-CwZaPacf.mjs} +6 -6
  75. package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +250 -0
  76. package/dist/.setup/session-catalog-fUdWDx-U.mjs +2464 -0
  77. package/dist/.setup/session-catalog-index-B141u15s.mjs +1070 -0
  78. package/dist/.setup/session-catalog-index-order-Cc5BzlQr.mjs +48 -0
  79. package/dist/.setup/session-catalog-index-state-BAuDztHN.mjs +180 -0
  80. package/dist/{session-catalog-parsing-CdD3JhdM.js → .setup/session-catalog-native-projection-ChV3cCtm.mjs} +213 -21
  81. package/dist/{session-catalog-node-adoption-BUuDYY8R.js → .setup/session-catalog-node-adoption-BVRsYOSh.mjs} +3 -3
  82. package/dist/{session-catalog-node-continue-CBtc4wkI.js → .setup/session-catalog-node-continue-Dowv8osw.mjs} +7 -7
  83. package/dist/.setup/session-catalog-projection-C1Bj9Jl-.mjs +414 -0
  84. package/dist/{session-cli-CbgaHh0f.js → .setup/session-cli-DIj-IE-E.mjs} +4 -4
  85. package/dist/{session-history-Cz-tOOYj.js → .setup/session-history-C--SrLI8.mjs} +10 -5
  86. package/dist/{session-history-import-DFN7sWRU.js → .setup/session-history-import-JHXT5Xfi.mjs} +4 -4
  87. package/dist/{session-history-read-cxPUxyVV.js → .setup/session-history-read-B3ZfSUbF.mjs} +2 -2
  88. package/dist/{session-history.worker-CNEvGaU5.js → .setup/session-history.worker-CpNj7H_P.mjs} +192 -89
  89. package/dist/{session-initialization-Jo86C60I.js → .setup/session-initialization-DH1z6fXn.mjs} +2 -2
  90. package/dist/{session-permission-policy-B22InTp_.js → .setup/session-permission-policy-DhurXY0l.mjs} +2 -2
  91. package/dist/{session-retirement-BSNG_mhf.js → .setup/session-retirement-CU87AOg9.mjs} +6 -6
  92. package/dist/{settled-turn-context-Du6gdUDd.js → .setup/settled-turn-context-fmwouT5I.mjs} +2 -2
  93. package/dist/{settled-turn-finalizer-BuLUrZl2.js → .setup/settled-turn-finalizer-CiY2bLFK.mjs} +10 -10
  94. package/dist/{shared-client-CVhez2Uo.js → .setup/shared-client-BpTtuLQ5.mjs} +495 -156
  95. package/dist/{side-question-DLbr2vUU.js → .setup/side-question-DSCZyoBD.mjs} +64 -47
  96. package/dist/{source-Da-h6f7e.js → .setup/source-Bjp4UQij.mjs} +15 -14
  97. package/dist/{thread-archive-guard-D1bP04Tf.js → .setup/thread-archive-guard-jmecf6OJ.mjs} +1 -1
  98. package/dist/.setup/thread-history-page-BTx-4xsg.mjs +83 -0
  99. package/dist/{thread-lifecycle-D1pzRwHB.js → .setup/thread-lifecycle-Cik28qWn.mjs} +330 -150
  100. package/dist/{thread-ownership-D6oASVRu.js → .setup/thread-ownership-skomxnIt.mjs} +4 -4
  101. package/dist/{thread-policy-D8kI7yAO.js → .setup/thread-policy-Cjs4B8xf.mjs} +3 -3
  102. package/dist/{thread-resume-T5cveyxA.js → .setup/thread-resume-BkNpj9Pz.mjs} +8 -5
  103. package/dist/.setup/timeout-DZF05XrR.mjs +63 -0
  104. package/dist/{session-catalog-home-id-D7-aLiNt.js → .setup/transcript-history-projection-DHNBDhCU.mjs} +73 -20
  105. package/dist/{transcript-mirror-t5TOccct.js → .setup/transcript-mirror-D4qp_leP.mjs} +15 -6
  106. package/dist/{transcript-mirror-attestation-DibE0krH.js → .setup/transcript-mirror-attestation-CzM-94NC.mjs} +4 -1
  107. package/dist/{transport-stdio-BGjHoYLr.js → .setup/transport-stdio-Cmx94Oiy.mjs} +149 -44
  108. package/dist/{upstream-session-fork-De-sLJ2r.js → .setup/upstream-session-fork-D3UKxgVD.mjs} +27 -26
  109. package/dist/{usage-CPPTmBvZ.js → .setup/usage-BOgBEKso.mjs} +4 -4
  110. package/dist/.setup/usage-limit-error-C0ow7DOc.mjs +166 -0
  111. package/dist/{version-omm6IPI3.js → .setup/version-CoqzXPgK.mjs} +1 -1
  112. package/dist/{web-search-provider.runtime-CSVgQL0w.js → .setup/web-search-provider.runtime-CTGuJt6i.mjs} +3 -3
  113. package/dist/api.js +28 -20
  114. package/dist/cli-metadata.js +1 -1
  115. package/dist/doctor-contract-api.js +8 -528
  116. package/dist/harness.js +1 -1
  117. package/dist/index.js +130 -135
  118. package/dist/media-understanding-provider.js +3 -3
  119. package/dist/migration-provider-api.js +2 -0
  120. package/dist/native-tool-policy.js +12 -0
  121. package/dist/provider-discovery.js +18 -0
  122. package/dist/session-history-worker-runtime.js +23 -5
  123. package/dist/session-history.worker.js +2 -2
  124. package/dist/web-search-contract-api.js +1 -1
  125. package/openclaw.plugin.json +354 -68
  126. package/package.json +11 -8
  127. package/dist/binding-connection-QqgcPCgk.js +0 -60
  128. package/dist/event-projector-usage-CIyrYYid.js +0 -102
  129. package/dist/native-subagent-monitor-BbCUKRwC.js +0 -3350
  130. package/dist/request-CGvGOpeR.js +0 -198
  131. package/dist/session-catalog-HaDcp7Sv.js +0 -1533
  132. package/dist/session-catalog-provenance-DkJHo735.js +0 -124
  133. package/dist/timeout-BVw8aaM1.js +0 -33
  134. package/dist/{auth-profile-selection-DFu9e167.js → .setup/auth-profile-selection-DFu9e167.mjs} +0 -0
  135. package/dist/{context-compaction-activity-CMla5FPJ.js → .setup/context-compaction-activity-CMla5FPJ.mjs} +0 -0
  136. package/dist/{elicitation-input-DPoK8F7w.js → .setup/elicitation-input-DPoK8F7w.mjs} +0 -0
  137. package/dist/{history-rejection-B4nOXNXF.js → .setup/history-rejection-B4nOXNXF.mjs} +0 -0
  138. package/dist/{image-payload-sanitizer-tupAr-2o.js → .setup/image-payload-sanitizer-tupAr-2o.mjs} +0 -0
  139. package/dist/{incognito-session-uhrBF6wJ.js → .setup/incognito-session-uhrBF6wJ.mjs} +0 -0
  140. package/dist/{local-runtime-attribution-B_2mnqhb.js → .setup/local-runtime-attribution-B_2mnqhb.mjs} +0 -0
  141. package/dist/{native-execution-policy-umd0tgh4.js → .setup/native-execution-policy-YBMHSzC4.mjs} +1 -1
  142. /package/dist/{rolldown-runtime-8H4AJuhK.js → .setup/rolldown-runtime-8H4AJuhK.mjs} +0 -0
  143. /package/dist/{session-binding-meta-B7aEMU7g.js → .setup/session-binding-meta-B7aEMU7g.mjs} +0 -0
  144. /package/dist/{session-upstream-marker-D15C9NHp.js → .setup/session-upstream-marker-D15C9NHp.mjs} +0 -0
  145. /package/dist/{upstream-prompt-provenance-LphB8slG.js → .setup/upstream-prompt-provenance-LphB8slG.mjs} +0 -0
  146. /package/dist/{web-search-provider.shared-BrZmlqyR.js → .setup/web-search-provider.shared-BrZmlqyR.mjs} +0 -0
@@ -1,59 +1,64 @@
1
- import { l as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced } from "./session-binding-record-CaZjYwNS.js";
2
- import { n as defineCodexBuildState } from "./build-state-6RL6qohz.js";
3
- import { b as readCodexRequirementsToml, c as hasCodexMcpToolApprovalOverrides, d as withMcpElicitationsApprovalPolicy, i as resolveCodexAppServerHomeScope, m as resolveCodexModelBackedReviewerPolicyContext, o as resolveCodexComputerUseConfig, u as shouldAutoApproveCodexAppServerApprovals } from "./config-options-jnIFvwxD.js";
4
- import { S as resolveCodexPluginsPolicy, a as flattenCodexDynamicToolFunctions, b as isCodexSandboxExecServerEnabled, o as isJsonObject, s as resolveCodexAppServerHomeDir, v as isCodexPairedNodeRemoteExecPlacementSandbox, x as readCodexPluginConfig, y as isCodexRemoteExecPlacementSandbox } from "./protocol-CAAcVIKF.js";
5
- import { A as isMatchingDynamicToolTerminalDiagnostic, D as handleDynamicToolCallWithTimeout, E as createCodexElicitationResponse, F as toCodexDynamicToolProgressResponse, I as toCodexDynamicToolProtocolResponse, L as resolveCodexToolAbortTerminalReason, M as resolveTerminalDynamicToolBatchAction, N as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, O as hasPendingDynamicToolTerminalDiagnostic, P as shouldReleaseTurnAfterTerminalDynamicTool, S as readCodexDynamicToolCallParams, T as readCodexTurnCompletedNotification, a as isCodexAppServerBrokenPipeError, c as isCodexAppServerIndeterminateTransportError, d as isCodexAppServerRequestTimeoutError, i as isCodexAppServerApprovalRequest, j as resolveDynamicToolCallTimeoutMs, k as isDynamicToolTerminalDiagnosticEvent, l as isCodexAppServerOverloadError, o as isCodexAppServerConnectionClosedError, p as resolveCodexAppServerClientInstanceId, r as getCodexAppServerClientInstanceId, s as isCodexAppServerIndeterminateRequestCancellationError, w as readCodexTurn, x as assertCodexTurnStartResponse } from "./client-BEKu4yDx.js";
6
- import { c as resolveCodexAppServerPreparedApiKeyCacheKey, m as retireSharedCodexAppServerClientIfCurrent, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-Kq6oerr6.js";
7
- import { t as isIncognitoSessionKey } from "./incognito-session-uhrBF6wJ.js";
8
- import { a as shouldRefreshCodexRateLimitsForUsageLimitMessage, i as resolveCodexUsageLimitResetAtMs, n as formatCodexUsageLimitErrorMessage } from "./rate-limits-Bqnx1N4z.js";
9
- import { a as formatCodexDisplayText } from "./command-formatters-DeTfrapr.js";
10
- import { r as CodexAppServerRpcError } from "./session-catalog-provenance-DkJHo735.js";
11
- import { t as CODEX_CONTROL_METHODS } from "./capabilities-BeqLPbtM.js";
12
- import { r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.js";
13
- import { n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey, s as defaultCodexAppInventoryCache } from "./plugin-app-cache-key-CdSQzWyX.js";
14
- import { t as withAbortableTimeout } from "./timeout-BVw8aaM1.js";
15
- import { n as resolveOpenClawExecPolicyForCodexAppServer, t as canUseCodexModelBackedApprovalsReviewerForModel } from "./config-JDfTI4VI.js";
16
- import { o as hasCodexMirrorOrigin, t as applyCodexTranscriptTaint } from "./transcript-mirror-attestation-DibE0krH.js";
17
- import { n as prepareCodexAppServerAuthBinding } from "./auth-binding-Co2Vfcf_.js";
18
- import { i as resolveCodexBindingAppServerConnection, t as assertCodexSessionRuntimeOwnership } from "./binding-connection-QqgcPCgk.js";
19
- import { i as resolveCodexAppServerAuthProfileIdForAgent, r as resolveCodexAppServerAuthProfileId } from "./auth-profile-CwzO4_RG.js";
20
- import { B as prepareCodexWorkspaceReferences, D as TURN_FINALIZE_DRAIN_ABORT_GRACE_MS, E as CodexAppServerStartupError, F as ensureCodexAppServerClientRuntime, J as rememberCodexRateLimitsRead, K as readCodexRateLimitsRevision, M as withCodexStartupTimeout, O as TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS, V as protectCodexAppServerLiveThread, X as resolveCodexAppServerAuthAccountCacheKey, Z as resolveCodexAppServerPreparedAuthHandoff, a as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, c as getLeasedSharedCodexAppServerClient, f as readCodexAppServerClientDesktopGenerationFingerprint, h as releaseLeasedSharedCodexAppServerClient, i as clearSharedCodexAppServerClientIfCurrent, j as resolveCodexStartupTimeoutMs, k as isCodexAppServerStartupError, l as getSharedCodexAppServerClient, q as readRecentCodexRateLimits, s as createIsolatedCodexAppServerClient, u as isCodexAppServerStartSelectionChangedError, v as retainSharedCodexAppServerClientIfCurrent } from "./shared-client-CVhez2Uo.js";
21
- import { F as readCodexProviderRefusal, H as readNullableString, L as readItem, M as extractRawAssistantText, O as matchesCodexSnapshotTurn, P as readCodexErrorNotificationMessage, R as readItemString, U as splitPlanText, V as readNonNegativeInteger, a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, f as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, g as readCodexNotificationThreadId, h as isCodexNotificationForTurn, k as shouldClearTerminalPresentationForNativeItem, l as retireUnsafeCodexTurnClientBestEffort, m as CodexProjectionDiagnostics, o as interruptCodexTurnAndWaitBestEffort, p as getCodexAppServerTurnRouter, r as CodexAppServerUnsafeSubscriptionError, u as terminateCodexBackgroundTerminals } from "./attempt-client-cleanup-D6cR54TV.js";
22
- import { a as isRawFunctionToolOutputCompletionNotification, c as readNotificationItemId, i as isPendingOpenClawDynamicToolCompletionNotification, l as readRawResponseToolCallId, o as isTerminalTurnStatus, r as isCodexTurnAbortMarkerNotification, s as readCodexNotificationItem, t as codexExecutionToolName, u as updateActiveTurnItemIds } from "./attempt-notifications--H8zXR5-.js";
23
- import { t as CodexUsageProjection } from "./event-projector-usage-CIyrYYid.js";
24
- import { s as resolveRecoverableCodexPluginConfigKeys } from "./plugin-inventory-CoRCzWW4.js";
25
- import { $ as codexLegacyDynamicToolsFingerprint, A as readCodexMcpToolConnectorId, B as emitCodexNativePreToolUseFailureDiagnostic, C as buildDeveloperInstructions, Ct as buildCodexPluginThreadConfigTimeoutFallback, D as resolveCodexAppServerThreadModelSelection, Dt as shouldBuildCodexPluginThreadConfig, H as resolveCodexNativeHookRelayTtlMs, I as buildCodexNativeHookRelayConfig, K as hasCodexNativeToolCatalog, L as buildCodexNativeHookRelayDisabledConfig, M as isCodexAppServerProfilerEnabled, P as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, Q as codexDynamicToolsFingerprint, S as resolveCodexWebSearchPlan, St as buildCodexPluginThreadConfigInputFingerprint, Tt as mergeCodexThreadConfigs, U as scheduleCodexNativeHookRelayUnregister, V as resolveCodexNativeHookRelayEvents, _t as projectContextEngineAssemblyForCodex, bt as resolveCodexContinuityProjectionMaxChars, c as assertScheduledCodexAppAuthorityRuntime, d as buildScheduledCodexAppServerConnectionIdentity, f as captureScheduledCodexAppAuthority, ft as CodexContextAttachmentError, gt as neutralizeCodexExplicitMentionSigils, h as resolveScheduledCodexAppCreatorCaptureDecision, ht as isCodexDurableCustomMessage, i as buildCodexUserInput, j as readCodexMcpToolUiVisibility, l as buildLegacyScheduledCodexAppRecoveryPrompt, lt as resolveCodexDynamicToolsLoadingForRuntime, m as readCurrentCodexScheduledAppPolicy$1, mt as fitCodexProjectedContextForTurnStart, n as buildTurnCollaborationMode, nt as filterCodexDynamicTools, ot as isSystemAgentOnlyCodexDynamicToolAllowlist, p as intersectCodexPluginThreadConfigWithScheduledAuthority, pt as buildCodexContinuityCalibration, q as loadCodexNativeToolCatalog, r as buildTurnStartParams, s as startOrResumeThread, u as buildScheduledCodexAppAuthorityInputFingerprint, ut as buildContextEngineBinding, vt as resolveCodexContextEngineProjectionMaxChars, xt as buildCodexPluginThreadConfig, yt as resolveCodexContextEngineProjectionReserveTokens, z as createCodexNativeHookRelay } from "./thread-lifecycle-D1pzRwHB.js";
26
- import { a as resolveCodexRunSessionBindingAuthority, n as createCodexSessionGenerationSupersededError, o as resolveCodexSessionBinding, s as scopeCodexRunBindingStore } from "./session-binding-CKSepwIC.js";
27
- import { n as CodexThreadPolicyHandoffError } from "./thread-policy-D8kI7yAO.js";
28
- import { r as retainCodexAppServerBindingSubscription } from "./thread-ownership-D6oASVRu.js";
29
- import { i as mirrorPromptAtTurnStartBestEffort, n as createCodexAppServerUserMessagePersistenceNotifier, o as buildCodexUserPromptMessage, s as promptSnapshot, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-t5TOccct.js";
30
- import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.js";
31
- import { i as createAssistantReasoningMessage, n as createAssistantCommentaryMessage, r as createAssistantMessage, t as createAssistantAsyncMessage } from "./event-projector-assistant-message-BmBM4qBV.js";
32
- import { C as shouldRequireCodexSandboxExecServerEnvironment, S as shouldEnableCodexAppServerNativeToolSurface, _ as resolveCodexAppServerHookChannelId, a as emitDynamicToolStartedDiagnostic, c as ensureCodexSandboxExecServerEnvironment, d as CodexNativeToolLifecycleProjector, f as buildDynamicTools, g as resolveCodexAppServerExecutionCwd, h as formatCodexDynamicToolBuildStageSummary, i as emitDynamicToolErrorDiagnostic, l as releaseCodexSandboxExecServerEnvironment, m as disableCodexPluginThreadConfig, n as projectCodexExecutableDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as createCodexDynamicToolBuildStageTracker, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as readBoundedCodexRemoteWorkspaceFile, v as resolveCodexExternalSandboxPolicyForOpenClawSandbox, w as shouldWarnCodexDynamicToolBuildStageSummary, x as resolveCodexSandboxEnvironmentSelection, y as resolveCodexMessageToolProvider } from "./dynamic-tools-D-JBoaLt.js";
33
- import { t as resolveCodexProviderWebSearchSupport } from "./provider-capabilities-W4tfK5Y5.js";
34
- import { a as CodexToolProgressProjection, c as isCodexCommandBearingToolCall, d as sanitizeCodexToolResponse, i as CodexToolTranscriptProjection, l as resolveCodexToolProgressDetailMode, n as CodexEventProjection, o as shouldEmitTranscriptToolProgress, r as emitCodexAgentEvent, s as inferCodexDynamicToolMeta, t as codexNativeSubagentMonitorRuntime, u as sanitizeCodexToolArguments } from "./native-subagent-monitor-BbCUKRwC.js";
35
- import { a as requestPluginApprovalOutcome } from "./plugin-approval-roundtrip-DeW95wB5.js";
36
- import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy } from "./session-permission-policy-B22InTp_.js";
37
- import { a as getCodexWorkspaceMemoryToolNames, c as readContextEngineThreadBootstrapProjection, d as resolveCodexDeliveryHintPreservedInputRange, f as resolveContextEngineBootstrapProjectionDecision, i as buildCodexWorkspaceBootstrapContext, l as readMirroredSessionHistoryMessages, n as buildCodexSystemPromptReport, r as buildCodexWatchedSessionsContext, s as prependCodexOpenClawPromptContext, t as buildCodexOpenClawPromptContext, u as renderCodexSkillsCollaborationInstructions } from "./attempt-context-AO4DSjE0.js";
38
- import { n as captureCodexSettledTurnFinalizationContext } from "./settled-turn-context-Du6gdUDd.js";
39
- import { a as runCodexComputerUseLiveTest, n as ensureCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-DgNfRAGA.js";
1
+ import { s as resolveRecoverableCodexPluginConfigKeys } from "./plugin-inventory-DUle8DLz.mjs";
2
+ import { b as createCodexNativeSubagentHistoryOwner, i as matchesCodexNativeSubagentSubmissionBinding, n as assertCodexBindingMayBeReplaced, p as sessionBindingIdentity } from "./session-binding-record-TH3xA0zj.mjs";
3
+ import { n as defineCodexBuildState } from "./build-state-Xx9ybZqa.mjs";
4
+ import { E as readCodexRequirementsToml, h as resolveCodexAppServerHomeDir, l as shouldAutoApproveCodexAppServerApprovals, m as isJsonObject, n as hasCodexMcpToolApprovalOverrides, p as flattenCodexDynamicToolFunctions, u as withMcpElicitationsApprovalPolicy } from "./config-security-BRQ2mgW9.mjs";
5
+ import { c as isCodexPairedNodeRemoteExecPlacementSandbox, d as readCodexPluginConfig, f as resolveCodexPluginsPolicy, l as isCodexRemoteExecPlacementSandbox, u as isCodexSandboxExecServerEnabled } from "./config-parsing-CcB9iPoq.mjs";
6
+ import { A as isMatchingDynamicToolTerminalDiagnostic, D as handleDynamicToolCallWithTimeout, E as createCodexElicitationResponse, F as toCodexDynamicToolProgressResponse, I as toCodexDynamicToolProtocolResponse, L as resolveCodexToolAbortTerminalReason, M as resolveTerminalDynamicToolBatchAction, N as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, O as hasPendingDynamicToolTerminalDiagnostic, P as shouldReleaseTurnAfterTerminalDynamicTool, S as readCodexDynamicToolCallParams, T as readCodexTurnCompletedNotification, c as isCodexAppServerIndeterminateTransportError, i as isCodexAppServerApprovalRequest, j as resolveDynamicToolCallTimeoutMs, k as isDynamicToolTerminalDiagnosticEvent, o as isCodexAppServerConnectionClosedError, p as resolveCodexAppServerClientInstanceId, r as getCodexAppServerClientInstanceId, s as isCodexAppServerIndeterminateRequestCancellationError, w as readCodexTurn, x as assertCodexTurnStartResponse } from "./client-vXs2929Q.mjs";
7
+ import { i as resolveCodexAppServerHomeScope, l as resolveCodexModelBackedReviewerPolicyContext, o as resolveCodexComputerUseConfig } from "./config-options-BsanJ8QG.mjs";
8
+ import { c as resolveCodexAppServerPreparedApiKeyCacheKey, m as retireSharedCodexAppServerClientIfCurrent, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-QirmgiCo.mjs";
9
+ import { t as isIncognitoSessionKey } from "./incognito-session-uhrBF6wJ.mjs";
10
+ import { o as formatCodexDisplayText } from "./command-formatters-CGEkdawF.mjs";
11
+ import { i as CodexAppServerRpcError, t as withAbortableTimeout } from "./timeout-DZF05XrR.mjs";
12
+ import { t as readCodexAsyncQuestions } from "./async-questions-DdhOCwGi.mjs";
13
+ import { D as splitPlanText, E as readNullableString, S as readItemString, T as readNonNegativeInteger, d as matchesCodexSnapshotTurn, f as shouldClearTerminalPresentationForNativeItem, g as extractRawAssistantText, v as readCodexErrorNotificationMessage, x as readItem, y as readCodexProviderRefusal } from "./event-projector-items-DyTQ_XqL.mjs";
14
+ import { r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.mjs";
15
+ import { a as defaultCodexAppInventoryCache, n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-BOxKP7db.mjs";
16
+ import { i as resolveCodexBindingAppServerConnection, t as assertCodexSessionRuntimeOwnership } from "./binding-connection-Bm38niE8.mjs";
17
+ import { n as resolveOpenClawExecPolicyForCodexAppServer, t as canUseCodexModelBackedApprovalsReviewerForModel } from "./config-CedDWjM-.mjs";
18
+ import { o as hasCodexMirrorOrigin, t as applyCodexTranscriptTaint } from "./transcript-mirror-attestation-CzM-94NC.mjs";
19
+ import { i as resolveCodexAppServerAuthProfileIdForAgent, r as resolveCodexAppServerAuthProfileId } from "./auth-profile-WqZtZfXN.mjs";
20
+ import { r as prepareCodexAppServerAuthBinding } from "./auth-binding-DhLWa_7K.mjs";
21
+ import { A as getCodexInferenceThread, B as prepareCodexWorkspaceReferences, K as readCodexRateLimitsRevision, P as ensureCodexAppServerClientRuntime, V as protectCodexAppServerLiveThread, X as resolveCodexAppServerAuthAccountCacheKey, Z as resolveCodexAppServerPreparedAuthHandoff, a as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, at as resolveCodexStartupTimeoutMs, c as getLeasedSharedCodexAppServerClient, et as CodexAppServerStartupError, f as readCodexAppServerClientDesktopGenerationFingerprint, h as releaseLeasedSharedCodexAppServerClient, i as clearSharedCodexAppServerClientIfCurrent, l as getSharedCodexAppServerClient, nt as TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS, ot as withCodexStartupTimeout, q as readRecentCodexRateLimits, s as createIsolatedCodexAppServerClient, tt as TURN_FINALIZE_DRAIN_ABORT_GRACE_MS, u as isCodexAppServerStartSelectionChangedError, v as retainSharedCodexAppServerClientIfCurrent, w as CodexThreadClientReplacementError } from "./shared-client-BpTtuLQ5.mjs";
22
+ import { _ as CodexProjectionDiagnostics, a as closeCodexStartupClientBestEffort, d as terminateCodexBackgroundTerminals, f as unsubscribeCodexThreadBestEffort, g as waitForPromiseOrAbort, l as retireUnsafeCodexTurnClientBestEffort, m as getCodexAppServerTurnRouter, o as interruptCodexTurnAndWaitBestEffort, p as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, r as CodexAppServerUnsafeSubscriptionError, u as shouldRetireCodexStartupClient, v as isCodexNotificationForTurn, y as readCodexNotificationThreadId } from "./attempt-client-cleanup-BpYKdTA0.mjs";
23
+ import { a as isPendingOpenClawDynamicToolCompletionNotification, c as readCodexNotificationItem, d as updateActiveTurnItemIds, i as isCodexTurnAbortMarkerNotification, l as readNotificationItemId, o as isRawFunctionToolOutputCompletionNotification, r as codexExecutionToolName, s as isTerminalTurnStatus, t as CodexUsageProjection, u as readRawResponseToolCallId } from "./event-projector-usage-C7Ntzs-f.mjs";
24
+ import { At as shouldBuildCodexPluginThreadConfig, Ct as resolveCodexContinuityProjectionMaxChars, Et as buildCodexPluginThreadConfigTimeoutFallback, G as scheduleCodexNativeHookRelayUnregister, H as emitCodexNativePreToolUseFailureDiagnostic, I as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, J as hasCodexNativeToolCatalog, M as readCodexMcpToolUiVisibility, Ot as mergeCodexThreadConfigs, P as isCodexAppServerProfilerEnabled, R as buildCodexNativeHookRelayConfig, St as resolveCodexContextEngineProjectionReserveTokens, T as buildDeveloperInstructions, Tt as buildCodexPluginThreadConfigInputFingerprint, U as resolveCodexNativeHookRelayEvents, V as createCodexNativeHookRelay, W as resolveCodexNativeHookRelayTtlMs, Y as loadCodexNativeToolCatalog, _ as resolveScheduledCodexAppCreatorCaptureDecision, _t as fitCodexProjectedContextForTurnStart, a as buildTurnStartParams, bt as projectContextEngineAssemblyForCodex, ct as isSystemAgentOnlyCodexDynamicToolAllowlist, d as buildLegacyScheduledCodexAppRecoveryPrompt, dt as resolveCodexDynamicToolsLoadingForRuntime, et as codexDynamicToolsFingerprint, f as buildScheduledCodexAppAuthorityInputFingerprint, ft as buildContextEngineBinding, g as readCurrentCodexScheduledAppPolicy$1, gt as buildCodexContinuityCalibration, h as intersectCodexPluginThreadConfigWithScheduledAuthority, ht as CodexContextAttachmentError, i as buildTurnCollaborationMode, it as filterCodexDynamicTools, j as readCodexMcpToolConnectorId, k as resolveCodexAppServerThreadModelSelection, l as startOrResumeThread, m as captureScheduledCodexAppAuthority, mt as CODEX_TURN_START_TEXT_INPUT_MAX_CHARS, n as buildCodexParentLocalInstructions, o as buildCodexUserInput, p as buildScheduledCodexAppServerConnectionIdentity, t as buildCodexHistoryProvenancePrefix, tt as codexLegacyDynamicToolsFingerprint, u as assertScheduledCodexAppAuthorityRuntime, vt as isCodexDurableCustomMessage, w as resolveCodexWebSearchPlan, wt as buildCodexPluginThreadConfig, xt as resolveCodexContextEngineProjectionMaxChars, yt as neutralizeCodexExplicitMentionSigils, z as buildCodexNativeHookRelayDisabledConfig } from "./thread-lifecycle-Cik28qWn.mjs";
25
+ import { a as resolveCodexRunSessionBindingAuthority, n as createCodexSessionGenerationSupersededError, o as resolveCodexSessionBinding, s as scopeCodexRunBindingStore } from "./session-binding-_0W_fHRr.mjs";
26
+ import { n as CodexThreadPolicyHandoffError } from "./thread-policy-Cjs4B8xf.mjs";
27
+ import { r as retainCodexAppServerBindingSubscription, s as withExclusiveCodexAppServerThread, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-skomxnIt.mjs";
28
+ import { c as promptSnapshot, i as mirrorPromptAtTurnStartBestEffort, n as createCodexAppServerUserMessagePersistenceNotifier, o as buildCodexUserPromptMessage, s as buildResolvedCodexUserPromptMessage, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-D4qp_leP.mjs";
29
+ import { a as resolveCodexPromptError, i as refreshCodexUsageLimitPromptError, n as formatCodexTurnStartUsageLimitError, r as markCodexAuthProfileBlockedFromRateLimits, t as CodexUsageLimitPromptError } from "./usage-limit-error-C0ow7DOc.mjs";
30
+ import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.mjs";
31
+ import { t as attemptTerminal } from "./attempt-terminal-gZrxQ35N.mjs";
32
+ import { a as shouldKeepCodexSharedAbortOpen, i as runCodexAgentEndHook, n as ensureCodexWorkspaceDirOnce, o as withCodexAppServerFastModeServiceTier, r as estimateCodexAppServerProjectedTurnTokens, t as emitCodexAppServerEvent } from "./run-attempt-lifecycle-B7JbY4-F.mjs";
33
+ import { t as CODEX_INFERENCE_GENERATION_KEY } from "./inference-context-fulhZuz8.mjs";
34
+ import { i as createAssistantReasoningMessage, n as createAssistantCommentaryMessage, r as createAssistantMessage, t as createAssistantAsyncMessage } from "./event-projector-assistant-message-DNUR1s0A.mjs";
35
+ import { _ as inferCodexDynamicToolMeta, b as sanitizeCodexToolArguments, v as isCodexCommandBearingToolCall, x as sanitizeCodexToolResponse, y as resolveCodexToolProgressDetailMode } from "./native-subagent-task-ids-DsuOonKv.mjs";
36
+ import { C as shouldRequireCodexSandboxExecServerEnvironment, S as shouldEnableCodexAppServerNativeToolSurface, _ as resolveCodexAppServerHookChannelId, a as emitDynamicToolStartedDiagnostic, c as ensureCodexSandboxExecServerEnvironment, d as CodexNativeToolLifecycleProjector, f as buildDynamicTools, g as resolveCodexAppServerExecutionCwd, h as formatCodexDynamicToolBuildStageSummary, i as emitDynamicToolErrorDiagnostic, l as releaseCodexSandboxExecServerEnvironment, m as disableCodexPluginThreadConfig, n as projectCodexExecutableDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as createCodexDynamicToolBuildStageTracker, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as readBoundedCodexRemoteWorkspaceFile, v as resolveCodexExternalSandboxPolicyForOpenClawSandbox, w as shouldWarnCodexDynamicToolBuildStageSummary, x as resolveCodexSandboxEnvironmentSelection, y as resolveCodexMessageToolProvider } from "./dynamic-tools-D16lOp67.mjs";
37
+ import { t as resolveCodexProviderWebSearchSupport } from "./provider-capabilities-B8J4Dy-O.mjs";
38
+ import { a as requestPluginApprovalOutcome } from "./plugin-approval-roundtrip-CjfzafAZ.mjs";
39
+ import { a as CodexToolProgressProjection, i as CodexToolTranscriptProjection, n as CodexEventProjection, o as shouldEmitTranscriptToolProgress, r as emitCodexAgentEvent, t as codexNativeSubagentMonitorRuntime } from "./native-subagent-monitor-B1hxzIOy.mjs";
40
+ import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy } from "./session-permission-policy-DhurXY0l.mjs";
41
+ import { a as getCodexWorkspaceMemoryToolNames, c as readContextEngineThreadBootstrapProjection, d as resolveCodexDeliveryHintPreservedInputRange, f as resolveContextEngineBootstrapProjectionDecision, i as buildCodexWorkspaceBootstrapContext, l as readMirroredSessionHistoryMessages, n as buildCodexSystemPromptReport, r as buildCodexWatchedSessionsContext, s as prependCodexOpenClawPromptContext, t as buildCodexOpenClawPromptContext, u as renderCodexSkillsCollaborationInstructions } from "./attempt-context-VXVwTCfS.mjs";
42
+ import { n as captureCodexSettledTurnFinalizationContext } from "./settled-turn-context-fmwouT5I.mjs";
43
+ import { a as runCodexComputerUseLiveTest, n as ensureCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-DsS5buNa.mjs";
40
44
  import { asOptionalRecord, normalizeOptionalString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
41
45
  import { createHash } from "node:crypto";
46
+ import { isDeepStrictEqual } from "node:util";
42
47
  import { resolveAgentConfig, resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
43
48
  import { MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
44
49
  import path from "node:path";
45
50
  import fs from "node:fs/promises";
46
51
  import { addAbortListener } from "node:events";
47
52
  import { truncateUtf16Safe, truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
48
- import { Buffer as Buffer$1 } from "node:buffer";
53
+ import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
49
54
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
55
+ import { Buffer as Buffer$1 } from "node:buffer";
50
56
  import { isPathStrictlyInside, root } from "openclaw/plugin-sdk/file-access-runtime";
51
- import { isDeepStrictEqual } from "node:util";
52
- import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
53
- import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, agentHarnessAttemptTerminal, agentHarnessStructuredInput, assembleHarnessContextEngine, assertContextEngineHostSupport, awaitAgentEndSideEffects, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedForegroundPromptContext, buildHarnessContextEngineRuntimeContext, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, emitAgentEvent, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, hasBeforeToolCallPolicy, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, projectProgressCardChannelUpdate, resolveAgentDir as resolveAgentDir$2, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveAttemptFsWorkspaceOnly, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveUserPath, runAgentCleanupStep, runAgentEndSideEffects, runAgentHarnessAfterCompactionHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
57
+ import { resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
58
+ import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, agentHarnessStructuredInput, assembleHarnessContextEngine, assertContextEngineHostSupport, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedForegroundPromptContext, buildHarnessContextEngineRuntimeContext, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, hasBeforeToolCallPolicy, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, projectProgressCardChannelUpdate, resolveAgentDir as resolveAgentDir$2, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveAttemptFsWorkspaceOnly, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveUserPath, runAgentCleanupStep, runAgentHarnessAfterCompactionHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
54
59
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
55
- import { parseSqliteSessionFileMarker } from "openclaw/plugin-sdk/session-store-runtime";
56
- import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
60
+ import { getSessionEntry, parseSqliteSessionFileMarker } from "openclaw/plugin-sdk/session-store-runtime";
61
+ import { acknowledgeInternalToolResult } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
57
62
  import { captureFinalCodexCronCreatorToolAllowlist, formatMcpCodexApprovalRemedy, materializeStaticMcpToolsForHarnessRun, resolveCodexMcpToolOverridesForAgent, resolveCodexTtsProvenanceTransfer } from "openclaw/plugin-sdk/codex-mcp-projection";
58
63
  import { appendSessionYieldContext, hasPromptImageInput } from "openclaw/plugin-sdk/session-transcript-runtime";
59
64
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-local-roots";
@@ -62,7 +67,6 @@ import { generatedImageAssetFromBase64 } from "openclaw/plugin-sdk/image-generat
62
67
  import { resolveGeneratedMediaMaxBytes } from "openclaw/plugin-sdk/media-generation-runtime";
63
68
  import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
64
69
  import { stripInvisibleUnicode } from "openclaw/plugin-sdk/web-content-extractor";
65
- import { acknowledgeInternalToolResult } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
66
70
  import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
67
71
  //#region extensions/codex/src/app-server/attempt-preparation-timing.ts
68
72
  /** Records startup before the native turn owns inference and tool execution. */
@@ -122,6 +126,7 @@ var CodexSteeringAcceptedUnconfirmedError = class extends Error {
122
126
  * app-server `turn/steer` requests.
123
127
  */
124
128
  function createCodexSteeringQueue(params) {
129
+ const acceptedMessages = [];
125
130
  let batchedMessages = [];
126
131
  const dispatchedBatches = /* @__PURE__ */ new Map();
127
132
  const pendingMessages = /* @__PURE__ */ new Set();
@@ -147,9 +152,13 @@ function createCodexSteeringQueue(params) {
147
152
  item.acceptance = accepted ? "accepted" : "rejected";
148
153
  item.onQueueAccepted?.(accepted);
149
154
  };
155
+ const acceptItem = (item) => {
156
+ if (item.acceptance === "open") acceptedMessages.push(item.prepared.message);
157
+ reportItemAcceptance(item, true);
158
+ };
150
159
  const resolveItem = (item) => {
151
160
  if (item.settled) return;
152
- reportItemAcceptance(item, true);
161
+ acceptItem(item);
153
162
  item.settled = true;
154
163
  pendingMessages.delete(item);
155
164
  item.resolve();
@@ -167,7 +176,7 @@ function createCodexSteeringQueue(params) {
167
176
  params.signal.removeEventListener("abort", abortQueue);
168
177
  clearBatchTimer();
169
178
  batchedMessages = [];
170
- for (const batch of dispatchedBatches.values()) for (const item of batch.items) reportItemAcceptance(item, true);
179
+ for (const batch of dispatchedBatches.values()) for (const item of batch.items) acceptItem(item);
171
180
  dispatchedBatches.clear();
172
181
  for (const item of pendingMessages) rejectItem(item, error);
173
182
  };
@@ -186,13 +195,14 @@ function createCodexSteeringQueue(params) {
186
195
  closeQueue(/* @__PURE__ */ new Error("codex app-server steering queue cancelled"));
187
196
  };
188
197
  const sendBatch = async (items) => {
189
- let liveItems = items.filter((item) => !item.settled);
190
- if (liveItems.length === 0) return;
198
+ const pendingItems = items.filter((item) => !item.settled);
199
+ let liveItems = [];
200
+ if (pendingItems.length === 0) return;
191
201
  let clientUserMessageId;
192
202
  let skippedRevokedBatch = false;
193
203
  try {
194
204
  assertActive();
195
- const prepared = /* @__PURE__ */ new Map();
205
+ const prepared = [];
196
206
  const isCurrent = (item) => {
197
207
  if (item.settled) return false;
198
208
  try {
@@ -203,17 +213,17 @@ function createCodexSteeringQueue(params) {
203
213
  return false;
204
214
  }
205
215
  };
206
- for (const item of liveItems) {
216
+ for (const item of pendingItems) {
207
217
  if (!isCurrent(item)) continue;
208
218
  try {
209
- prepared.set(item, await params.prepareMessage(item.text, item));
219
+ prepared.push(Object.assign(item, { prepared: await params.prepareMessage(item.text, item) }));
210
220
  } catch (error) {
211
221
  if (isCurrent(item)) throw error;
212
222
  }
213
223
  assertActive();
214
224
  isCurrent(item);
215
225
  }
216
- liveItems = liveItems.filter(isCurrent);
226
+ liveItems = prepared.filter(isCurrent);
217
227
  if (liveItems.length === 0) return;
218
228
  if (params.beforeSubmit) {
219
229
  await params.beforeSubmit(liveItems);
@@ -226,7 +236,7 @@ function createCodexSteeringQueue(params) {
226
236
  const request = {
227
237
  threadId: params.threadId,
228
238
  expectedTurnId: params.turnId,
229
- input: liveItems.flatMap((item) => prepared.get(item) ?? []),
239
+ input: liveItems.flatMap((item) => item.prepared.input),
230
240
  clientUserMessageId
231
241
  };
232
242
  await params.client.request("turn/steer", request, {
@@ -235,7 +245,7 @@ function createCodexSteeringQueue(params) {
235
245
  assertCurrent: () => {
236
246
  assertActive();
237
247
  liveItems = liveItems.filter(isCurrent);
238
- request.input = liveItems.flatMap((item) => prepared.get(item) ?? []);
248
+ request.input = liveItems.flatMap((item) => item.prepared.input);
239
249
  dispatchedBatches.set(request.clientUserMessageId, { items: liveItems });
240
250
  if (liveItems.length === 0) {
241
251
  skippedRevokedBatch = true;
@@ -243,15 +253,12 @@ function createCodexSteeringQueue(params) {
243
253
  }
244
254
  }
245
255
  });
246
- for (const item of liveItems) reportItemAcceptance(item, true);
256
+ for (const item of liveItems) acceptItem(item);
247
257
  } catch (error) {
248
258
  if (clientUserMessageId) dispatchedBatches.delete(clientUserMessageId);
249
259
  if (skippedRevokedBatch) return;
250
- const acceptedUnconfirmed = clientUserMessageId !== void 0 && (isCodexAppServerIndeterminateRequestCancellationError(error) || isCodexAppServerIndeterminateTransportError(error));
251
- for (const item of liveItems) {
252
- if (acceptedUnconfirmed) reportItemAcceptance(item, true);
253
- rejectItem(item, error);
254
- }
260
+ if (clientUserMessageId !== void 0 && (isCodexAppServerIndeterminateRequestCancellationError(error) || isCodexAppServerIndeterminateTransportError(error))) for (const item of liveItems) acceptItem(item);
261
+ for (const item of items) rejectItem(item, error);
255
262
  throw error;
256
263
  }
257
264
  };
@@ -324,6 +331,7 @@ function createCodexSteeringQueue(params) {
324
331
  for (const item of batch.items) resolveItem(item);
325
332
  return true;
326
333
  },
334
+ getAcceptedMessages: () => acceptedMessages.slice(),
327
335
  sealAdmission: sealQueueAdmission,
328
336
  cancel: cancelQueue
329
337
  };
@@ -333,9 +341,6 @@ function normalizeCodexSteerDebounceMs(value) {
333
341
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : CODEX_STEER_ALL_DEBOUNCE_MS;
334
342
  }
335
343
  //#endregion
336
- //#region extensions/codex/src/app-server/attempt-terminal.ts
337
- const attemptTerminal = agentHarnessAttemptTerminal;
338
- //#endregion
339
344
  //#region extensions/codex/src/app-server/event-projector-assistant.ts
340
345
  var CodexAssistantProjection = class {
341
346
  constructor(params, emitAgentEvent, matchesToolProgressEcho, nextTranscriptTimestamp, checkpointCommentary) {
@@ -349,6 +354,7 @@ var CodexAssistantProjection = class {
349
354
  this.assistantTimestampByItem = /* @__PURE__ */ new Map();
350
355
  this.assistantPhaseByItem = /* @__PURE__ */ new Map();
351
356
  this.assistantDeliveryByItem = /* @__PURE__ */ new Map();
357
+ this.assistantQuestionsByItem = /* @__PURE__ */ new Map();
352
358
  this.latestTerminalAssistantCandidateSuperseded = false;
353
359
  this.terminalAssistantCandidateEarlierActiveItemIds = /* @__PURE__ */ new Set();
354
360
  this.lastCommentaryProgressEventByItem = /* @__PURE__ */ new Map();
@@ -412,7 +418,7 @@ var CodexAssistantProjection = class {
412
418
  });
413
419
  if (knownFinalAnswer && !replaceable) await this.params.onPartialReply?.(streamPayload);
414
420
  }
415
- recordItemStarted(item, itemId) {
421
+ async recordItemStarted(item, itemId) {
416
422
  this.noteNativeWorkBarrier(item);
417
423
  this.rememberAssistantPhase(item);
418
424
  if (item?.type === "agentMessage" && itemId && !this.isNonTerminalAssistantItem(itemId) && itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
@@ -421,6 +427,10 @@ var CodexAssistantProjection = class {
421
427
  this.markTerminalAssistantCandidateSupersededBy(itemId, { preserveEarlierActiveItem: true });
422
428
  if (this.latestTerminalAssistantCandidateSuperseded) this.pendingRawTerminalAssistantEchoItemId = void 0;
423
429
  }
430
+ if (item?.type === "agentMessage" && itemId && item.text && !this.assistantTextByItem.has(itemId)) await this.handleAssistantDelta({
431
+ itemId,
432
+ delta: item.text
433
+ });
424
434
  }
425
435
  recordItemCompleted(item, itemId, activeItemIds) {
426
436
  if (itemId && item?.type === "agentMessage") this.completedAssistantItemIds.add(itemId);
@@ -524,14 +534,11 @@ var CodexAssistantProjection = class {
524
534
  }
525
535
  collectAsyncMessages() {
526
536
  return this.assistantItemOrder.flatMap((itemId) => {
527
- if (!this.isAsyncAssistantItem(itemId)) return [];
528
- const text = this.assistantTextByItem.get(itemId)?.trim();
529
- const timestamp = this.assistantTimestampByItem.get(itemId);
530
- if (!text || timestamp === void 0) return [];
531
- return [{
537
+ const delivery = this.createAsyncDelivery(itemId);
538
+ return delivery ? [{
532
539
  itemId,
533
- message: createAssistantAsyncMessage(this.params, text, itemId, timestamp)
534
- }];
540
+ message: delivery.message
541
+ }] : [];
535
542
  });
536
543
  }
537
544
  collectCompletedAssistantMessages(completedItemIds, options) {
@@ -612,6 +619,11 @@ var CodexAssistantProjection = class {
612
619
  if (phase) this.assistantPhaseByItem.set(item.id, phase);
613
620
  const delivery = readItemString(item, "delivery");
614
621
  if (delivery) this.assistantDeliveryByItem.set(item.id, delivery);
622
+ if (item.questions !== void 0) {
623
+ const questions = readCodexAsyncQuestions(item.questions);
624
+ if (questions && delivery === "async") this.assistantQuestionsByItem.set(item.id, questions);
625
+ else this.assistantQuestionsByItem.delete(item.id);
626
+ }
615
627
  }
616
628
  isCommentaryAssistantItem(itemId) {
617
629
  return this.assistantPhaseByItem.get(itemId) === "commentary";
@@ -751,7 +763,7 @@ var CodexAssistantProjection = class {
751
763
  if (!text?.trim() || timestamp === void 0) return;
752
764
  return {
753
765
  itemId,
754
- message: createAssistantAsyncMessage(this.params, text, itemId, timestamp),
766
+ message: createAssistantAsyncMessage(this.params, text, itemId, timestamp, this.assistantQuestionsByItem.get(itemId)),
755
767
  text
756
768
  };
757
769
  }
@@ -970,8 +982,7 @@ var CodexReasoningProjection = class {
970
982
  this.params = params;
971
983
  this.emitAgentEvent = emitAgentEvent;
972
984
  this.onNativePlanUpdate = onNativePlanUpdate;
973
- this.reasoningTextByGroup = /* @__PURE__ */ new Map();
974
- this.reasoningItemOrder = /* @__PURE__ */ new Map();
985
+ this.reasoningTextByItem = /* @__PURE__ */ new Map();
975
986
  this.planTextByItem = /* @__PURE__ */ new Map();
976
987
  this.reasoningStarted = false;
977
988
  this.reasoningEnded = false;
@@ -981,16 +992,14 @@ var CodexReasoningProjection = class {
981
992
  const delta = readStringField(params, "delta") ?? "";
982
993
  if (!delta) return;
983
994
  this.reasoningStarted = true;
984
- if (!this.reasoningItemOrder.has(itemId)) this.reasoningItemOrder.set(itemId, this.reasoningItemOrder.size);
995
+ const item = this.reasoningTextByItem.get(itemId) ?? {
996
+ summary: /* @__PURE__ */ new Map(),
997
+ content: /* @__PURE__ */ new Map()
998
+ };
999
+ this.reasoningTextByItem.set(itemId, item);
985
1000
  const groupIndex = method === "item/reasoning/textDelta" ? readNonNegativeInteger(params, "contentIndex") ?? 0 : readNonNegativeInteger(params, "summaryIndex") ?? 0;
986
- const groupKey = `${method}\0${itemId}\0${groupIndex}`;
987
- const current = this.reasoningTextByGroup.get(groupKey);
988
- this.reasoningTextByGroup.set(groupKey, {
989
- itemId,
990
- method,
991
- index: groupIndex,
992
- text: `${current?.text ?? ""}${delta}`
993
- });
1001
+ const sections = method === "item/reasoning/textDelta" ? item.content : item.summary;
1002
+ sections.set(groupIndex, `${sections.get(groupIndex) ?? ""}${delta}`);
994
1003
  await this.params.onReasoningStream?.({
995
1004
  text: this.reasoningText(),
996
1005
  isReasoningSnapshot: true
@@ -1030,10 +1039,27 @@ var CodexReasoningProjection = class {
1030
1039
  });
1031
1040
  this.emitPlanUpdate({
1032
1041
  explanation,
1042
+ ...params.explanationFormat === "plain" ? { explanationFormat: "plain" } : {},
1033
1043
  steps: plan
1034
1044
  }, source);
1035
1045
  }
1036
- recordItem(item) {
1046
+ async recordItem(item) {
1047
+ if (item?.type === "reasoning") {
1048
+ const previousText = this.reasoningText();
1049
+ this.reasoningTextByItem.set(item.id, {
1050
+ summary: readReasoningSections(item.summary),
1051
+ content: readReasoningSections(item.content)
1052
+ });
1053
+ const text = this.reasoningText();
1054
+ if (text !== previousText) {
1055
+ this.reasoningStarted = true;
1056
+ await this.params.onReasoningStream?.({
1057
+ text,
1058
+ isReasoningSnapshot: true
1059
+ });
1060
+ }
1061
+ return;
1062
+ }
1037
1063
  if (item?.type === "plan" && typeof item.text === "string" && item.text) {
1038
1064
  this.planTextByItem.set(item.id, item.text);
1039
1065
  this.emitPlanUpdate({
@@ -1051,7 +1077,7 @@ var CodexReasoningProjection = class {
1051
1077
  await this.params.onReasoningEnd?.();
1052
1078
  }
1053
1079
  reasoningText() {
1054
- return collectReasoningTextValues(this.reasoningTextByGroup, this.reasoningItemOrder).join("\n\n");
1080
+ return [...this.reasoningTextByItem.values()].flatMap(({ summary, content }) => [summary, content]).flatMap((sections) => [...sections].toSorted(([left], [right]) => left - right)).map(([, text]) => text).filter((text) => text.trim().length > 0).join("\n\n");
1055
1081
  }
1056
1082
  planText() {
1057
1083
  return this.turnPlanText ?? [...this.planTextByItem.values()].filter((text) => text.trim().length > 0).join("\n\n");
@@ -1065,6 +1091,7 @@ var CodexReasoningProjection = class {
1065
1091
  title: "Plan updated",
1066
1092
  source,
1067
1093
  ...params.explanation ? { explanation: params.explanation } : {},
1094
+ ...params.explanationFormat ? { explanationFormat: params.explanationFormat } : {},
1068
1095
  ...params.steps ? { steps: params.steps } : {}
1069
1096
  }
1070
1097
  });
@@ -1074,16 +1101,12 @@ function normalizePlanStepStatus(status) {
1074
1101
  if (status === "inProgress" || status === "in_progress") return "in_progress";
1075
1102
  return status === "completed" ? "completed" : "pending";
1076
1103
  }
1077
- function collectReasoningTextValues(groups, itemOrder) {
1078
- return [...groups.values()].toSorted((left, right) => {
1079
- const itemDelta = (itemOrder.get(left.itemId) ?? Number.MAX_SAFE_INTEGER) - (itemOrder.get(right.itemId) ?? Number.MAX_SAFE_INTEGER);
1080
- if (itemDelta !== 0) return itemDelta;
1081
- const methodDelta = reasoningMethodOrder(left.method) - reasoningMethodOrder(right.method);
1082
- return methodDelta !== 0 ? methodDelta : left.index - right.index;
1083
- }).map((group) => group.text).filter((text) => text.trim().length > 0);
1084
- }
1085
- function reasoningMethodOrder(method) {
1086
- return method === "item/reasoning/summaryTextDelta" ? 0 : 1;
1104
+ function readReasoningSections(value) {
1105
+ const sections = /* @__PURE__ */ new Map();
1106
+ if (Array.isArray(value)) value.forEach((text, index) => {
1107
+ if (typeof text === "string") sections.set(index, text);
1108
+ });
1109
+ return sections;
1087
1110
  }
1088
1111
  //#endregion
1089
1112
  //#region extensions/codex/src/app-server/event-projector-settlement.ts
@@ -1152,7 +1175,8 @@ function buildCodexMessagesSnapshot(params) {
1152
1175
  ...commentaryMessages,
1153
1176
  ...asyncMessages,
1154
1177
  ...(params.assistantMessages ?? []).map(({ itemId, message }) => attachCodexMirrorIdentity(message, `${params.turnId}:assistant:${itemId}`)),
1155
- ...params.toolMessages
1178
+ ...params.toolMessages,
1179
+ ...params.steeringMessages ?? []
1156
1180
  ].toSorted((left, right) => (asDateTimestampMs(left.timestamp) ?? 0) - (asDateTimestampMs(right.timestamp) ?? 0));
1157
1181
  messages.push(...visibleWorkMessages);
1158
1182
  if (params.lastAssistant) {
@@ -1162,6 +1186,7 @@ function buildCodexMessagesSnapshot(params) {
1162
1186
  const taint = { tainted: false };
1163
1187
  return messages.map((message) => projectAgentHarnessTranscriptMessageForDisplay({
1164
1188
  hidden: params.runParams.trigger === "memory",
1189
+ inputProvenance: params.runParams.inputProvenance,
1165
1190
  message: applyCodexTranscriptTaint(message, taint)
1166
1191
  }));
1167
1192
  }
@@ -1189,164 +1214,6 @@ function buildCodexSteeringMessagesSnapshot(params) {
1189
1214
  };
1190
1215
  }
1191
1216
  //#endregion
1192
- //#region extensions/codex/src/app-server/usage-limit-error.ts
1193
- /**
1194
- * Enriches Codex usage-limit failures with current rate-limit information and
1195
- * marks blocked auth profiles when Codex exposes a reset time.
1196
- */
1197
- const CODEX_USAGE_LIMIT_RATE_LIMIT_REFRESH_TIMEOUT_MS = 5e3;
1198
- var CodexUsageLimitPromptError = class extends Error {
1199
- constructor(..._args) {
1200
- super(..._args);
1201
- this.status = 429;
1202
- }
1203
- };
1204
- function resolveCodexPromptError(source) {
1205
- const usageLimitMessage = formatCodexUsageLimitErrorMessage(source);
1206
- if (usageLimitMessage) return new CodexUsageLimitPromptError(usageLimitMessage);
1207
- const info = source.codexErrorInfo;
1208
- let status = info === "rateLimitExceeded" ? 429 : info === "serverOverloaded" ? 503 : info === "internalServerError" ? 500 : void 0;
1209
- if (isJsonObject(info)) for (const variant of [
1210
- "httpConnectionFailed",
1211
- "responseStreamConnectionFailed",
1212
- "responseStreamDisconnected",
1213
- "responseTooManyFailedAttempts"
1214
- ]) {
1215
- const detail = info[variant];
1216
- if (isJsonObject(detail) && typeof detail.httpStatusCode === "number") {
1217
- status = detail.httpStatusCode;
1218
- break;
1219
- }
1220
- }
1221
- return status === void 0 ? source.message ?? void 0 : Object.assign(new Error(source.message ?? "codex app-server error"), {
1222
- status,
1223
- ...info === "serverOverloaded" ? { code: "OVERLOADED" } : {}
1224
- });
1225
- }
1226
- /** Marks a Codex auth profile blocked until the reset time advertised by rate limits. */
1227
- async function markCodexAuthProfileBlockedFromRateLimits(params) {
1228
- const authProfileId = params.authProfileId?.trim();
1229
- if (!authProfileId || !params.params.authProfileStore) return;
1230
- const blockedUntil = resolveCodexUsageLimitResetAtMs(params.rateLimits);
1231
- if (!blockedUntil) return;
1232
- try {
1233
- await markAuthProfileBlockedUntil({
1234
- store: params.params.authProfileStore,
1235
- profileId: authProfileId,
1236
- blockedUntil,
1237
- source: "codex_rate_limits",
1238
- agentDir: params.params.agentDir,
1239
- runId: params.params.runId,
1240
- modelId: params.params.modelId
1241
- });
1242
- } catch (error) {
1243
- embeddedAgentLog.debug("failed to mark Codex auth profile blocked from app-server limits", {
1244
- authProfileId,
1245
- error: formatErrorMessage(error)
1246
- });
1247
- }
1248
- }
1249
- /** Formats a turn-start usage-limit error, refreshing rate limits when needed. */
1250
- async function formatCodexTurnStartUsageLimitError(params) {
1251
- return refreshCodexUsageLimitError({
1252
- client: params.client,
1253
- source: readCodexTurnStartUsageLimitErrorSource(params.client, params.error, params.errorNotification, params.rateLimitsRevisionBeforeTurnStart),
1254
- timeoutMs: params.timeoutMs,
1255
- signal: params.signal
1256
- });
1257
- }
1258
- /** Refreshes a generic prompt usage-limit message into a reset-aware message. */
1259
- async function refreshCodexUsageLimitPromptError(params) {
1260
- if (!shouldRefreshCodexRateLimitsForUsageLimitMessage(params.message)) return;
1261
- return refreshCodexUsageLimitError({
1262
- client: params.client,
1263
- source: {
1264
- message: params.message,
1265
- codexErrorInfo: "usageLimitExceeded",
1266
- rateLimits: readRecentCodexRateLimits(params.client)
1267
- },
1268
- timeoutMs: params.timeoutMs,
1269
- signal: params.signal
1270
- });
1271
- }
1272
- async function refreshCodexUsageLimitError(params) {
1273
- const initialMessage = formatCodexUsageLimitErrorMessage(params.source);
1274
- if (!shouldRefreshCodexRateLimitsForUsageLimitMessage(initialMessage)) return initialMessage ? {
1275
- message: initialMessage,
1276
- ...params.source.rateLimitsTrustedForProfile ? { rateLimitsForProfile: params.source.rateLimits } : {}
1277
- } : void 0;
1278
- const rateLimits = await readCodexRateLimitsFromAppServerForUsageLimitError({
1279
- client: params.client,
1280
- timeoutMs: params.timeoutMs,
1281
- signal: params.signal
1282
- });
1283
- if (!rateLimits) return initialMessage ? {
1284
- message: initialMessage,
1285
- ...params.source.rateLimitsTrustedForProfile ? { rateLimitsForProfile: params.source.rateLimits } : {}
1286
- } : void 0;
1287
- const message = formatCodexUsageLimitErrorMessage({
1288
- message: params.source.message,
1289
- codexErrorInfo: params.source.codexErrorInfo,
1290
- rateLimits,
1291
- rateLimitsAuthoritative: true
1292
- }) ?? initialMessage;
1293
- return message ? {
1294
- message,
1295
- rateLimitsForProfile: rateLimits
1296
- } : void 0;
1297
- }
1298
- async function readCodexRateLimitsFromAppServerForUsageLimitError(params) {
1299
- if (params.signal?.aborted) return;
1300
- try {
1301
- const rateLimits = await params.client.request(CODEX_CONTROL_METHODS.rateLimits, void 0, {
1302
- timeoutMs: resolveCodexUsageLimitRateLimitRefreshTimeoutMs(params.timeoutMs),
1303
- signal: params.signal
1304
- });
1305
- rememberCodexRateLimitsRead(params.client, rateLimits);
1306
- return rateLimits;
1307
- } catch (error) {
1308
- embeddedAgentLog.debug("codex app-server rate-limit refresh failed after usage-limit error", { error: formatErrorMessage(error) });
1309
- return;
1310
- }
1311
- }
1312
- function resolveCodexUsageLimitRateLimitRefreshTimeoutMs(timeoutMs) {
1313
- if (timeoutMs === void 0 || !Number.isFinite(timeoutMs) || timeoutMs <= 0) return CODEX_USAGE_LIMIT_RATE_LIMIT_REFRESH_TIMEOUT_MS;
1314
- return Math.max(100, Math.min(timeoutMs, CODEX_USAGE_LIMIT_RATE_LIMIT_REFRESH_TIMEOUT_MS));
1315
- }
1316
- function readCodexTurnStartUsageLimitErrorSource(client, error, errorNotification, rateLimitsRevisionBeforeTurnStart) {
1317
- const notificationError = readCodexErrorNotification(errorNotification);
1318
- const errorPayload = readCodexErrorPayload(error);
1319
- const rateLimits = errorPayload.rateLimits ?? readRecentCodexRateLimits(client);
1320
- const cacheUpdatedDuringTurnStart = rateLimitsRevisionBeforeTurnStart !== void 0 && readCodexRateLimitsRevision(client) > rateLimitsRevisionBeforeTurnStart;
1321
- return {
1322
- message: notificationError?.message ?? errorPayload.message ?? formatErrorMessage(error),
1323
- codexErrorInfo: notificationError?.codexErrorInfo ?? errorPayload.codexErrorInfo,
1324
- rateLimits,
1325
- rateLimitsTrustedForProfile: errorPayload.rateLimits !== void 0 || cacheUpdatedDuringTurnStart
1326
- };
1327
- }
1328
- function readCodexErrorNotification(notification) {
1329
- if (notification?.method !== "error" || !isJsonObject(notification.params)) return;
1330
- const error = notification.params.error;
1331
- return isJsonObject(error) ? {
1332
- message: readStringField(error, "message"),
1333
- codexErrorInfo: error.codexErrorInfo
1334
- } : void 0;
1335
- }
1336
- function readCodexErrorPayload(error) {
1337
- const message = error instanceof Error ? error.message : void 0;
1338
- if (!error || typeof error !== "object" || !("data" in error)) return { message };
1339
- const data = error.data;
1340
- if (!isJsonObject(data)) return { message };
1341
- const nestedError = isJsonObject(data.error) ? data.error : data;
1342
- const rateLimits = nestedError.rateLimits ?? data.rateLimits;
1343
- return {
1344
- message: readStringField(nestedError, "message") ?? message,
1345
- codexErrorInfo: nestedError.codexErrorInfo,
1346
- rateLimits
1347
- };
1348
- }
1349
- //#endregion
1350
1217
  //#region extensions/codex/src/app-server/event-projector-terminal-failure.ts
1351
1218
  var CodexTerminalFailureProjection = class {
1352
1219
  constructor() {
@@ -1413,6 +1280,7 @@ var CodexTranscriptCheckpoint = class {
1413
1280
  const message = entry.read();
1414
1281
  return message ? [projectAgentHarnessTranscriptMessageForDisplay({
1415
1282
  hidden: this.params.trigger === "memory",
1283
+ inputProvenance: this.params.inputProvenance,
1416
1284
  message: applyCodexTranscriptTaint(message, taint)
1417
1285
  })] : [];
1418
1286
  });
@@ -1482,7 +1350,7 @@ var CodexTurnProjection = class {
1482
1350
  trajectoryRecorder: options.trajectoryRecorder,
1483
1351
  checkpointMessage: this.transcriptCheckpoint.enqueue
1484
1352
  });
1485
- this.eventProjection = new CodexEventProjection(threadId, turnId, (event) => this.emitAgentEvent(event), this.toolProgressProjection, this.toolTranscriptProjection, options.onNativeToolResultRecorded);
1353
+ this.eventProjection = new CodexEventProjection(params.provider, threadId, turnId, (event) => this.emitAgentEvent(event), this.toolProgressProjection, this.toolTranscriptProjection, options.onNativeToolResultRecorded);
1486
1354
  this.assistantProjection = new CodexAssistantProjection(this.settlement.params, (event) => this.emitAgentEvent(event), (text) => this.toolProgressProjection.matchesEcho(text), this.transcriptCheckpoint.nextTimestamp, this.transcriptCheckpoint.enqueueCommentary);
1487
1355
  this.reasoningProjection = new CodexReasoningProjection(this.settlement.params, (event) => this.emitAgentEvent(event), options.onNativePlanUpdate);
1488
1356
  }
@@ -1539,6 +1407,7 @@ var CodexTurnProjection = class {
1539
1407
  asyncMessages,
1540
1408
  commentaryMessages,
1541
1409
  toolMessages: this.toolTranscriptProjection.transcriptMessages,
1410
+ steeringMessages: options?.steeringMessages,
1542
1411
  lastAssistant,
1543
1412
  turnTainted
1544
1413
  });
@@ -1685,6 +1554,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1685
1554
  this.assistantProjection.handleNotification(notification.method, params);
1686
1555
  switch (notification.method) {
1687
1556
  case "item/agentMessage/delta":
1557
+ if (readStringField(params, "delta")) this.eventProjection.markSafetyBufferingAssistantStarted();
1688
1558
  await this.assistantProjection.handleAssistantDelta(params);
1689
1559
  break;
1690
1560
  case "item/reasoning/summaryTextDelta":
@@ -1748,6 +1618,9 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1748
1618
  case "model/rerouted":
1749
1619
  this.eventProjection.handleModelRerouted(params);
1750
1620
  break;
1621
+ case "model/safetyBuffering/updated":
1622
+ this.eventProjection.handleSafetyBuffering(params);
1623
+ break;
1751
1624
  case "error": {
1752
1625
  this.usageProjection.invalidateContext();
1753
1626
  if (params.willRetry === true) {
@@ -1755,6 +1628,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1755
1628
  break;
1756
1629
  }
1757
1630
  const codexErrorInfo = isJsonObject(params.error) ? params.error.codexErrorInfo : void 0;
1631
+ this.eventProjection.handleCyberPolicyError(codexErrorInfo, this.params.modelId);
1758
1632
  const compactionFailure = codexErrorInfo === "other" && this.isCompacting();
1759
1633
  this.settledTurnFailureFinalizationAllowed = codexErrorInfo === "serverOverloaded" || compactionFailure;
1760
1634
  this.terminalFailure.record({
@@ -1775,8 +1649,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1775
1649
  case "item/fileChange/patchUpdated":
1776
1650
  case "item/mcpToolCall/progress":
1777
1651
  case "model/verification":
1778
- case "turn/moderationMetadata":
1779
- case "model/safetyBuffering/updated": break;
1652
+ case "turn/moderationMetadata": break;
1780
1653
  default: this.diagnostics.warnUnknownEvent(notification, params);
1781
1654
  }
1782
1655
  if (!this.projectionClosed && [
@@ -1785,6 +1658,23 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1785
1658
  "rawResponseItem/completed"
1786
1659
  ].includes(notification.method)) await this.settlement.project("transcript/checkpoint", () => this.transcriptCheckpoint.flush());
1787
1660
  }
1661
+ recordUserInputResponse(params) {
1662
+ if (this.projectionClosed) return;
1663
+ this.toolTranscriptProjection.recordToolCall({
1664
+ id: params.itemId,
1665
+ name: "request_user_input",
1666
+ arguments: { questions: params.questions }
1667
+ });
1668
+ this.toolTranscriptProjection.recordToolResult({
1669
+ id: params.itemId,
1670
+ name: "request_user_input",
1671
+ text: JSON.stringify({
1672
+ response: params.response,
1673
+ request: { questions: params.questions }
1674
+ }),
1675
+ isError: false
1676
+ });
1677
+ }
1788
1678
  recordDynamicToolCall(params) {
1789
1679
  this.toolTranscriptProjection.recordDynamicToolCall(params);
1790
1680
  }
@@ -1794,7 +1684,8 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1794
1684
  if (update) {
1795
1685
  const projected = {
1796
1686
  plan: update.steps,
1797
- ...update.explanation ? { explanation: update.explanation } : {}
1687
+ ...update.explanation ? { explanation: update.explanation } : {},
1688
+ ...update.explanationFormat ? { explanationFormat: update.explanationFormat } : {}
1798
1689
  };
1799
1690
  await this.reasoningProjection.handleTurnPlanUpdated(projected, "openclaw");
1800
1691
  }
@@ -1821,8 +1712,9 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1821
1712
  }
1822
1713
  async handleItemStarted(params) {
1823
1714
  const item = readItem(params.item);
1715
+ if (item?.type === "agentMessage" && item.text) this.eventProjection.markSafetyBufferingAssistantStarted();
1824
1716
  const itemId = item?.id ?? readStringField(params, "itemId");
1825
- this.assistantProjection.recordItemStarted(item, itemId);
1717
+ await this.assistantProjection.recordItemStarted(item, itemId);
1826
1718
  if (itemId) this.activeItemIds.add(itemId);
1827
1719
  this.recordNativeToolOutcome(item);
1828
1720
  if (item?.type === "contextCompaction" && itemId) {
@@ -1870,10 +1762,12 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1870
1762
  }
1871
1763
  async handleItemCompleted(params) {
1872
1764
  const item = readItem(params.item);
1765
+ const itemId = item?.id ?? readStringField(params, "itemId");
1766
+ if (item?.type === "contextCompaction" && itemId && this.completedItemIds.has(itemId)) return;
1767
+ if (item?.type === "agentMessage" && item.text) this.eventProjection.markSafetyBufferingAssistantStarted();
1873
1768
  this.diagnostics.warnUnknownItemStatus(item);
1874
1769
  this.recordNativeToolOutcome(item);
1875
1770
  this.nativeToolLifecycleProjector.clearTerminalPresentationForNativeItem(item);
1876
- const itemId = item?.id ?? readStringField(params, "itemId");
1877
1771
  if (itemId) {
1878
1772
  this.activeItemIds.delete(itemId);
1879
1773
  this.completedItemIds.add(itemId);
@@ -1882,7 +1776,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1882
1776
  const asyncMessage = this.assistantProjection.recordItemCompleted(item, itemId, this.activeItemIds);
1883
1777
  if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
1884
1778
  if (this.projectionClosed) return;
1885
- this.reasoningProjection.recordItem(item);
1779
+ await this.reasoningProjection.recordItem(item);
1886
1780
  await this.settlement.project("media_projection", () => this.generatedMediaProjection.recordNative(item));
1887
1781
  if (this.projectionClosed) return;
1888
1782
  if (item?.type === "contextCompaction" && itemId) {
@@ -1943,11 +1837,13 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1943
1837
  const turn = readCodexTurn(params.turn);
1944
1838
  if (!turn || turn.id !== this.turnId) return;
1945
1839
  this.completedTurn = turn;
1840
+ this.eventProjection.endSafetyBuffering();
1946
1841
  const compactionFailure = turn.status === "failed" && (this.terminalFailure.promptErrorSource === "compaction" || turn.error?.codexErrorInfo === "other" && this.isCompacting());
1947
1842
  this.settledTurnFailureFinalizationAllowed = turn.status === "failed" && (turn.error?.codexErrorInfo === "serverOverloaded" || compactionFailure);
1948
1843
  if (turn.status !== "completed") this.usageProjection.invalidateContext();
1949
1844
  if (turn.status === "failed") {
1950
1845
  const codexErrorInfo = turn.error?.codexErrorInfo;
1846
+ this.eventProjection.handleCyberPolicyError(codexErrorInfo, this.params.modelId);
1951
1847
  this.terminalFailure.record({
1952
1848
  message: turn.error?.message,
1953
1849
  codexErrorInfo,
@@ -1974,7 +1870,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1974
1870
  const asyncMessage = this.assistantProjection.recordSnapshotItem(item);
1975
1871
  if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
1976
1872
  if (this.projectionClosed) return;
1977
- this.reasoningProjection.recordItem(item);
1873
+ await this.reasoningProjection.recordItem(item);
1978
1874
  await this.settlement.project("media_projection", () => this.generatedMediaProjection.recordNative(item));
1979
1875
  if (this.projectionClosed) return;
1980
1876
  this.toolProgressProjection.recordToolMeta(item);
@@ -2007,6 +1903,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
2007
1903
  async handleRawResponseItemCompleted(params) {
2008
1904
  const item = isJsonObject(params.item) ? params.item : void 0;
2009
1905
  if (!item) return;
1906
+ if (item.role === "assistant" && extractRawAssistantText(item)) this.eventProjection.markSafetyBufferingAssistantStarted();
2010
1907
  this.toolTranscriptProjection.recordRawNativeToolItem(item);
2011
1908
  this.assistantProjection.handleRawResponseItemCompleted(item, this.activeItemIds);
2012
1909
  await this.settlement.project("media_projection", () => this.generatedMediaProjection.recordRaw(item));
@@ -2288,7 +2185,9 @@ function createCodexUserInputBridge(params) {
2288
2185
  embeddedAgentLog.warn("failed to bridge codex operator input", { error });
2289
2186
  return job.abort.signal.aborted ? job.cancelValue : job.failureValue;
2290
2187
  }).then((value) => {
2291
- job.resolve(job.abort.signal.aborted ? job.cancelValue : value ?? job.failureValue);
2188
+ const response = job.abort.signal.aborted ? job.cancelValue : value ?? job.failureValue;
2189
+ job.onResponse?.(response);
2190
+ job.resolve(response);
2292
2191
  }).finally(() => {
2293
2192
  if (jobs[0] === job) jobs.shift();
2294
2193
  activeCompletion = void 0;
@@ -2351,6 +2250,11 @@ function createCodexUserInputBridge(params) {
2351
2250
  abort: new AbortController(),
2352
2251
  cancelValue,
2353
2252
  failureValue: cancelValue,
2253
+ onResponse: requestParams.questions.some((question) => question.isSecret) ? void 0 : (response) => params.onOrdinaryResponse?.({
2254
+ itemId: requestParams.itemId,
2255
+ questions: requestParams.questions,
2256
+ response
2257
+ }),
2354
2258
  run: async (signal) => {
2355
2259
  const result = await execute(input, timeoutMs, signal);
2356
2260
  return result.status === "answered" ? gatewayAnswersToCodexResponse(result.answers) : cancelValue;
@@ -2377,7 +2281,7 @@ function createCodexUserInputBridge(params) {
2377
2281
  });
2378
2282
  }
2379
2283
  if (readOwnDataString(requestSnapshot, "threadId") !== params.threadId) return;
2380
- const { compileCodexOrdinaryElicitation } = await import("./elicitation-input-DPoK8F7w.js");
2284
+ const { compileCodexOrdinaryElicitation } = await import("./elicitation-input-DPoK8F7w.mjs");
2381
2285
  const compiled = compileCodexOrdinaryElicitation({
2382
2286
  snapshot: requestSnapshot,
2383
2287
  turnId: params.turnId
@@ -2435,6 +2339,7 @@ function readUserInputParams(value) {
2435
2339
  return {
2436
2340
  threadId,
2437
2341
  turnId,
2342
+ itemId,
2438
2343
  questions: parsed,
2439
2344
  isBlocking: readValue(snapshot, "isBlocking") !== false
2440
2345
  };
@@ -2546,6 +2451,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2546
2451
  emitExecutionPhaseOnce("turn_accepted", { phase: "turn_accepted" });
2547
2452
  userInputBridgeRef.current = createCodexUserInputBridge({
2548
2453
  paramsForRun: params,
2454
+ onOrdinaryResponse: (response) => projectorRef.current?.recordUserInputResponse(response),
2549
2455
  threadId: resourceState.thread.threadId,
2550
2456
  turnId: activeTurnId,
2551
2457
  signal: runAbortController.signal
@@ -2633,7 +2539,10 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2633
2539
  state.terminalTurnNotificationQueued = true;
2634
2540
  deadlines.beginSettlement(Date.now());
2635
2541
  }
2636
- emitLifecycleStart();
2542
+ emitLifecycleStart({
2543
+ provider: projectionParams.provider,
2544
+ model: projectionParams.modelId
2545
+ });
2637
2546
  const activeProjector = projectorRef.current;
2638
2547
  noteProgress("turn:start");
2639
2548
  const abortListener = () => {
@@ -2729,12 +2638,33 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2729
2638
  userTurnTranscriptRecorder: options.userTurnTranscriptRecorder
2730
2639
  });
2731
2640
  if (result.failedMediaCount) throw new Error(`failed to hydrate ${result.failedMediaCount} structured image attachment(s) for Codex steering`);
2732
- return buildCodexUserInput(text, result.images);
2641
+ const source = await buildResolvedCodexUserPromptMessage({
2642
+ ...params,
2643
+ prompt: text,
2644
+ transcriptPrompt: text,
2645
+ userTurnTranscriptRecorder: options.userTurnTranscriptRecorder
2646
+ });
2647
+ return {
2648
+ input: buildCodexUserInput(text, result.images),
2649
+ message: {
2650
+ ...source,
2651
+ role: "user",
2652
+ content: result.images.length ? [{
2653
+ type: "text",
2654
+ text
2655
+ }, ...result.images] : text,
2656
+ ...result.images.length ? { __openclaw: {
2657
+ ...asOptionalRecord(Reflect.get(source, "__openclaw")),
2658
+ mediaImageBlockFactIndexes: result.imageFactIndexes
2659
+ } } : {}
2660
+ }
2661
+ };
2733
2662
  },
2734
2663
  beforeSubmit: async (items) => {
2735
2664
  const transcriptItems = items.filter((item) => item.isInboundUserMessage === true || item.userTurnTranscriptRecorder !== void 0);
2736
2665
  if (transcriptItems.length === 0) return;
2737
- await promptMirrorPromise;
2666
+ await projectionReady;
2667
+ await notifications.drainNotificationQueue();
2738
2668
  assertSteeringActive();
2739
2669
  const messages = activeProjector.buildSteeringTranscriptPrefix();
2740
2670
  if (params.sessionTarget && messages.length > 0) {
@@ -2858,6 +2788,11 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2858
2788
  cancel: () => abortExplicitly("cancelled"),
2859
2789
  abort: () => abortExplicitly("aborted")
2860
2790
  };
2791
+ if (thread.preserveNativeModel !== true && thread.connectionScope !== "supervision" && !params.expectedSessionRuntimeOwnership) {
2792
+ const route = resourceState.turnRoute;
2793
+ params.registerPluginRuntimeRefreshConsumer?.(() => resourceState.turnRoute === route && route?.signal.aborted === false && turnRuntime.turnIdRef.current === activeTurnId && !state.completed && !state.terminalTurnNotificationQueued && !runAbortController.signal.aborted);
2794
+ }
2795
+ const projectionReady = bindProjection();
2861
2796
  params.replyOperation?.attachBackend(handle);
2862
2797
  setActiveEmbeddedRun(params.sessionId, handle, params.sessionKey, params.sessionFile, sessionAgentId);
2863
2798
  const freezeRunTerminalOutcome = () => {
@@ -2878,7 +2813,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2878
2813
  freezeRunTerminalOutcome,
2879
2814
  notifyUserMessagePersisted,
2880
2815
  abortListener,
2881
- ready: bindProjection()
2816
+ ready: projectionReady
2882
2817
  };
2883
2818
  }
2884
2819
  //#endregion
@@ -2891,6 +2826,8 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2891
2826
  const { maybeEmitFastModeAutoResetBestEffort, emitLifecycleTerminal, buildLifecycleTerminalMeta } = lifecycle;
2892
2827
  const { codexModelCallDiagnostics } = requestRuntime;
2893
2828
  const { activeTurnId, abortListener, handle, freezeRunTerminalOutcome } = activeTurn;
2829
+ resourceState.releaseInferenceContext?.();
2830
+ resourceState.releaseInferenceContext = void 0;
2894
2831
  prompt.context.attemptTools.scheduledAppAuthoritySourceRef.current = void 0;
2895
2832
  freezeRunTerminalOutcome();
2896
2833
  const projectionClose = state.projectionClosed ? void 0 : activeTurn.activeProjector.closeProjection();
@@ -2900,6 +2837,7 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2900
2837
  else await state.abortCleanup?.catch(() => {});
2901
2838
  if (params.oneShotCliRun) await runCleanupStep("codex-one-shot-terminals", () => terminateCodexBackgroundTerminals(resourceState.client, resourceState.thread.threadId, true));
2902
2839
  try {
2840
+ await state.pluginRuntimeRefreshStop;
2903
2841
  steeringQueueRef.current?.cancel();
2904
2842
  if (params.isFinalFallbackAttempt !== false) await maybeEmitFastModeAutoResetBestEffort();
2905
2843
  codexModelCallDiagnostics.emitError("codex app-server run completed without model-call terminal event");
@@ -2919,8 +2857,9 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2919
2857
  aborted: runAbortController.signal.aborted && !state.clientClosedAbort
2920
2858
  });
2921
2859
  await runCleanupStep("codex-trajectory-flush", () => trajectoryRecorder?.flush());
2922
- const retainLiveIncognitoThread = (terminalState.settledTurnStatus === "completed" || state.permissionChangeRestart === "confirmed" && !params.abortSignal?.aborted) && isIncognitoSessionKey(params.sessionKey);
2923
- const retainLiveThread = ((retainLiveIncognitoThread && resourceState.thread.liveThreadEphemeralPolicy !== void 0 || terminalState.settledTurnStatus !== void 0 && !isIncognitoSessionKey(params.sessionKey) && params.cleanupBundleMcpOnRunEnd !== true && resourceState.thread.liveThreadConfigFingerprint !== void 0 && resourceState.thread.preserveNativeModel !== true && resourceState.thread.connectionScope !== "supervision" && !resourceState.thread.ringZeroConfigFingerprint) && resourceState.thread.clientId === resolveCodexAppServerClientInstanceId(resourceState.client) ? bindingStore.read(bindingIdentity)?.threadId === resourceState.thread.threadId && await bindingStore.withLease(bindingIdentity, async () => {
2860
+ const pluginRuntimeRefreshing = state.pluginRuntimeRefreshStop !== void 0 && !runAbortController.signal.aborted && terminalState.settledTurnStatus === "completed";
2861
+ const retainLiveIncognitoThread = !pluginRuntimeRefreshing && (terminalState.settledTurnStatus === "completed" || state.permissionChangeRestart === "confirmed" && !params.abortSignal?.aborted) && isIncognitoSessionKey(params.sessionKey);
2862
+ const retainLiveThread = (!pluginRuntimeRefreshing && (retainLiveIncognitoThread && resourceState.thread.liveThreadEphemeralPolicy !== void 0 || terminalState.settledTurnStatus !== void 0 && !isIncognitoSessionKey(params.sessionKey) && params.cleanupBundleMcpOnRunEnd !== true && resourceState.thread.liveThreadConfigFingerprint !== void 0 && resourceState.thread.preserveNativeModel !== true && resourceState.thread.connectionScope !== "supervision" && !resourceState.thread.ringZeroConfigFingerprint) && resourceState.thread.clientId === resolveCodexAppServerClientInstanceId(resourceState.client) ? bindingStore.read(bindingIdentity)?.threadId === resourceState.thread.threadId && await bindingStore.withLease(bindingIdentity, async () => {
2924
2863
  if (bindingStore.read(bindingIdentity)?.threadId !== resourceState.thread.threadId) return false;
2925
2864
  return await retainCodexAppServerBindingSubscription(resourceState.client, resourceState.thread.threadId, {
2926
2865
  release: resourceState.thread.liveThreadOwnership?.release,
@@ -2929,20 +2868,42 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2929
2868
  ephemeralPolicy: resourceState.thread.liveThreadEphemeralPolicy
2930
2869
  });
2931
2870
  }) : false) || retainLiveIncognitoThread && resourceState.thread.liveThreadEphemeralPolicy === void 0;
2932
- const bindingReleased = isIncognitoSessionKey(params.sessionKey) && !retainLiveThread ? await bindingStore.mutate(bindingIdentity, {
2933
- kind: "clear",
2934
- threadId: resourceState.thread.threadId
2935
- }) : true;
2936
- if (!retainLiveThread) {
2937
- if (bindingReleased) {
2871
+ if (pluginRuntimeRefreshing) await withExclusiveCodexAppServerThread({
2872
+ bindingStore,
2873
+ identity: bindingIdentity,
2874
+ threadId: resourceState.thread.threadId,
2875
+ run: () => bindingStore.withLease(bindingIdentity, async () => {
2876
+ if (!isSameCodexAppServerThreadOwner(bindingStore.read(bindingIdentity), resourceState.thread)) throw new Error("Codex plugin refresh lost its managed thread binding.");
2938
2877
  if (!await unsubscribeCodexThreadBestEffort(resourceState.client, {
2939
2878
  threadId: resourceState.thread.threadId,
2940
- timeoutMs: 5e3
2879
+ timeoutMs: 5e3,
2880
+ assertCurrent: connection.assertCurrent
2941
2881
  })) {
2942
2882
  await closeCodexStartupClientBestEffort(resourceState.client);
2943
- if (params.oneShotCliRun) await runCleanupStep("codex-one-shot-unsubscribe", async () => {
2944
- throw new Error("Codex one-shot thread unsubscribe was not confirmed");
2945
- });
2883
+ throw new Error("Plugin reload could not release the previous Codex thread.");
2884
+ }
2885
+ if (!await bindingStore.mutate(bindingIdentity, {
2886
+ kind: "clear",
2887
+ threadId: resourceState.thread.threadId
2888
+ }, connection.assertCurrent)) throw new Error("Codex plugin refresh lost its managed thread binding.");
2889
+ })
2890
+ });
2891
+ else {
2892
+ const bindingReleased = isIncognitoSessionKey(params.sessionKey) && !retainLiveThread ? await bindingStore.mutate(bindingIdentity, {
2893
+ kind: "clear",
2894
+ threadId: resourceState.thread.threadId
2895
+ }) : true;
2896
+ if (!retainLiveThread) {
2897
+ if (bindingReleased) {
2898
+ if (!await unsubscribeCodexThreadBestEffort(resourceState.client, {
2899
+ threadId: resourceState.thread.threadId,
2900
+ timeoutMs: 5e3
2901
+ })) {
2902
+ await closeCodexStartupClientBestEffort(resourceState.client);
2903
+ if (params.oneShotCliRun) await runCleanupStep("codex-one-shot-unsubscribe", async () => {
2904
+ throw new Error("Codex one-shot thread unsubscribe was not confirmed");
2905
+ });
2906
+ }
2946
2907
  }
2947
2908
  }
2948
2909
  }
@@ -2960,13 +2921,14 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2960
2921
  await runCleanupStep("codex-shared-client-release", releaseSharedClientLeaseAndRetireOneShotClient);
2961
2922
  const nativeHookRelay = resourceState.nativeHookRelay;
2962
2923
  resourceState.nativeHookRelay = void 0;
2963
- await runCleanupStep("codex-native-hook-relay-release", () => {
2924
+ await runCleanupStep("codex-native-hook-relay-release", async () => {
2964
2925
  if (!nativeHookRelay) return;
2965
2926
  if (state.shouldDelayNativeHookRelayUnregister && !params.oneShotCliRun) scheduleCodexNativeHookRelayUnregister({
2966
2927
  relay: nativeHookRelay,
2967
2928
  hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec
2968
2929
  });
2969
2930
  else nativeHookRelay.unregister();
2931
+ await nativeHookRelay.drain();
2970
2932
  });
2971
2933
  await runCleanupStep("codex-sandbox-release", releaseSandboxExecEnvironment);
2972
2934
  await runCleanupStep("codex-abort-listener-remove", () => {
@@ -2981,72 +2943,6 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2981
2943
  await state.abortCleanup;
2982
2944
  }
2983
2945
  //#endregion
2984
- //#region extensions/codex/src/app-server/workspace-dir-cache.ts
2985
- /** Process-local cache of Codex workspaces already created by the run loop. */
2986
- const codexWorkspaceDirCache = /* @__PURE__ */ new Set();
2987
- //#endregion
2988
- //#region extensions/codex/src/app-server/run-attempt-lifecycle.ts
2989
- const CODEX_APP_SERVER_PROJECTED_CHARS_PER_TOKEN = 4;
2990
- function shouldKeepCodexSharedAbortOpen(params) {
2991
- const terminal = attemptTerminal.project(params.result.terminal);
2992
- if (params.explicitCancellationObserved || terminal.aborted || terminal.externalAbort) return false;
2993
- return params.trigger === "memory" || !params.attemptSucceeded;
2994
- }
2995
- function withCodexAppServerFastModeServiceTier(appServer, params) {
2996
- const fastMode = typeof params.fastMode === "function" ? params.fastMode() : params.fastMode;
2997
- const serviceTier = fastMode === void 0 ? appServer.serviceTier : fastMode ? "priority" : void 0;
2998
- if (serviceTier === appServer.serviceTier) return appServer;
2999
- if (serviceTier) return {
3000
- ...appServer,
3001
- serviceTier
3002
- };
3003
- return {
3004
- ...appServer,
3005
- serviceTier: null
3006
- };
3007
- }
3008
- function estimateCodexAppServerProjectedTurnTokens(params) {
3009
- const inputChars = params.prompt.length + (params.developerInstructions?.length ?? 0);
3010
- return Math.max(1, Math.ceil(inputChars / CODEX_APP_SERVER_PROJECTED_CHARS_PER_TOKEN));
3011
- }
3012
- async function ensureCodexWorkspaceDirOnce(workspaceDir) {
3013
- const normalized = path.resolve(workspaceDir);
3014
- if (codexWorkspaceDirCache.has(normalized)) return;
3015
- await fs.mkdir(normalized, { recursive: true });
3016
- codexWorkspaceDirCache.add(normalized);
3017
- }
3018
- async function emitCodexAppServerEvent(params, event) {
3019
- try {
3020
- emitAgentEvent({
3021
- runId: params.runId,
3022
- stream: event.stream,
3023
- data: event.data,
3024
- ...params.sessionKey ? { sessionKey: params.sessionKey } : {}
3025
- });
3026
- } catch (error) {
3027
- embeddedAgentLog.debug("codex app-server global agent event emit failed", { error });
3028
- }
3029
- try {
3030
- await params.onAgentEvent?.(event);
3031
- } catch (error) {
3032
- embeddedAgentLog.debug("codex app-server agent event handler threw", { error });
3033
- }
3034
- }
3035
- async function runCodexAgentEndHook(params, hookParams) {
3036
- const sideEffectParams = {
3037
- ...hookParams,
3038
- ctx: {
3039
- ...hookParams.ctx,
3040
- config: params.config
3041
- }
3042
- };
3043
- if (!params.messageChannel && !params.messageProvider) {
3044
- await awaitAgentEndSideEffects(sideEffectParams);
3045
- return;
3046
- }
3047
- runAgentEndSideEffects(sideEffectParams);
3048
- }
3049
- //#endregion
3050
2946
  //#region extensions/codex/src/app-server/startup-binding.ts
3051
2947
  const CODEX_APP_SERVER_NATIVE_THREAD_FALLBACK_MAX_TOKENS = 3e5;
3052
2948
  const CODEX_APP_SERVER_NATIVE_THREAD_DEFAULT_RESERVE_TOKENS = 2e4;
@@ -3467,7 +3363,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3467
3363
  const usesSupervisionConnection = startupBinding?.connectionScope === "supervision";
3468
3364
  if (usesSupervisionConnection) activeContextEngine = void 0;
3469
3365
  if (usesSupervisionConnection && pluginConfig.supervision?.enabled !== true) throw new Error("Codex supervision is disabled; refusing to open a native user-home supervised session");
3470
- const resolveRuntimeOptionsForBinding = (binding, selection) => resolveCodexBindingAppServerConnection({
3366
+ const resolveRuntimeOptionsForBinding = async (binding, selection) => (await resolveCodexBindingAppServerConnection({
3471
3367
  binding,
3472
3368
  pluginConfig,
3473
3369
  execPolicy,
@@ -3477,8 +3373,9 @@ async function prepareCodexAttemptConnection({ params, options }) {
3477
3373
  agentDir,
3478
3374
  requirementsToml,
3479
3375
  openClawSandboxActive: sandbox?.enabled === true,
3480
- sessionPermissionMode: params.permissionMode
3481
- }).appServer;
3376
+ sessionPermissionMode: params.permissionMode,
3377
+ assertCurrent
3378
+ })).appServer;
3482
3379
  const initialStartupBindingHadInactiveThreadBootstrap = isInactiveThreadBootstrapBinding(startupBinding);
3483
3380
  const appServerHomeScope = resolveCodexAppServerHomeScope({ appServer: pluginConfig.appServer });
3484
3381
  const preparedAuthRoute = usesSupervisionConnection ? void 0 : params.runtimePlan?.auth.modelRoute;
@@ -3521,7 +3418,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3521
3418
  };
3522
3419
  let reviewerPolicyContext = resolveReviewerPolicyContext(startupBinding);
3523
3420
  preDynamicStartupStages.mark("auth-profile");
3524
- let configuredAppServer = resolveRuntimeOptionsForBinding(startupBinding, {
3421
+ let configuredAppServer = await resolveRuntimeOptionsForBinding(startupBinding, {
3525
3422
  modelProvider: reviewerPolicyContext.modelProvider,
3526
3423
  model: reviewerPolicyContext.model
3527
3424
  });
@@ -3632,7 +3529,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3632
3529
  preDynamicStartupStages.mark("rotate-binding");
3633
3530
  if (startupBinding !== startupBindingBeforeRotation) {
3634
3531
  reviewerPolicyContext = resolveReviewerPolicyContext(startupBinding);
3635
- configuredAppServer = resolveRuntimeOptionsForBinding(startupBinding, {
3532
+ configuredAppServer = await resolveRuntimeOptionsForBinding(startupBinding, {
3636
3533
  modelProvider: reviewerPolicyContext.modelProvider,
3637
3534
  model: reviewerPolicyContext.model
3638
3535
  });
@@ -3660,7 +3557,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3660
3557
  pluginAppServer: appServer,
3661
3558
  continuityCalibration: startupBindingBeforeRotation?.continuityCalibration
3662
3559
  };
3663
- const resolveRuntimeOptionsForCurrentBinding = (selection) => resolveFinalAppServer(resolveRuntimeOptionsForBinding(mutable.startupBinding, selection), selection).appServer;
3560
+ const resolveRuntimeOptionsForCurrentBinding = async (selection) => resolveFinalAppServer(await resolveRuntimeOptionsForBinding(mutable.startupBinding, selection), selection).appServer;
3664
3561
  assertCurrent();
3665
3562
  return {
3666
3563
  params,
@@ -3778,6 +3675,7 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
3778
3675
  const messages = await readMirroredSessionHistoryMessages({
3779
3676
  ...activeTranscriptTarget,
3780
3677
  signal: connection.runAbortController.signal,
3678
+ contextTokenBudget: effectiveContextTokenBudget,
3781
3679
  ...transcriptReadFence ? { admission: transcriptReadFence } : {}
3782
3680
  });
3783
3681
  connection.runAbortController.signal.throwIfAborted();
@@ -3802,6 +3700,7 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
3802
3700
  modelId: params.modelId
3803
3701
  } : {},
3804
3702
  trigger: params.trigger,
3703
+ inputProvenance: params.inputProvenance,
3805
3704
  ...buildAgentHookContextChannelFields({
3806
3705
  sessionKey: contextSessionKey,
3807
3706
  messageChannel: params.messageChannel,
@@ -3846,6 +3745,7 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
3846
3745
  });
3847
3746
  historyState.messages = await readFencedHistory() ?? historyState.messages;
3848
3747
  }
3748
+ historyState.messages.push(...params.pluginRuntimeRefreshMessages ?? []);
3849
3749
  const memoryToolNames = getCodexWorkspaceMemoryToolNames(toolBridge.availableSpecs);
3850
3750
  const workspaceBootstrapContext = await buildCodexWorkspaceBootstrapContext({
3851
3751
  params: runtimeParams,
@@ -4212,6 +4112,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4212
4112
  clearTimeout(drainGraceTimer);
4213
4113
  deadlines.dispose();
4214
4114
  };
4115
+ if (state.pluginRuntimeRefreshStop) await state.pluginRuntimeRefreshStop.catch(() => void 0);
4215
4116
  const settlement = drainNotificationQueue().then(async () => {
4216
4117
  await closeProjection();
4217
4118
  await activeProjector.settlement.drain();
@@ -4231,7 +4132,10 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4231
4132
  } finally {
4232
4133
  if (!state.projectionClosed) await resources.runCleanupStep("codex-transcript-checkpoint", closeProjection);
4233
4134
  }
4234
- const result = activeProjector.buildResult(toolBridge.telemetry, { yieldDetected: toolState.yieldDetected });
4135
+ const result = activeProjector.buildResult(toolBridge.telemetry, {
4136
+ yieldDetected: toolState.yieldDetected,
4137
+ steeringMessages: params.pluginRuntimeRefreshPending?.() ? turnRuntime.steeringQueueRef.current?.getAcceptedMessages() : void 0
4138
+ });
4235
4139
  const projectedTerminal = attemptTerminal.project(result.terminal);
4236
4140
  const isFinalAborted = () => terminalState.explicitCancellationObserved || !resourceState.executionDisconnectError && (projectedTerminal.aborted || runAbortController.signal.aborted && !state.clientClosedAbort);
4237
4141
  const currentPromptError = (fallback) => resourceState.executionDisconnectError ?? state.clientClosedPromptError ?? (state.timeout ? `codex app-server ${state.timeout.kind === "execution" ? "execution budget" : "terminal settlement"} timed out` : fallback);
@@ -4476,7 +4380,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4476
4380
  hookRunner
4477
4381
  });
4478
4382
  state.shouldDelayNativeHookRelayUnregister = completedTurnStatus === "completed" && !effectiveTimedOut && !runAbortController.signal.aborted && !finalAborted && !finalPromptError;
4479
- if (state.shouldDelayNativeHookRelayUnregister) try {
4383
+ if (turnSucceeded && !runAbortController.signal.aborted && !state.pluginRuntimeRefreshStop) try {
4480
4384
  const continuityCalibration = context.promptState.noEngineContinuityProjectionApplied ? buildCodexContinuityCalibration({
4481
4385
  promptChars: prompt.turnState.codexTurnPromptText.length,
4482
4386
  inputTokens: result.attemptUsage?.contextUsage?.state === "available" ? result.attemptUsage.contextUsage.promptTokens ?? 0 : 0
@@ -4521,27 +4425,30 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4521
4425
  });
4522
4426
  markTrajectoryEndRecorded();
4523
4427
  const terminalAssistantText = collectTerminalAssistantText(result);
4524
- if (terminalAssistantText && (!streamState.eventEmitted || streamState.needsTerminalSnapshot) && !finalAborted && !finalPromptError) emitCodexAppServerEvent(params, {
4428
+ if (terminalAssistantText && (assistantTranscriptIdempotencyKey || (!streamState.eventEmitted || streamState.needsTerminalSnapshot) && !finalAborted && !finalPromptError)) emitCodexAppServerEvent(params, {
4525
4429
  stream: "assistant",
4526
- data: { text: terminalAssistantText }
4430
+ data: {
4431
+ text: terminalAssistantText,
4432
+ ...assistantTranscriptIdempotencyKey ? {
4433
+ itemId: assistantTranscriptIdempotencyKey,
4434
+ replace: true,
4435
+ replaceable: true
4436
+ } : {}
4437
+ }
4527
4438
  });
4528
- emitLifecycleTerminal(finalPromptError ? {
4529
- phase: "error",
4530
- error: formatErrorMessage(finalPromptError),
4531
- ...buildLifecycleTerminalMeta({
4532
- aborted: finalAborted,
4533
- timedOut: effectiveTimedOut
4534
- })
4535
- } : {
4536
- phase: "end",
4439
+ emitLifecycleTerminal({
4440
+ phase: finalPromptError ? "error" : "end",
4441
+ ...finalPromptError ? { error: formatErrorMessage(finalPromptError) } : {},
4442
+ ...assistantTranscriptIdempotencyKey ? { assistantTranscriptIdempotencyKey } : {},
4537
4443
  ...buildLifecycleTerminalMeta({
4538
4444
  aborted: finalAborted,
4539
4445
  timedOut: effectiveTimedOut,
4540
- yielded: toolState.yieldDetected
4446
+ yielded: finalPromptError ? void 0 : toolState.yieldDetected
4541
4447
  })
4542
4448
  });
4543
4449
  const finalizedResult = Object.assign(result, {
4544
4450
  ...runtimeModelSelection ? { runtimeModelSelection } : {},
4451
+ ...turnSucceeded && params.pluginRuntimeRefreshPending?.() ? { pluginRuntimeRefreshMessages: params.suppressNextUserMessagePersistence && !params.pluginRuntimeRefreshMessages ? [params.userTurnTranscriptRecorder?.getPersistedMessage?.() ?? buildCodexUserPromptMessage(params), ...result.messagesSnapshot] : result.messagesSnapshot } : {},
4545
4452
  ...toolState.yieldAcknowledgment ? { yieldAcknowledgment: toolState.yieldAcknowledgment } : {},
4546
4453
  ...codexAppServerFailure ? { codexAppServerFailure } : {},
4547
4454
  ...promptTimeoutOutcome ? { promptTimeoutOutcome } : {},
@@ -4668,7 +4575,7 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
4668
4575
  state.pendingTerminalDynamicToolRelease = value;
4669
4576
  scheduleTerminalDynamicToolReleaseCheck();
4670
4577
  };
4671
- const emitLifecycleStart = () => {
4578
+ const emitLifecycleStart = (model) => {
4672
4579
  emitCodexAppServerEvent(params, {
4673
4580
  stream: "lifecycle",
4674
4581
  data: {
@@ -4676,10 +4583,17 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
4676
4583
  startedAt: attemptStartedAt
4677
4584
  }
4678
4585
  });
4586
+ emitCodexAppServerEvent(params, {
4587
+ stream: "lifecycle",
4588
+ data: {
4589
+ phase: "model",
4590
+ ...model
4591
+ }
4592
+ });
4679
4593
  state.lifecycleStarted = true;
4680
4594
  };
4681
4595
  const emitLifecycleTerminal = (data) => {
4682
- if (!state.lifecycleStarted || state.lifecycleTerminalEmitted || state.permissionChangeRestart) return;
4596
+ if (!state.lifecycleStarted || state.lifecycleTerminalEmitted || state.permissionChangeRestart || params.pluginRuntimeRefreshPending?.()) return;
4683
4597
  emitCodexAppServerEvent(params, {
4684
4598
  stream: "lifecycle",
4685
4599
  data: {
@@ -4777,13 +4691,29 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
4777
4691
  //#endregion
4778
4692
  //#region extensions/codex/src/app-server/run-attempt-notification-controller.ts
4779
4693
  function createCodexAttemptNotificationController(resources, turnRuntime, lifecycle) {
4780
- const { prompt, state: resourceState, projectorRef, registerNativeSubagentMonitor } = resources;
4694
+ const { prompt, state: resourceState, projectorRef } = resources;
4781
4695
  const { context, turnState } = prompt;
4782
4696
  const { attemptTools, runtime } = context;
4783
4697
  const { appServer, runAbortController } = runtime.connection;
4784
4698
  const { allocateCodexToolOutcomeOrdinal } = attemptTools;
4785
4699
  const { state, turnIdRef, userInputBridgeRef, steeringQueueRef, activeTurnItemIds, pendingOpenClawDynamicToolCompletionIds, openClawDynamicToolExecutions, completeTurn, noteProgress, deadlines } = turnRuntime;
4786
4700
  const { scheduleTerminalDynamicToolReleaseCheck, reportExecutionNotification, maybeAnnounceFastModeAutoOff } = lifecycle;
4701
+ const pendingNativeCommandItems = /* @__PURE__ */ new Set();
4702
+ const nativeItemObservers = /* @__PURE__ */ new Set();
4703
+ const waitForNativeTerminalItems = async (signal) => {
4704
+ if (pendingNativeCommandItems.size === 0) return;
4705
+ const completion = createDeferred();
4706
+ const observe = () => {
4707
+ if (pendingNativeCommandItems.size === 0) completion.resolve();
4708
+ };
4709
+ nativeItemObservers.add(observe);
4710
+ try {
4711
+ observe();
4712
+ if (!await waitForPromiseOrAbort(completion.promise, signal)) signal.throwIfAborted();
4713
+ } finally {
4714
+ nativeItemObservers.delete(observe);
4715
+ }
4716
+ };
4787
4717
  const isTerminalTurnNotificationForTurn = (notification, notificationTurnId) => isTerminalCodexTurnNotificationForTurn({
4788
4718
  notification,
4789
4719
  threadId: resourceState.thread.threadId,
@@ -4838,6 +4768,11 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
4838
4768
  });
4839
4769
  } finally {
4840
4770
  state.activeLocalProjections -= 1;
4771
+ if (isCurrentTurn && notification.method === "item/completed") {
4772
+ const item = readCodexNotificationItem(notification.params);
4773
+ if (item?.type === "commandExecution" && typeof item.id === "string") pendingNativeCommandItems.delete(item.id);
4774
+ }
4775
+ for (const observe of nativeItemObservers) observe();
4841
4776
  if (isTerminal) {
4842
4777
  if ((readCodexTurnCompletedNotification(notification.params)?.turn)?.status === "interrupted" && state.sawCodexInterruptMarker) projector.markAborted();
4843
4778
  completeTurn();
@@ -4876,6 +4811,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
4876
4811
  const modelToolCallId = readRawResponseToolCallId(notification);
4877
4812
  if (modelToolCallId) allocateCodexToolOutcomeOrdinal?.(modelToolCallId);
4878
4813
  const nativeItem = readCodexNotificationItem(notification.params);
4814
+ if (notification.method === "item/started" && nativeItem?.type === "commandExecution" && typeof nativeItem.id === "string") pendingNativeCommandItems.add(nativeItem.id);
4879
4815
  if (nativeItem?.type === "webSearch") {
4880
4816
  projector.settlement.turnTainted ||= notification.method === "item/completed";
4881
4817
  projector.recordNativeToolOutcome(nativeItem);
@@ -4892,9 +4828,9 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
4892
4828
  const drainNotificationQueue = async () => {
4893
4829
  await resourceState.turnRoute?.drain();
4894
4830
  };
4895
- registerNativeSubagentMonitor(resourceState.thread.threadId);
4896
4831
  return {
4897
4832
  waitForActiveNativeTurnCompletion,
4833
+ waitForNativeTerminalItems,
4898
4834
  noteNotificationReceived,
4899
4835
  enqueueNotification,
4900
4836
  drainNotificationQueue
@@ -4910,13 +4846,24 @@ async function prepareCodexAttemptPrompt(context) {
4910
4846
  const { connection, buildActiveRunAttemptParams, effectiveContextTokenBudget, effectiveRuntimeModelId, effectiveRuntimeProviderId } = runtime;
4911
4847
  const { params, activeContextEngine, usesSupervisionConnection, mutable, isInactiveThreadBootstrapBinding, bindingStore, bindingIdentity, agentDir, appServer, contextSessionKey, effectiveWorkspace, sandbox } = connection;
4912
4848
  const { toolBridge } = attemptTools;
4913
- let contextImages = [];
4914
- const currentUserTurnIdempotencyKey = params.userTurnTranscriptRecorder?.message?.idempotencyKey;
4849
+ const nativeHistoryProvenancePrefix = params.trigger === "user" ? buildCodexHistoryProvenancePrefix(params) : void 0;
4850
+ const forkedSession = !mutable.startupBinding?.threadId && params.sessionTarget ? getSessionEntry({
4851
+ ...params.sessionTarget,
4852
+ sessionKey: contextSessionKey,
4853
+ hydrateSkillPromptRefs: false,
4854
+ readConsistency: "latest"
4855
+ }) : void 0;
4856
+ const preserveForkedToolResults = Boolean(forkedSession?.sessionId === params.sessionId && forkedSession.createdVia === "spawn" && forkedSession.parentSessionKey && forkedSession.parentSessionKey !== contextSessionKey && forkedSession.forkSource?.sessionKey === forkedSession.parentSessionKey && forkedSession.forkSource.sessionId !== params.sessionId);
4857
+ let contextImageGroups = [];
4858
+ let turnContextImageGroups = [];
4915
4859
  const assertProjectionCurrent = () => {
4916
4860
  params.hostCapabilities.assertActive();
4917
4861
  connection.assertCurrent();
4918
4862
  connection.runAbortController.signal.throwIfAborted();
4919
4863
  };
4864
+ const admittedMessage = params.userTurnTranscriptRecorder?.message ?? await params.userTurnTranscriptRecorder?.resolveMessage();
4865
+ assertProjectionCurrent();
4866
+ const currentUserTurnIdempotencyKey = params.pluginRuntimeRefreshMessages ? void 0 : admittedMessage?.idempotencyKey;
4920
4867
  const prepareFileContext = async (message, maxChars) => {
4921
4868
  const prepare = params.hostCapabilities.prepareContextMedia;
4922
4869
  if (!prepare) {
@@ -4942,11 +4889,12 @@ async function prepareCodexAttemptPrompt(context) {
4942
4889
  originalHistoryMessages: historyState.messages,
4943
4890
  prompt: params.prompt,
4944
4891
  maxRenderedContextChars: codexContinuityProjectionMaxChars,
4892
+ toolPayloadMode: params.pluginRuntimeRefreshMessages || preserveForkedToolResults ? "preserve" : "elide",
4945
4893
  prepareFileContext,
4946
4894
  currentUserTurnIdempotencyKey
4947
4895
  });
4948
4896
  assertProjectionCurrent();
4949
- contextImages = projection.images ?? [];
4897
+ contextImageGroups = projection.imageGroups ?? [];
4950
4898
  promptState.promptText = projection.promptText;
4951
4899
  promptState.promptContextRange = projection.promptContextRange;
4952
4900
  promptState.prePromptMessageCount = projection.prePromptMessageCount;
@@ -4991,12 +4939,12 @@ async function prepareCodexAttemptPrompt(context) {
4991
4939
  prompt: params.prompt,
4992
4940
  systemPromptAddition: assembled.systemPromptAddition,
4993
4941
  maxRenderedContextChars: codexContextProjectionMaxChars,
4994
- toolPayloadMode: contextEngineProjection ? "preserve" : "elide",
4942
+ toolPayloadMode: contextEngineProjection || params.pluginRuntimeRefreshMessages || preserveForkedToolResults ? "preserve" : "elide",
4995
4943
  ...projectionDecision.project ? { prepareFileContext } : {},
4996
4944
  currentUserTurnIdempotencyKey
4997
4945
  });
4998
4946
  assertProjectionCurrent();
4999
- contextImages = projectionDecision.project ? projection.images ?? [] : [];
4947
+ contextImageGroups = projectionDecision.project ? projection.imageGroups ?? [] : [];
5000
4948
  const decisionBinding = decisionStartupBinding;
5001
4949
  embeddedAgentLog.info("codex app-server context-engine projection decision", {
5002
4950
  sessionId: params.sessionId,
@@ -5024,13 +4972,17 @@ async function prepareCodexAttemptPrompt(context) {
5024
4972
  if (activeContextEngine) try {
5025
4973
  await applyActiveContextEngineProjection(runtime.nativeToolSurfaceEnabled ? mutable.startupBinding : void 0);
5026
4974
  } catch (assembleErr) {
5027
- if (assembleErr instanceof CodexContextAttachmentError) throw assembleErr;
4975
+ if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
5028
4976
  assertProjectionCurrent();
5029
4977
  embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
5030
4978
  }
5031
4979
  const codexModelInputHistoryMessages = [];
4980
+ const admittedContent = admittedMessage?.content;
4981
+ const currentUserMessage = admittedMessage ? typeof admittedContent === "string" ? admittedContent : (admittedContent ?? []).flatMap((part) => part.type === "text" ? [part.text] : []).join("\n") : params.pluginRuntimeRefreshMessages ? "" : params.prompt;
5032
4982
  const buildPromptFromCurrentInputs = async () => {
5033
4983
  return await resolveAgentHarnessBeforePromptBuildResult({
4984
+ currentUserMessage,
4985
+ currentUserMessageId: admittedMessage?.idempotencyKey,
5034
4986
  prompt: prependCurrentInboundContext(promptState.promptText, params.currentInboundContext),
5035
4987
  developerInstructions: { build: ({ toolsAllow }) => {
5036
4988
  if (isRestrictivePromptToolsAllow(toolsAllow)) throw new Error("Codex app-server cannot enforce before_prompt_build toolsAllow; use the embedded or Copilot runtime for turn-scoped tool policy.");
@@ -5080,23 +5032,34 @@ async function prepareCodexAttemptPrompt(context) {
5080
5032
  promptInputRange: promptBuildResult.promptInputRange,
5081
5033
  decoratedPrompt: turnPromptText
5082
5034
  });
5083
- return fitCodexProjectedContextForTurnStart({
5035
+ const imageOffset = projectedRanges && promptState.promptContextRange ? projectedRanges.contextRange.start - promptState.promptContextRange.start : void 0;
5036
+ const fitted = fitCodexProjectedContextForTurnStart({
5084
5037
  promptText: turnPromptText,
5038
+ maxChars: CODEX_TURN_START_TEXT_INPUT_MAX_CHARS - (nativeHistoryProvenancePrefix?.length ?? 0),
5085
5039
  contextRange: projectedRanges?.contextRange,
5086
5040
  requestRange: projectedRanges?.requestRange,
5087
- preservedRange
5041
+ preservedRange,
5042
+ imageGroups: imageOffset === void 0 ? [] : contextImageGroups.map((group) => ({
5043
+ images: group.images,
5044
+ start: group.start + imageOffset,
5045
+ end: group.end + imageOffset
5046
+ }))
5088
5047
  });
5048
+ turnContextImageGroups = fitted.imageGroups ?? [];
5049
+ return fitted.promptText;
5089
5050
  };
5090
5051
  const firstPromptBuild = await buildPromptFromCurrentInputs();
5091
5052
  const turnState = {
5092
5053
  promptBuild: firstPromptBuild,
5093
5054
  codexTurnPromptText: decorateCodexTurnPromptText(firstPromptBuild)
5094
5055
  };
5095
- const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(turnState.promptBuild.developerInstructions, buildTurnCollaborationMode(params, {
5056
+ let parentLocalEgress = false;
5057
+ const parentLocalContext = {
5096
5058
  turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
5097
5059
  skillsCollaborationInstructions,
5098
5060
  memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions
5099
- }).settings.developer_instructions ?? void 0);
5061
+ };
5062
+ const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(turnState.promptBuild.developerInstructions, (parentLocalEgress ? buildCodexParentLocalInstructions(params, parentLocalContext) : buildTurnCollaborationMode(params, parentLocalContext).settings.developer_instructions) ?? void 0);
5100
5063
  const rebuildCodexPromptBuildFromCurrentProjection = async () => {
5101
5064
  turnState.promptBuild = await buildPromptFromCurrentInputs();
5102
5065
  turnState.codexTurnPromptText = decorateCodexTurnPromptText(turnState.promptBuild);
@@ -5140,7 +5103,7 @@ async function prepareCodexAttemptPrompt(context) {
5140
5103
  };
5141
5104
  const applyNoContextEngineContinuityProjection = async (action, binding) => {
5142
5105
  const hasContinuity = historyState.messages.some((message) => message.role === "user" || isCodexDurableCustomMessage(message) || action === "started" && (message.role === "compactionSummary" || message.role === "branchSummary"));
5143
- if (activeContextEngine || !hasContinuity) return false;
5106
+ if (activeContextEngine || !hasContinuity && !params.pluginRuntimeRefreshMessages?.length) return false;
5144
5107
  if (action === "resumed" && promptState.precomputedStaleBindingContinuityProjectionApplied) return true;
5145
5108
  if (action === "started" && promptState.staleBindingContinuityForcedFreshStart) return true;
5146
5109
  if (action === "started" && promptState.inactiveThreadBootstrapBindingForcedFreshStart) return false;
@@ -5184,7 +5147,7 @@ async function prepareCodexAttemptPrompt(context) {
5184
5147
  try {
5185
5148
  await applyActiveContextEngineProjection(void 0);
5186
5149
  } catch (assembleErr) {
5187
- if (assembleErr instanceof CodexContextAttachmentError) throw assembleErr;
5150
+ if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
5188
5151
  assertProjectionCurrent();
5189
5152
  embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
5190
5153
  }
@@ -5213,10 +5176,11 @@ async function prepareCodexAttemptPrompt(context) {
5213
5176
  let workspaceReferencesIncluded = true;
5214
5177
  return {
5215
5178
  context,
5216
- get contextImages() {
5217
- return contextImages;
5179
+ get contextImageGroups() {
5180
+ return turnContextImageGroups;
5218
5181
  },
5219
5182
  codexModelInputHistoryMessages,
5183
+ nativeHistoryProvenancePrefix,
5220
5184
  turnState,
5221
5185
  refreshWorkspaceReferences: (include) => {
5222
5186
  turnState.codexTurnPromptText = decorateCodexTurnPromptText(turnState.promptBuild, include);
@@ -5225,6 +5189,10 @@ async function prepareCodexAttemptPrompt(context) {
5225
5189
  workspaceReferencesIncluded = include;
5226
5190
  }
5227
5191
  },
5192
+ setParentLocalEgress: () => {
5193
+ parentLocalEgress = true;
5194
+ Object.assign(systemPromptReport, buildSystemPromptReport(!workspaceReferencesIncluded));
5195
+ },
5228
5196
  buildRenderedCodexDeveloperInstructions,
5229
5197
  rebuildCodexTurnPromptTextFromCurrentProjection,
5230
5198
  applyNoContextEngineContinuityProjection,
@@ -5280,6 +5248,7 @@ function prepareCodexAttemptResources(prompt) {
5280
5248
  sharedCodexClientRetiredForOneShotCleanup: false,
5281
5249
  sandboxExecEnvironment: void 0,
5282
5250
  executionDisconnectError: void 0,
5251
+ releaseInferenceContext: void 0,
5283
5252
  codexEnvironmentSelection: void 0,
5284
5253
  codexExecutionCwd: effectiveCwd,
5285
5254
  codexSandboxPolicy: void 0,
@@ -5366,17 +5335,65 @@ function prepareCodexAttemptResources(prompt) {
5366
5335
  await operation();
5367
5336
  }
5368
5337
  });
5369
- const unregisterNativeSubagentMonitor = () => {
5370
- state.nativeSubagentMonitor?.unregister();
5338
+ let nativeSubagentMonitorSettlement;
5339
+ const unregisterNativeSubagentMonitor = async () => {
5340
+ const registration = state.nativeSubagentMonitor;
5371
5341
  state.nativeSubagentMonitor = void 0;
5342
+ if (registration) nativeSubagentMonitorSettlement = registration.unregister();
5343
+ await nativeSubagentMonitorSettlement;
5372
5344
  };
5373
- const registerNativeSubagentMonitor = (parentThreadId) => {
5374
- unregisterNativeSubagentMonitor();
5345
+ const registerNativeSubagentMonitor = async (parentThreadId) => {
5346
+ await unregisterNativeSubagentMonitor();
5347
+ connection.assertCurrent();
5348
+ const sessionKey = params.sessionKey;
5349
+ const storePath = params.sessionTarget?.storePath;
5350
+ const parentSession = sessionKey && storePath ? getSessionEntry({
5351
+ agentId: sessionAgentId,
5352
+ sessionKey,
5353
+ storePath,
5354
+ readConsistency: "latest",
5355
+ hydrateSkillPromptRefs: false
5356
+ }) : void 0;
5357
+ const historyOwner = createCodexNativeSubagentHistoryOwner({
5358
+ parentThreadId,
5359
+ sessionId: params.sessionId,
5360
+ ...parentSession?.sessionId === params.sessionId ? { lifecycleRevision: parentSession.lifecycleRevision } : {},
5361
+ binding: state.thread
5362
+ });
5363
+ const { bindingStore, bindingIdentity } = connection;
5364
+ const submissionStore = historyOwner ? {
5365
+ assertCurrent: () => {
5366
+ const current = bindingStore.read(bindingIdentity);
5367
+ if (!current || !matchesCodexNativeSubagentSubmissionBinding(current, historyOwner)) throw new Error("Native submission binding is no longer current.");
5368
+ if (historyOwner.lifecycleRevision && sessionKey && storePath) {
5369
+ if (getSessionEntry({
5370
+ agentId: sessionAgentId,
5371
+ sessionKey,
5372
+ storePath,
5373
+ readConsistency: "latest",
5374
+ hydrateSkillPromptRefs: false
5375
+ })?.lifecycleRevision !== historyOwner.lifecycleRevision) throw new Error("Native submission session lifecycle is no longer current.");
5376
+ }
5377
+ },
5378
+ read: () => bindingStore.readNativeSubagentSubmissions(bindingIdentity, historyOwner),
5379
+ record: (receipt, assertCurrent) => bindingStore.mutate(bindingIdentity, {
5380
+ kind: "record-native-subagent-submission",
5381
+ owner: historyOwner,
5382
+ receipt
5383
+ }, assertCurrent),
5384
+ consume: (receipt, assertCurrent) => bindingStore.mutate(bindingIdentity, {
5385
+ kind: "consume-native-subagent-submission",
5386
+ owner: historyOwner,
5387
+ receipt
5388
+ }, assertCurrent)
5389
+ } : void 0;
5375
5390
  state.nativeSubagentMonitor = codexNativeSubagentMonitorRuntime.register({
5376
5391
  client: state.client,
5377
5392
  parentThreadId,
5378
5393
  requesterSessionKey: params.sessionKey,
5379
5394
  taskRuntimeScope: params.agentHarnessTaskRuntimeScope,
5395
+ historyOwner,
5396
+ submissionStore,
5380
5397
  agentId: sessionAgentId,
5381
5398
  retainClient: () => retainSharedCodexAppServerClientIfCurrent(state.client),
5382
5399
  retainParentThread: (protectedThreadId) => protectCodexAppServerLiveThread(state.client, protectedThreadId),
@@ -5387,13 +5404,15 @@ function prepareCodexAttemptResources(prompt) {
5387
5404
  } } : {}
5388
5405
  });
5389
5406
  };
5390
- const releaseCurrentRoute = () => {
5407
+ const releaseCurrentRoute = async () => {
5408
+ state.releaseInferenceContext?.();
5409
+ state.releaseInferenceContext = void 0;
5391
5410
  state.detachRouteAbort();
5392
5411
  state.detachRouteAbort = () => void 0;
5393
5412
  state.turnRoute?.release();
5394
5413
  state.turnRoute = void 0;
5395
5414
  state.routeActivated = false;
5396
- unregisterNativeSubagentMonitor();
5415
+ await unregisterNativeSubagentMonitor();
5397
5416
  };
5398
5417
  const startupTimeoutMs = resolveCodexStartupTimeoutMs({
5399
5418
  timeoutMs: params.timeoutMs,
@@ -5401,8 +5420,11 @@ function prepareCodexAttemptResources(prompt) {
5401
5420
  });
5402
5421
  const requesterChannel = params.messageChannel ?? params.messageProvider;
5403
5422
  const requester = buildCodexHookRequester(params);
5404
- const buildNativeHookRelayFinalConfigPatch = (decision) => {
5405
- state.nativeHookRelay?.unregister();
5423
+ const buildNativeHookRelayFinalConfigPatch = async (decision) => {
5424
+ const previousRelay = state.nativeHookRelay;
5425
+ previousRelay?.unregister();
5426
+ await previousRelay?.drain();
5427
+ connection.assertCurrent();
5406
5428
  if (params.pluginHarnessToolPolicyRestricted === true) {
5407
5429
  state.nativeHookRelay = void 0;
5408
5430
  return {
@@ -5446,6 +5468,8 @@ function prepareCodexAttemptResources(prompt) {
5446
5468
  else pendingNativePreToolUseFailures.push(failure);
5447
5469
  }
5448
5470
  });
5471
+ await state.nativeHookRelay?.prepareInvocation();
5472
+ connection.assertCurrent();
5449
5473
  return {
5450
5474
  configPatch: state.nativeHookRelay ? buildCodexNativeHookRelayConfig({
5451
5475
  relay: state.nativeHookRelay,
@@ -5478,7 +5502,7 @@ function prepareCodexAttemptResources(prompt) {
5478
5502
  //#endregion
5479
5503
  //#region extensions/codex/src/app-server/run-attempt-route.ts
5480
5504
  async function prepareCodexAttemptRoute(resources, turnRuntime, notifications, handleServerRequest) {
5481
- const { prompt, state: resourceState, trajectoryRecorder, releaseCurrentRoute, registerNativeSubagentMonitor, activateNativePreToolUseFailureFallback, releaseSandboxExecEnvironment, releaseSharedClientLeaseOnce } = resources;
5505
+ const { prompt, state: resourceState, trajectoryRecorder, releaseCurrentRoute, registerNativeSubagentMonitor, activateNativePreToolUseFailureFallback, releaseSandboxExecEnvironment, releaseSharedClientLeaseOnce, runCleanupStep } = resources;
5482
5506
  const { connection } = prompt.context.runtime;
5483
5507
  const { runAbortController } = connection;
5484
5508
  const { state, turnIdRef, completeTurn } = turnRuntime;
@@ -5511,12 +5535,12 @@ async function prepareCodexAttemptRoute(resources, turnRuntime, notifications, h
5511
5535
  };
5512
5536
  const ensureCurrentThreadRoute = async () => {
5513
5537
  if (resourceState.turnRoute?.threadId !== resourceState.thread.threadId) {
5514
- releaseCurrentRoute();
5538
+ await releaseCurrentRoute();
5515
5539
  resourceState.turnRoute = resourceState.turnRouter.reserveThread({ threadId: resourceState.thread.threadId });
5516
5540
  }
5517
5541
  if (!resourceState.turnRoute) throw new Error("codex app-server turn route was not reserved");
5518
5542
  if (!resourceState.routeActivated) {
5519
- if (!resourceState.nativeSubagentMonitor) registerNativeSubagentMonitor(resourceState.thread.threadId);
5543
+ if (!resourceState.nativeSubagentMonitor) await registerNativeSubagentMonitor(resourceState.thread.threadId);
5520
5544
  resourceState.detachRouteAbort = attachRouteAbort(resourceState.turnRoute);
5521
5545
  await resourceState.turnRoute.activate({
5522
5546
  onNotificationReceived: noteNotificationReceived,
@@ -5531,8 +5555,18 @@ async function prepareCodexAttemptRoute(resources, turnRuntime, notifications, h
5531
5555
  await ensureCurrentThreadRoute();
5532
5556
  } catch (error) {
5533
5557
  activateNativePreToolUseFailureFallback();
5534
- releaseCurrentRoute();
5535
- resourceState.nativeHookRelay?.unregister();
5558
+ await runCleanupStep("codex-route-failure-route-release", releaseCurrentRoute);
5559
+ const relay = resourceState.nativeHookRelay;
5560
+ relay?.unregister();
5561
+ await runAgentCleanupStep({
5562
+ runId: connection.params.runId,
5563
+ sessionId: connection.params.sessionId,
5564
+ step: "codex-route-failure-native-hook-relay",
5565
+ log: embeddedAgentLog,
5566
+ cleanup: async () => {
5567
+ await relay?.drain();
5568
+ }
5569
+ });
5536
5570
  await releaseSandboxExecEnvironment();
5537
5571
  releaseSharedClientLeaseOnce();
5538
5572
  throw error;
@@ -5659,7 +5693,7 @@ async function prepareCodexAttemptRuntime(connection) {
5659
5693
  const authenticatedScheduledMode = params.trigger === "cron" && params.scheduledToolPolicy !== void 0 && Array.isArray(params.toolsAllow);
5660
5694
  const scheduledConfiguredMcpSurface = authenticatedScheduledMode && (bundleMcpThreadConfig.staticServerNames.length > 0 || mutable.startupBinding?.configuredMcpOwnershipVersion === 1);
5661
5695
  const cronCreatorAuthorityCapability = params.cronCreatorAuthorityCapability;
5662
- const hasFreshCreatorAuthority = cronCreatorAuthorityCapability?.active === true && !(cronCreatorAuthorityCapability.controlUiAdmin && cronCreatorAuthorityCapability.callerOrigin.kind === "unknown") && cronCreatorAuthorityCapability.runId === params.runId && !cronCreatorAuthorityCapability.signal.aborted;
5696
+ const hasFreshCreatorAuthority = cronCreatorAuthorityCapability?.active === true && !(cronCreatorAuthorityCapability.managementEntitlement && cronCreatorAuthorityCapability.callerOrigin.kind === "unknown") && cronCreatorAuthorityCapability.runId === params.runId && !cronCreatorAuthorityCapability.signal.aborted;
5663
5697
  const mayResolveScheduledConfiguredMcpCreatorAuthority = !authenticatedScheduledMode && canResolveScheduledConfiguredMcpCreatorAuthority({
5664
5698
  trigger: params.trigger,
5665
5699
  connectionClass: appServer.connectionClass,
@@ -5837,7 +5871,7 @@ const DYNAMIC_TOOL_TERMINAL_DIAGNOSTIC_TYPES = [
5837
5871
  "tool.execution.error",
5838
5872
  "tool.execution.blocked"
5839
5873
  ];
5840
- function createCodexAttemptServerRequestController(resources, turnRuntime, lifecycle) {
5874
+ function createCodexAttemptServerRequestController(resources, turnRuntime, lifecycle, waitForNativeItems) {
5841
5875
  const { prompt, state: resourceState, projectorRef, trajectoryRecorder } = resources;
5842
5876
  const { context } = prompt;
5843
5877
  const { runtime, attemptTools } = context;
@@ -5847,7 +5881,24 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
5847
5881
  const { compactionPlanState, toolBridge, toolOutcomeOrdinals, suppressedDynamicToolOutcomeOrdinals, allocateCodexToolOutcomeOrdinal } = attemptTools;
5848
5882
  const { state, turnIdRef, userInputBridgeRef, openClawDynamicToolExecutions, pendingOpenClawDynamicToolCompletionIds, noteProgress } = turnRuntime;
5849
5883
  const { emitExecutionPhaseOnce, scheduleTurnReleaseAfterTerminalDynamicTool, scheduleTerminalDynamicToolReleaseCheck } = lifecycle;
5850
- const handleServerRequest = async (request, scope, requestSignal = new AbortController().signal) => {
5884
+ let refreshDrain;
5885
+ let refreshStopping = false;
5886
+ const settlePluginRuntimeRefresh = async (turnId) => {
5887
+ if (!params.pluginRuntimeRefreshPending?.()) return;
5888
+ refreshDrain ??= createDeferred();
5889
+ state.pluginRuntimeRefreshStop = refreshDrain.promise;
5890
+ if (!refreshStopping && pendingOpenClawDynamicToolCompletionIds.size === 0) {
5891
+ refreshStopping = true;
5892
+ state.pendingTerminalDynamicToolRelease = void 0;
5893
+ turnRuntime.steeringQueueRef.current?.cancel();
5894
+ turnRuntime.interruptTurn(turnId, { locallyCompleted: true }).then(async (confirmed) => {
5895
+ if (!confirmed) throw new Error("Plugin reload could not confirm the previous Codex turn stopped.");
5896
+ await terminateCodexBackgroundTerminals(resourceState.client, resourceState.thread.threadId, params.oneShotCliRun === true, waitForNativeItems);
5897
+ }).then(refreshDrain.resolve, refreshDrain.reject).finally(turnRuntime.completeTurn);
5898
+ }
5899
+ await refreshDrain.promise;
5900
+ };
5901
+ const handleServerRequest = async (request, scope, requestSignal = new AbortController().signal, setExecutionTimeoutMs) => {
5851
5902
  const signal = AbortSignal.any([runAbortController.signal, requestSignal]);
5852
5903
  const turnId = turnIdRef.current;
5853
5904
  const projector = projectorRef.current;
@@ -5908,7 +5959,9 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
5908
5959
  const replayedExecution = openClawDynamicToolExecutions.get(call);
5909
5960
  if (replayedExecution) {
5910
5961
  markCurrentTurnRequestProgress();
5911
- return toCodexDynamicToolProtocolResponse(await replayedExecution);
5962
+ const response = await replayedExecution;
5963
+ await settlePluginRuntimeRefresh(turnId);
5964
+ return toCodexDynamicToolProtocolResponse(response);
5912
5965
  }
5913
5966
  const toolCallOrdinal = allocateCodexToolOutcomeOrdinal?.(call.callId);
5914
5967
  markCurrentTurnRequestProgress();
@@ -5948,8 +6001,10 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
5948
6001
  });
5949
6002
  const dynamicToolTimeoutMs = resolveDynamicToolCallTimeoutMs({
5950
6003
  call,
5951
- config: params.config
6004
+ config: params.config,
6005
+ toolBridge
5952
6006
  });
6007
+ setExecutionTimeoutMs?.(dynamicToolTimeoutMs);
5953
6008
  const toolStartedAt = Date.now();
5954
6009
  let terminalDiagnosticObserved = false;
5955
6010
  const unsubscribeToolDiagnosticObserver = onInternalDiagnosticEvent((event) => {
@@ -6055,7 +6110,8 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6055
6110
  durationMs: toolDurationMs
6056
6111
  });
6057
6112
  pendingOpenClawDynamicToolCompletionIds.delete(call.callId);
6058
- if (response.terminate === true && response.success) scheduleTurnReleaseAfterTerminalDynamicTool({
6113
+ if (params.pluginRuntimeRefreshPending?.()) await settlePluginRuntimeRefresh(turnId);
6114
+ else if (response.terminate === true && response.success) scheduleTurnReleaseAfterTerminalDynamicTool({
6059
6115
  call,
6060
6116
  response,
6061
6117
  durationMs: toolDurationMs
@@ -6081,6 +6137,7 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6081
6137
  sessionKey: params.sessionKey,
6082
6138
  durationMs: Math.max(0, Date.now() - toolStartedAt)
6083
6139
  });
6140
+ await settlePluginRuntimeRefresh(turnId);
6084
6141
  throw error;
6085
6142
  } finally {
6086
6143
  toolOutcomeOrdinals.delete(call.callId);
@@ -6100,7 +6157,7 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6100
6157
  //#region extensions/codex/src/app-server/attempt-runtime-artifact.ts
6101
6158
  async function verifyStartupArtifact(params) {
6102
6159
  if (!params.request) return;
6103
- const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-T-NwqeSH.js");
6160
+ const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-Dy38Z5iU.mjs");
6104
6161
  const runtimeArtifact = readCodexAppServerClientRuntimeArtifact(params.client);
6105
6162
  const expected = params.request.expected;
6106
6163
  const matchesExpected = !expected || runtimeArtifact?.id === expected.id && runtimeArtifact.fingerprint === expected.fingerprint;
@@ -6123,7 +6180,7 @@ function startCodexComputerUseHealthMonitor(params) {
6123
6180
  reason: params.config.enabled ? "health_disabled" : "disabled"
6124
6181
  };
6125
6182
  }
6126
- const fingerprint = buildComputerUseHealthMonitorFingerprint(params.config);
6183
+ const fingerprint = buildComputerUseHealthMonitorFingerprint(params.config, params.tools);
6127
6184
  const intervalMs = params.config.healthCheckIntervalMinutes * 6e4;
6128
6185
  if (existing?.fingerprint === fingerprint) return {
6129
6186
  started: false,
@@ -6135,7 +6192,7 @@ function startCodexComputerUseHealthMonitor(params) {
6135
6192
  fingerprint,
6136
6193
  intervalMs,
6137
6194
  timer: setInterval(() => {
6138
- runCodexComputerUseHealthProbe(params.client, params.config, monitor);
6195
+ runCodexComputerUseHealthProbe(params.client, params.config, monitor, params.tools);
6139
6196
  }, intervalMs),
6140
6197
  disposeCloseHandler: () => void 0,
6141
6198
  running: false
@@ -6151,21 +6208,23 @@ function startCodexComputerUseHealthMonitor(params) {
6151
6208
  intervalMs
6152
6209
  };
6153
6210
  }
6154
- function buildComputerUseHealthMonitorFingerprint(config) {
6211
+ function buildComputerUseHealthMonitorFingerprint(config, tools) {
6155
6212
  return JSON.stringify({
6156
6213
  autoRepair: config.autoRepair,
6157
6214
  healthCheckIntervalMinutes: config.healthCheckIntervalMinutes,
6158
6215
  liveTestTimeoutMs: config.liveTestTimeoutMs,
6159
6216
  mcpServerName: config.mcpServerName,
6160
- toolCallTimeoutMs: config.toolCallTimeoutMs
6217
+ toolCallTimeoutMs: config.toolCallTimeoutMs,
6218
+ tools: tools?.toSorted()
6161
6219
  });
6162
6220
  }
6163
- async function runCodexComputerUseHealthProbe(client, config, monitor) {
6221
+ async function runCodexComputerUseHealthProbe(client, config, monitor, tools) {
6164
6222
  if (monitor.running) return;
6165
6223
  monitor.running = true;
6166
6224
  try {
6167
6225
  const { liveTest, repair } = await runCodexComputerUseLiveTest({
6168
6226
  config,
6227
+ tools,
6169
6228
  request: async (method, requestParams, requestOptions) => await client.request(method, requestParams, { timeoutMs: requestOptions?.timeoutMs ?? config.liveTestTimeoutMs })
6170
6229
  });
6171
6230
  if (!liveTest.ok) {
@@ -6368,6 +6427,7 @@ async function startCodexAttemptThread(params) {
6368
6427
  try {
6369
6428
  const attemptParams = params.buildAttemptParams();
6370
6429
  params.assertCurrent?.();
6430
+ if (startupAbandonController.signal.aborted) throw new CodexAppServerStartupError("aborted");
6371
6431
  startupClient = await params.attemptClientFactory({
6372
6432
  assertCurrent: params.assertCurrent,
6373
6433
  startOptions: params.appServer.start,
@@ -6416,15 +6476,16 @@ async function startCodexAttemptThread(params) {
6416
6476
  config: params.config
6417
6477
  });
6418
6478
  const turnRouter = getCodexAppServerTurnRouter(activeStartupClient);
6479
+ let computerUseTools = [];
6419
6480
  try {
6420
- await ensureCodexComputerUse({
6481
+ computerUseTools = (await ensureCodexComputerUse({
6421
6482
  client: activeStartupClient,
6422
6483
  pluginConfig: params.pluginConfig,
6423
6484
  config: params.config,
6424
6485
  agentDir: params.agentDir,
6425
6486
  timeoutMs: params.appServer.requestTimeoutMs,
6426
6487
  signal: startupAbandonController.signal
6427
- });
6488
+ })).tools;
6428
6489
  } catch (error) {
6429
6490
  if (startupAbandonController.signal.aborted || isCodexAppServerStartSelectionChangedError(error)) throw error;
6430
6491
  throw new AgentHarnessPreflightError(`Codex Computer Use readiness failed: ${formatErrorMessage(error)}`, {
@@ -6586,7 +6647,8 @@ async function startCodexAttemptThread(params) {
6586
6647
  startupSandboxEnvironmentAcquired = false;
6587
6648
  startCodexComputerUseHealthMonitor({
6588
6649
  client: activeStartupClient,
6589
- config: params.computerUseConfig
6650
+ config: params.computerUseConfig,
6651
+ tools: computerUseTools
6590
6652
  });
6591
6653
  startupAttemptSucceeded = true;
6592
6654
  return {
@@ -6621,7 +6683,6 @@ async function startCodexAttemptThread(params) {
6621
6683
  const sharedClient = clearSharedCodexAppServerClientIfCurrentAndUnclaimed(startupClientForAbandonedRequestCleanup);
6622
6684
  if (sharedClient.found && !sharedClient.closed) startupClientForAbandonedRequestCleanup = void 0;
6623
6685
  }
6624
- throw error;
6625
6686
  } finally {
6626
6687
  if (!startupAttemptSucceeded) {
6627
6688
  if (releaseSharedClientLease === startupClientLease) releaseSharedClientLease = void 0;
@@ -6632,13 +6693,20 @@ async function startCodexAttemptThread(params) {
6632
6693
  }
6633
6694
  }
6634
6695
  }
6696
+ if (startupAttemptError instanceof CodexThreadClientReplacementError && startupClient) {
6697
+ if (!(await startupClient.closeAndWait()).exited) throw new AgentHarnessPreflightError("The previous conversation process did not confirm shutdown; the conversation was preserved.");
6698
+ }
6699
+ throw startupAttemptError;
6635
6700
  };
6701
+ let replacedSettledFailureClient = false;
6636
6702
  for (let attempt = 1; attempt <= CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS; attempt += 1) try {
6637
6703
  return await startupAttempt();
6638
6704
  } catch (error) {
6639
6705
  const selectionChanged = isCodexAppServerStartSelectionChangedError(error);
6640
- if (startupAbandonController.signal.aborted || !selectionChanged && !isCodexAppServerConnectionClosedError(error)) throw error;
6641
- const refreshedSharedClient = selectionChanged ? retireSharedCodexAppServerClientIfCurrent(attemptedClient) : clearSharedCodexAppServerClientIfCurrent(attemptedClient);
6706
+ const clientRetired = error instanceof CodexThreadClientReplacementError;
6707
+ if (startupAbandonController.signal.aborted || clientRetired && replacedSettledFailureClient || !clientRetired && !selectionChanged && !isCodexAppServerConnectionClosedError(error)) throw error;
6708
+ replacedSettledFailureClient ||= clientRetired;
6709
+ const refreshedSharedClient = clientRetired ? void 0 : selectionChanged ? retireSharedCodexAppServerClientIfCurrent(attemptedClient) : clearSharedCodexAppServerClientIfCurrent(attemptedClient);
6642
6710
  if (startupClientForAbandonedRequestCleanup === attemptedClient) startupClientForAbandonedRequestCleanup = void 0;
6643
6711
  if (attempt >= CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS) {
6644
6712
  embeddedAgentLog.warn(selectionChanged ? "codex app-server executable selection kept changing during startup; retries exhausted" : "codex app-server connection closed during startup; retries exhausted", {
@@ -6649,8 +6717,8 @@ async function startCodexAttemptThread(params) {
6649
6717
  });
6650
6718
  throw error;
6651
6719
  }
6652
- const retryDelayMs = selectionChanged ? 0 : 1e3 * 2 ** (attempt - 1);
6653
- embeddedAgentLog.warn(selectionChanged ? "codex app-server executable selection changed during startup; restarting app-server and retrying" : "codex app-server connection closed during startup; restarting app-server and retrying", {
6720
+ const retryDelayMs = selectionChanged || clientRetired ? 0 : 1e3 * 2 ** (attempt - 1);
6721
+ embeddedAgentLog.warn(clientRetired ? "codex app-server retired a settled failed client; resuming on a fresh client" : selectionChanged ? "codex app-server executable selection changed during startup; restarting app-server and retrying" : "codex app-server connection closed during startup; restarting app-server and retrying", {
6654
6722
  attempt,
6655
6723
  nextAttempt: attempt + 1,
6656
6724
  maxAttempts: CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS,
@@ -6681,10 +6749,6 @@ async function startCodexAttemptThread(params) {
6681
6749
  params.signal.removeEventListener("abort", abandonStartupAcquire);
6682
6750
  }
6683
6751
  }
6684
- function shouldRetireCodexStartupClient(error, spawnedBy, signal) {
6685
- if (signal.aborted || isCodexAppServerStartupError(error) || isCodexAppServerRequestTimeoutError(error)) return true;
6686
- return !isCodexAppServerStartSelectionChangedError(error) && !isCodexAppServerOverloadError(error) && !(error instanceof AgentHarnessPreflightError && error.scope === void 0) && (isCodexAppServerBrokenPipeError(error) || !spawnedBy);
6687
- }
6688
6752
  //#endregion
6689
6753
  //#region extensions/codex/src/app-server/run-attempt-start.ts
6690
6754
  async function startCodexAttemptRuntime(resources) {
@@ -6772,10 +6836,11 @@ async function startCodexAttemptRuntime(resources) {
6772
6836
  if (usesSupervisionConnection && (state.thread.connectionScope !== "supervision" || state.thread.supervisionSourceThreadId !== connection.mutable.startupBinding?.supervisionSourceThreadId)) throw new Error("Codex supervised thread lost its private connection ownership");
6773
6837
  if (state.thread.lifecycle.action === "started" || state.thread.lifecycle.action === "forked") {
6774
6838
  const activePolicy = resolveReviewerPolicyContext(state.thread);
6775
- const activeConfig = resolveRuntimeOptionsForCurrentBinding({
6839
+ const activeConfig = await resolveRuntimeOptionsForCurrentBinding({
6776
6840
  modelProvider: activePolicy.modelProvider,
6777
6841
  model: activePolicy.model
6778
6842
  });
6843
+ connection.assertCurrent();
6779
6844
  const activeAppServer = resolveCodexAppServerForModelProvider({
6780
6845
  appServer: activeConfig,
6781
6846
  provider: activePolicy.modelProvider,
@@ -6816,12 +6881,16 @@ async function startCodexAttemptRuntime(resources) {
6816
6881
  toolCount: flattenCodexDynamicToolFunctions(toolBridge.specs).length
6817
6882
  });
6818
6883
  connection.mutable.pluginAppServer = pluginAppServer;
6884
+ await resources.registerNativeSubagentMonitor(state.thread.threadId);
6819
6885
  } catch (error) {
6820
6886
  await runCleanupStep("codex-start-failure-hook-fallback", activateNativePreToolUseFailureFallback);
6821
6887
  await runCleanupStep("codex-start-failure-route-release", releaseCurrentRoute);
6822
6888
  const nativeHookRelay = state.nativeHookRelay;
6823
6889
  state.nativeHookRelay = void 0;
6824
- await runCleanupStep("codex-start-failure-native-hook-relay", () => nativeHookRelay?.unregister());
6890
+ await runCleanupStep("codex-start-failure-native-hook-relay", async () => {
6891
+ nativeHookRelay?.unregister();
6892
+ await nativeHookRelay?.drain();
6893
+ });
6825
6894
  await runCleanupStep("codex-start-failure-sandbox-release", releaseSandboxExecEnvironment);
6826
6895
  await runCleanupStep("codex-start-failure-shared-client-release", releaseSharedClientLeaseAndRetireOneShotClient);
6827
6896
  throw error instanceof CodexThreadPolicyHandoffError ? error : state.executionDisconnectError ?? error;
@@ -7047,6 +7116,45 @@ async function prepareCodexAttemptTools(runtime) {
7047
7116
  ...params.memberRoleIds?.length ? { roleIds: [...params.memberRoleIds] } : {}
7048
7117
  };
7049
7118
  const hasRequester = Object.keys(requester).length > 0;
7119
+ const requestInteractiveMcpApproval = async (approval) => {
7120
+ const allowedDecisions = approval.mode === "prompt" ? ["allow-once", "deny"] : [
7121
+ "allow-once",
7122
+ "allow-always",
7123
+ "deny"
7124
+ ];
7125
+ const outcome = await requestPluginApprovalOutcome({
7126
+ hostCapabilities: params.hostCapabilities,
7127
+ signal: approval.signal,
7128
+ title: `Run MCP tool ${approval.serverName}/${approval.toolName}`,
7129
+ description: `Codex approval mode "${approval.mode}" requires an operator decision before this MCP tool runs. ${formatMcpCodexApprovalRemedy(approval.serverName)}`,
7130
+ allowedDecisions,
7131
+ toolName: approval.safeToolName,
7132
+ toolCallId: approval.toolCallId,
7133
+ mcpTool: {
7134
+ server: approval.serverName,
7135
+ tool: approval.toolName
7136
+ },
7137
+ isMcpToolApprovalActive: approval.isActive
7138
+ });
7139
+ if (outcome !== "approved-once" && outcome !== "approved-session") throw new Error(`${approval.serverName}/${approval.toolName}: interactive Codex approval (${approval.mode}) was not granted: ${outcome}`);
7140
+ };
7141
+ const requestRequesterMcpApproval = async (approval) => {
7142
+ const outcome = await requestPluginApprovalOutcome({
7143
+ hostCapabilities: params.hostCapabilities,
7144
+ signal: approval.signal,
7145
+ title: `Run MCP tool ${approval.serverName}/${approval.toolName}`,
7146
+ description: `Codex approval mode "${approval.mode}" requires an operator decision before this MCP tool runs. ${formatMcpCodexApprovalRemedy(approval.serverName)}`,
7147
+ allowedDecisions: ["allow-once", "deny"],
7148
+ toolName: approval.safeToolName,
7149
+ toolCallId: approval.toolCallId,
7150
+ mcpTool: {
7151
+ server: approval.serverName,
7152
+ tool: approval.toolName
7153
+ },
7154
+ isMcpToolApprovalActive: approval.isActive
7155
+ });
7156
+ if (outcome !== "approved-once" && outcome !== "approved-session") throw new Error(`${approval.serverName}/${approval.toolName}: interactive Codex approval (${approval.mode}) was not granted: ${outcome}`);
7157
+ };
7050
7158
  const configuredMcp = configuredMcpSurface ? await materializeStaticMcpToolsForHarnessRun({
7051
7159
  sessionId: params.sessionId,
7052
7160
  sessionKey: params.sessionKey,
@@ -7060,28 +7168,7 @@ async function prepareCodexAttemptTools(runtime) {
7060
7168
  toolOverrides: codexMcpToolOverrides,
7061
7169
  autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
7062
7170
  projectedMcpServers: bundleMcpThreadConfig.configPatch?.mcp_servers,
7063
- ...configuredMcpSurface === "transient" ? { requestInteractiveCodexApproval: async (approval) => {
7064
- const allowedDecisions = approval.mode === "prompt" ? ["allow-once", "deny"] : [
7065
- "allow-once",
7066
- "allow-always",
7067
- "deny"
7068
- ];
7069
- const outcome = await requestPluginApprovalOutcome({
7070
- hostCapabilities: params.hostCapabilities,
7071
- signal: approval.signal,
7072
- title: `Run MCP tool ${approval.serverName}/${approval.toolName}`,
7073
- description: `Codex approval mode "${approval.mode}" requires an operator decision before this MCP tool runs. ${formatMcpCodexApprovalRemedy(approval.serverName)}`,
7074
- allowedDecisions,
7075
- toolName: approval.safeToolName,
7076
- toolCallId: approval.toolCallId,
7077
- mcpTool: {
7078
- server: approval.serverName,
7079
- tool: approval.toolName
7080
- },
7081
- isMcpToolApprovalActive: approval.isActive
7082
- });
7083
- if (outcome !== "approved-once" && outcome !== "approved-session") throw new Error(`${approval.serverName}/${approval.toolName}: interactive Codex approval (${approval.mode}) was not granted: ${outcome}`);
7084
- } } : {},
7171
+ ...configuredMcpSurface === "transient" ? { requestInteractiveCodexApproval: requestInteractiveMcpApproval } : {},
7085
7172
  policyContext,
7086
7173
  warn: (message) => embeddedAgentLog.warn(message)
7087
7174
  }) : void 0;
@@ -7104,6 +7191,8 @@ async function prepareCodexAttemptTools(runtime) {
7104
7191
  cfg: params.config,
7105
7192
  manifestRegistry: bundleManifestRegistry,
7106
7193
  toolOverrides: codexMcpToolOverrides,
7194
+ autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
7195
+ requestInteractiveCodexApproval: requestRequesterMcpApproval,
7107
7196
  requesterSenderId: params.senderId,
7108
7197
  agentAccountId: params.agentAccountId,
7109
7198
  messageChannel: params.messageChannel ?? params.messageProvider,
@@ -7274,7 +7363,7 @@ async function resolveCodexExplicitSkillInputs(params) {
7274
7363
  //#region extensions/codex/src/app-server/run-attempt-turn-request.ts
7275
7364
  async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurrentThreadRoute, waitForActiveNativeTurnCompletion) {
7276
7365
  const { prompt, state: resourceState, releaseCurrentRoute } = resources;
7277
- const { context, turnState, buildRenderedCodexDeveloperInstructions } = prompt;
7366
+ const { context, turnState, buildRenderedCodexDeveloperInstructions, nativeHistoryProvenancePrefix } = prompt;
7278
7367
  const { runtime, attemptTools, hookContextWindowFields, workspaceBootstrapContext } = context;
7279
7368
  const { connection, runtimeParams, effectiveRuntimeProviderId, effectiveRuntimeModelId } = runtime;
7280
7369
  const { tools, toolBridge } = attemptTools;
@@ -7332,14 +7421,14 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7332
7421
  connection.mutable.pluginAppServer = turnAppServer;
7333
7422
  const references = prepareWorkspaceReferences();
7334
7423
  const referencesRetained = turnState.codexTurnPromptText.includes(workspaceBootstrapContext.promptContext ?? "");
7335
- const turnStartParams = buildTurnStartParams({
7336
- ...runtimeParams,
7337
- images: [...prompt.contextImages, ...runtimeParams.images ?? []]
7338
- }, {
7424
+ const inferenceRoute = usesSupervisionConnection ? void 0 : getCodexInferenceThread(resourceState.client, resourceState.thread.threadId);
7425
+ const turnStartParams = buildTurnStartParams(runtimeParams, {
7339
7426
  threadId: resourceState.thread.threadId,
7340
7427
  cwd: resourceState.codexExecutionCwd,
7341
7428
  appServer: turnAppServer,
7342
7429
  promptText: turnState.codexTurnPromptText,
7430
+ historyProvenancePrefix: nativeHistoryProvenancePrefix,
7431
+ contextImageGroups: prompt.contextImageGroups,
7343
7432
  explicitSkillInputs,
7344
7433
  sandboxPolicy: resourceState.codexSandboxPolicy,
7345
7434
  environmentSelection: resourceState.codexEnvironmentSelection,
@@ -7352,10 +7441,49 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7352
7441
  skillsCollaborationInstructions: context.skillsCollaborationInstructions,
7353
7442
  memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions,
7354
7443
  preserveNativeTurnSettings: usesSupervisionConnection,
7444
+ parentLocalEgress: inferenceRoute !== void 0,
7355
7445
  messageToolAvailable: toolBridge.availableTools.some((tool) => tool.name === "message"),
7356
7446
  requireExplicitMessageTarget: attemptTools.requireExplicitMessageTarget,
7357
7447
  sessionStatusAvailable: toolBridge.availableTools.some((tool) => tool.name === "session_status")
7358
7448
  });
7449
+ if (inferenceRoute) {
7450
+ prompt.setParentLocalEgress();
7451
+ resourceState.releaseInferenceContext?.();
7452
+ const inferenceThread = resourceState.thread;
7453
+ const registration = inferenceRoute.context.register({
7454
+ threadId: resourceState.thread.threadId,
7455
+ text: buildCodexParentLocalInstructions(runtimeParams, {
7456
+ turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
7457
+ skillsCollaborationInstructions: context.skillsCollaborationInstructions,
7458
+ memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions
7459
+ }) ?? "",
7460
+ signal: runAbortController.signal,
7461
+ assertCurrent: () => {
7462
+ params.hostCapabilities.assertActive();
7463
+ connection.assertCurrent();
7464
+ if (resourceState.thread !== inferenceThread || getCodexInferenceThread(resourceState.client, inferenceThread.threadId) !== inferenceRoute) throw new Error("Codex inference thread ownership changed");
7465
+ inferenceThread.liveThreadOwnership?.assertCurrent();
7466
+ }
7467
+ });
7468
+ resourceState.releaseInferenceContext = registration.release;
7469
+ turnStartParams.responsesapiClientMetadata = {
7470
+ ...turnStartParams.responsesapiClientMetadata,
7471
+ [CODEX_INFERENCE_GENERATION_KEY]: registration.generation
7472
+ };
7473
+ } else if (!usesSupervisionConnection) {
7474
+ embeddedAgentLog.warn("Codex parent-local egress workaround is unavailable for this connection or native network profile; legacy collaboration delivery is not guaranteed.");
7475
+ prompt.systemPromptReport.source = "estimate";
7476
+ prompt.systemPromptReport.injectedWorkspaceFiles = prompt.systemPromptReport.injectedWorkspaceFiles.map((file) => [
7477
+ "SOUL.MD",
7478
+ "IDENTITY.MD",
7479
+ "USER.MD"
7480
+ ].includes(file.name.toUpperCase()) ? {
7481
+ ...file,
7482
+ injectionStatus: "native_unverified",
7483
+ injectedChars: null,
7484
+ truncated: null
7485
+ } : file);
7486
+ }
7359
7487
  codexModelCallDiagnostics.setRequestPayloadBytes(utf8JsonByteLength(turnStartParams));
7360
7488
  recordCodexTrajectoryContext(resources.trajectoryRecorder, {
7361
7489
  attempt: params,
@@ -7398,7 +7526,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7398
7526
  });
7399
7527
  if (resourceState.startupClientUnsafe) await retireUnsafeCodexTurnClientBestEffort(resourceState.client, "startup interrupt");
7400
7528
  } finally {
7401
- releaseCurrentRoute();
7529
+ await releaseCurrentRoute();
7402
7530
  }
7403
7531
  else await activeTurnRoute.cancelTurn();
7404
7532
  throw error;
@@ -7425,7 +7553,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7425
7553
  systemPrompt: buildRenderedCodexDeveloperInstructions(),
7426
7554
  prompt: turnState.codexTurnPromptText,
7427
7555
  historyMessages: prompt.codexModelInputHistoryMessages,
7428
- imagesCount: prompt.contextImages.length + (params.images?.length ?? 0),
7556
+ imagesCount: prompt.contextImageGroups.reduce((count, group) => count + group.images.length, 0) + (params.images?.length ?? 0),
7429
7557
  tools
7430
7558
  });
7431
7559
  return {
@@ -7605,9 +7733,19 @@ async function startCodexAttemptTurn(resources, turnRuntime, notifications, requ
7605
7733
  cleanup: async () => closeCodexStartupClientBestEffort(resourceState.client)
7606
7734
  });
7607
7735
  }
7608
- releaseCurrentRoute();
7736
+ await releaseCurrentRoute();
7609
7737
  activateNativePreToolUseFailureFallback();
7610
- resourceState.nativeHookRelay?.unregister();
7738
+ const relay = resourceState.nativeHookRelay;
7739
+ relay?.unregister();
7740
+ await runAgentCleanupStep({
7741
+ runId: params.runId,
7742
+ sessionId: params.sessionId,
7743
+ step: "codex-turn-start-failure-native-hook-relay",
7744
+ log: embeddedAgentLog,
7745
+ cleanup: async () => {
7746
+ await relay?.drain();
7747
+ }
7748
+ });
7611
7749
  await releaseSandboxExecEnvironment();
7612
7750
  await runAgentCleanupStep({
7613
7751
  runId: params.runId,
@@ -7720,36 +7858,30 @@ function createCodexAttemptDeadlineController(params) {
7720
7858
  //#endregion
7721
7859
  //#region extensions/codex/src/app-server/run-attempt-turn-state.ts
7722
7860
  const CODEX_NATIVE_HOOK_RELAY_RENEW_INTERVAL_MS = 6e4;
7861
+ var CodexAttemptState = class {
7862
+ constructor() {
7863
+ this.completed = false;
7864
+ this.abortCleanup = Promise.resolve();
7865
+ this.localCompletionRequested = false;
7866
+ this.terminalTurnNotificationQueued = false;
7867
+ this.sawCodexInterruptMarker = false;
7868
+ this.clientClosedAbort = false;
7869
+ this.shouldDelayNativeHookRelayUnregister = false;
7870
+ this.lifecycleStarted = false;
7871
+ this.lifecycleTerminalEmitted = false;
7872
+ this.nativeHookRelayLastRenewedAt = 0;
7873
+ this.activeAppServerTurnRequests = 0;
7874
+ this.activeLocalProjections = 0;
7875
+ this.projectionClosed = false;
7876
+ this.terminalDynamicToolReleaseCheckScheduled = false;
7877
+ this.currentTurnHadNonTerminalDynamicToolResult = false;
7878
+ }
7879
+ };
7723
7880
  function createCodexAttemptTurnState(resources) {
7724
7881
  const { prompt, state: resourceState, projectorRef, trajectoryRecorder, startupTimeoutMs } = resources;
7725
7882
  const { connection } = prompt.context.runtime;
7726
7883
  const { params, options, runAbortController } = connection;
7727
- const state = {
7728
- latestStartupErrorNotification: void 0,
7729
- rateLimitsRevisionBeforeLastTurnStart: void 0,
7730
- completed: false,
7731
- abortCleanup: Promise.resolve(),
7732
- permissionChangeRestart: void 0,
7733
- localCompletionRequested: false,
7734
- terminalTurnNotificationQueued: false,
7735
- sawCodexInterruptMarker: false,
7736
- timeout: void 0,
7737
- settlementWarning: void 0,
7738
- pendingSettlementStage: void 0,
7739
- clientClosedPromptError: void 0,
7740
- clientClosedDiagnostic: void 0,
7741
- clientClosedAbort: false,
7742
- shouldDelayNativeHookRelayUnregister: false,
7743
- lifecycleStarted: false,
7744
- lifecycleTerminalEmitted: false,
7745
- nativeHookRelayLastRenewedAt: 0,
7746
- activeAppServerTurnRequests: 0,
7747
- activeLocalProjections: 0,
7748
- projectionClosed: false,
7749
- pendingTerminalDynamicToolRelease: void 0,
7750
- terminalDynamicToolReleaseCheckScheduled: false,
7751
- currentTurnHadNonTerminalDynamicToolResult: false
7752
- };
7884
+ const state = new CodexAttemptState();
7753
7885
  const { promise: completion, resolve: resolveCompletion } = createDeferred();
7754
7886
  const settlementExpired = createDeferred();
7755
7887
  const pendingOpenClawDynamicToolCompletionIds = /* @__PURE__ */ new Set();
@@ -7775,19 +7907,28 @@ function createCodexAttemptTurnState(resources) {
7775
7907
  if (!completed) await closeCodexStartupClientBestEffort(resourceState.client);
7776
7908
  return completed;
7777
7909
  };
7910
+ let pendingNativeHookRenewal;
7778
7911
  const renewNativeHookRelayForTurnProgress = () => {
7779
- if (!resourceState.nativeHookRelay || options.nativeHookRelay?.ttlMs !== void 0) return;
7912
+ if (!resourceState.nativeHookRelay || options.nativeHookRelay?.ttlMs !== void 0 || pendingNativeHookRenewal) return;
7780
7913
  const now = Date.now();
7781
7914
  const renewsRecently = now - state.nativeHookRelayLastRenewedAt < CODEX_NATIVE_HOOK_RELAY_RENEW_INTERVAL_MS;
7782
7915
  const expiresSoon = now >= resourceState.nativeHookRelay.expiresAtMs - CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS;
7783
7916
  if (renewsRecently && !expiresSoon) return;
7784
- state.nativeHookRelayLastRenewedAt = now;
7785
- resourceState.nativeHookRelay.renew(resolveCodexNativeHookRelayTtlMs({
7917
+ const relay = resourceState.nativeHookRelay;
7918
+ relay.renew(resolveCodexNativeHookRelayTtlMs({
7786
7919
  explicitTtlMs: void 0,
7787
7920
  attemptTimeoutMs: params.timeoutMs,
7788
7921
  startupTimeoutMs,
7789
7922
  turnStartTimeoutMs: params.timeoutMs
7790
7923
  }));
7924
+ pendingNativeHookRenewal = relay.drain();
7925
+ pendingNativeHookRenewal.then(() => {
7926
+ pendingNativeHookRenewal = void 0;
7927
+ if (resourceState.nativeHookRelay === relay) state.nativeHookRelayLastRenewedAt = now;
7928
+ }, (error) => {
7929
+ pendingNativeHookRenewal = void 0;
7930
+ embeddedAgentLog.debug("native hook relay renewal did not drain", { error });
7931
+ });
7791
7932
  };
7792
7933
  const noteProgress = (reason) => {
7793
7934
  if (state.completed || state.projectionClosed || runAbortController.signal.aborted) return;
@@ -7882,7 +8023,7 @@ async function runCodexAppServerAttempt(params, options) {
7882
8023
  try {
7883
8024
  const lifecycle = createCodexAttemptLifecycleController(resources, turnRuntime);
7884
8025
  const notifications = createCodexAttemptNotificationController(resources, turnRuntime, lifecycle);
7885
- const serverRequests = createCodexAttemptServerRequestController(resources, turnRuntime, lifecycle);
8026
+ const serverRequests = createCodexAttemptServerRequestController(resources, turnRuntime, lifecycle, notifications.waitForNativeTerminalItems);
7886
8027
  const { ensureCurrentThreadRoute } = await preparation.measure("thread-route", () => prepareCodexAttemptRoute(resources, turnRuntime, notifications, serverRequests.handleServerRequest));
7887
8028
  const turnRequest = await preparation.measure("turn-request", () => prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurrentThreadRoute, notifications.waitForActiveNativeTurnCompletion));
7888
8029
  preparation.ready();
@@ -7891,10 +8032,22 @@ async function runCodexAppServerAttempt(params, options) {
7891
8032
  const activeTurn = activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notifications, turnStart.turn);
7892
8033
  let finalizedResult;
7893
8034
  try {
7894
- await activeTurn.ready;
7895
- finalizedResult = await finalizeCodexAttempt(resources, turnRuntime, lifecycle, notifications, turnRequest, activeTurn);
7896
- } finally {
7897
- await cleanupCodexAttempt(resources, turnRuntime, lifecycle, turnRequest, activeTurn);
8035
+ try {
8036
+ await activeTurn.ready;
8037
+ finalizedResult = await finalizeCodexAttempt(resources, turnRuntime, lifecycle, notifications, turnRequest, activeTurn);
8038
+ } finally {
8039
+ await cleanupCodexAttempt(resources, turnRuntime, lifecycle, turnRequest, activeTurn);
8040
+ }
8041
+ } catch (error) {
8042
+ if (!finalizedResult || !turnRuntime.state.pluginRuntimeRefreshStop) throw error;
8043
+ const original = attemptTerminal.project(finalizedResult.terminal).promptError;
8044
+ finalizedResult.terminal = attemptTerminal.merge(finalizedResult.terminal, {
8045
+ kind: "failed",
8046
+ source: "prompt",
8047
+ error: new AggregateError(original ? [original, error] : [error], "Plugin runtime changed, but native continuation failed. Inspect the existing thread before continuing; do not repeat completed actions.")
8048
+ });
8049
+ delete finalizedResult.pluginRuntimeRefreshMessages;
8050
+ delete finalizedResult.settledTurnFinalizationContext;
7898
8051
  }
7899
8052
  if (resources.state.executionDisconnectError && !connection.terminalState.explicitCancellationObserved) throw resources.state.executionDisconnectError;
7900
8053
  return finalizedResult;