@openclaw/codex 2026.9.4 → 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 (148) 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-CvT8tW5i.js → .setup/apply-CJ0ZfmBG.mjs} +11 -11
  5. package/dist/.setup/async-questions-DdhOCwGi.mjs +27 -0
  6. package/dist/{attempt-client-cleanup-DKHzbwt5.js → .setup/attempt-client-cleanup-BpYKdTA0.mjs} +29 -14
  7. package/dist/{attempt-context-D44yeDII.js → .setup/attempt-context-VXVwTCfS.mjs} +5 -5
  8. package/dist/.setup/attempt-terminal-gZrxQ35N.mjs +5 -0
  9. package/dist/{auth-binding-CWlKVccJ.js → .setup/auth-binding-DhLWa_7K.mjs} +1 -1
  10. package/dist/{auth-cache-key-7orQae_j.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-C_Hneydj.js → .setup/bounded-turn-BtlZcivC.mjs} +16 -11
  15. package/dist/{build-state-BCmg9-5p.js → .setup/build-state-Xx9ybZqa.mjs} +1 -1
  16. package/dist/{capabilities-8vx68WLH.js → .setup/capabilities-_vXcZGSx.mjs} +1 -1
  17. package/dist/{client-B57KWPQx.js → .setup/client-vXs2929Q.mjs} +332 -163
  18. package/dist/{command-dispatch-BpduNGVf.js → .setup/command-dispatch-naHIZwwF.mjs} +3 -3
  19. package/dist/{command-formatters-lxlkNZgU.js → .setup/command-formatters-CGEkdawF.mjs} +2 -2
  20. package/dist/{command-handlers-tiL9iWj7.js → .setup/command-handlers-BtAJEW1X.mjs} +59 -42
  21. package/dist/{command-rpc-CR5EOEZX.js → .setup/command-rpc-DHFpn4le.mjs} +22 -13
  22. package/dist/{compact-B_H3AOd7.js → .setup/compact-C3i3qlzj.mjs} +28 -43
  23. package/dist/{config-oIORaQ5T.js → .setup/config-CedDWjM-.mjs} +5 -4
  24. package/dist/{config-options-CXMq1T-C.js → .setup/config-options-BsanJ8QG.mjs} +6 -418
  25. package/dist/{protocol-5bh1G-H7.js → .setup/config-parsing-CcB9iPoq.mjs} +9 -51
  26. package/dist/{config-runtime-D0zGNIHu.js → .setup/config-runtime-CeAhl_h4.mjs} +2 -2
  27. package/dist/.setup/config-security-BRQ2mgW9.mjs +465 -0
  28. package/dist/{conversation-binding-DsB4-O7U.js → .setup/conversation-binding-DhzrpTM6.mjs} +23 -21
  29. package/dist/{conversation-binding-data-BiodpIzq.js → .setup/conversation-binding-data-CrcyZk6O.mjs} +1 -1
  30. package/dist/{conversation-control-CtUu1b3m.js → .setup/conversation-control-DN53ns41.mjs} +17 -13
  31. package/dist/.setup/cyber-failover-DYwbmf1o.mjs +123 -0
  32. package/dist/.setup/cyber-failover-notice-e9G3J9-e.mjs +17 -0
  33. package/dist/{dynamic-tools-CmN5RAip.js → .setup/dynamic-tools-D16lOp67.mjs} +101 -55
  34. package/dist/{effective-mcp-catalog-Bd73bqA8.js → .setup/effective-mcp-catalog-K6kLCN8X.mjs} +3 -3
  35. package/dist/{ephemeral-turn-D78_VmzO.js → .setup/ephemeral-turn-R1gA8Sn6.mjs} +4 -5
  36. package/dist/{event-projector-assistant-message-BmBM4qBV.js → .setup/event-projector-assistant-message-DNUR1s0A.mjs} +6 -3
  37. package/dist/{event-projector-items-5VhsECCO.js → .setup/event-projector-items-DyTQ_XqL.mjs} +1 -1
  38. package/dist/{attempt-notifications-C9XufG6l.js → .setup/event-projector-usage-C7Ntzs-f.mjs} +102 -9
  39. package/dist/{harness-C7rRa7bm.js → .setup/harness-rxaaoN-o.mjs} +74 -20
  40. package/dist/{inference-context-Dr_mzvk4.js → .setup/inference-context-fulhZuz8.mjs} +1 -1
  41. package/dist/{inference-proxy-HGXKUIre.js → .setup/inference-proxy-CC15HuSi.mjs} +4 -4
  42. package/dist/{isolated-completion-DWVb5U2J.js → .setup/isolated-completion-B6srt48J.mjs} +7 -7
  43. package/dist/{launch-args-RXQwn8zV.js → .setup/launch-args-DnMak49W.mjs} +22 -1
  44. package/dist/{managed-binary-D22rNEcR.js → .setup/managed-binary-DP6Rib3P.mjs} +2 -2
  45. package/dist/{managed-thread-store-D1t5jh3G.js → .setup/managed-thread-store-BMqgThVL.mjs} +48 -14
  46. package/dist/{model-catalog-Dq2n8f_p.js → .setup/model-catalog-DkvUuBey.mjs} +35 -10
  47. package/dist/{models-PCKOim-h.js → .setup/models-BDFgm_G-.mjs} +3 -3
  48. package/dist/.setup/native-auth-BLZGqFjw.mjs +57 -0
  49. package/dist/{native-subagent-history-DjtPloaU.js → .setup/native-subagent-history-YXaL6dMd.mjs} +24 -29
  50. package/dist/.setup/native-subagent-monitor-B1hxzIOy.mjs +5031 -0
  51. package/dist/{native-subagent-task-ids-BzTdT0Uw.js → .setup/native-subagent-task-ids-DsuOonKv.mjs} +32 -8
  52. package/dist/{node-cli-sessions-DKaOmVUh.js → .setup/node-cli-sessions-Cl8b2ZF3.mjs} +1 -1
  53. package/dist/{node-exec-server.runtime-Cl2vapEi.js → .setup/node-exec-server.runtime-BaViBKNz.mjs} +3 -3
  54. package/dist/{plan-7uG-Fp36.js → .setup/plan-xD7WKYTM.mjs} +64 -48
  55. package/dist/{plugin-activation-BYQculil.js → .setup/plugin-activation-r8nq5Jzp.mjs} +3 -3
  56. package/dist/{plugin-app-cache-key-d0eKxy7b.js → .setup/plugin-app-cache-key-BOxKP7db.mjs} +29 -25
  57. package/dist/{plugin-approval-roundtrip-Bz3FT8W5.js → .setup/plugin-approval-roundtrip-CjfzafAZ.mjs} +1 -1
  58. package/dist/{plugin-inventory-oL4Na1ZG.js → .setup/plugin-inventory-DUle8DLz.mjs} +7 -6
  59. package/dist/{plugin-metadata-cache-ClPJpRio.js → .setup/plugin-metadata-cache-DsS5buNa.mjs} +29 -14
  60. package/dist/{provider-capabilities-BvCUL69A.js → .setup/provider-capabilities-B8J4Dy-O.mjs} +2 -2
  61. package/dist/{provider-MQ8PVkuE.js → .setup/provider-fFh_-VR3.mjs} +4 -4
  62. package/dist/{rate-limits-CBMmWBr9.js → .setup/rate-limits-DOEGYRNs.mjs} +90 -46
  63. package/dist/{request-B7hEkBGq.js → .setup/request-BioXJLYa.mjs} +113 -33
  64. package/dist/.setup/run-attempt-lifecycle-B7JbY4-F.mjs +71 -0
  65. package/dist/{run-attempt-CvsAAGa0.js → .setup/run-attempt-rlA07pUv.mjs} +580 -498
  66. package/dist/{runtime-artifact-BJ0rXBZ_.js → .setup/runtime-artifact-Dy38Z5iU.mjs} +2 -2
  67. package/dist/{sandbox-guard-BxgyoM8M.js → .setup/sandbox-guard-BBP-RbTf.mjs} +3 -3
  68. package/dist/{session-binding-CI8UuilT.js → .setup/session-binding-_0W_fHRr.mjs} +46 -64
  69. package/dist/{session-binding-record-Bcvslnhf.js → .setup/session-binding-record-TH3xA0zj.mjs} +181 -3
  70. package/dist/.setup/session-binding-sidecars-CKYEcfNn.mjs +543 -0
  71. package/dist/{session-catalog-adoption-tcZi1IfX.js → .setup/session-catalog-adoption-CR_whkEW.mjs} +6 -6
  72. package/dist/{session-catalog-archive-CwKg8Xz2.js → .setup/session-catalog-archive-CwZaPacf.mjs} +6 -6
  73. package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +250 -0
  74. package/dist/.setup/session-catalog-fUdWDx-U.mjs +2464 -0
  75. package/dist/.setup/session-catalog-index-B141u15s.mjs +1070 -0
  76. package/dist/.setup/session-catalog-index-order-Cc5BzlQr.mjs +48 -0
  77. package/dist/.setup/session-catalog-index-state-BAuDztHN.mjs +180 -0
  78. package/dist/{thread-history-page-D0JIp48V.js → .setup/session-catalog-native-projection-ChV3cCtm.mjs} +206 -95
  79. package/dist/{session-catalog-node-adoption-B1tgDW-m.js → .setup/session-catalog-node-adoption-BVRsYOSh.mjs} +3 -3
  80. package/dist/{session-catalog-node-continue-Ci-DXyJP.js → .setup/session-catalog-node-continue-Dowv8osw.mjs} +7 -7
  81. package/dist/.setup/session-catalog-projection-C1Bj9Jl-.mjs +414 -0
  82. package/dist/{session-cli-DNN_jhGc.js → .setup/session-cli-DIj-IE-E.mjs} +4 -4
  83. package/dist/{session-history-Cz-tOOYj.js → .setup/session-history-C--SrLI8.mjs} +10 -5
  84. package/dist/{session-history-import-DwyijFI6.js → .setup/session-history-import-JHXT5Xfi.mjs} +4 -4
  85. package/dist/{session-history-read-cxPUxyVV.js → .setup/session-history-read-B3ZfSUbF.mjs} +2 -2
  86. package/dist/{session-history.worker-BeK1YOyT.js → .setup/session-history.worker-CpNj7H_P.mjs} +5 -6
  87. package/dist/{session-initialization-Ct0_Hzmg.js → .setup/session-initialization-DH1z6fXn.mjs} +2 -2
  88. package/dist/{session-permission-policy-BBmXA8Eg.js → .setup/session-permission-policy-DhurXY0l.mjs} +2 -2
  89. package/dist/{session-retirement-B2YfbAAT.js → .setup/session-retirement-CU87AOg9.mjs} +6 -6
  90. package/dist/{settled-turn-context-Du6gdUDd.js → .setup/settled-turn-context-fmwouT5I.mjs} +2 -2
  91. package/dist/{settled-turn-finalizer-Dn91stmc.js → .setup/settled-turn-finalizer-CiY2bLFK.mjs} +9 -9
  92. package/dist/{shared-client-CscigXXL.js → .setup/shared-client-BpTtuLQ5.mjs} +286 -145
  93. package/dist/{side-question-BGMJQf4U.js → .setup/side-question-DSCZyoBD.mjs} +64 -47
  94. package/dist/{source-CElXU0Oy.js → .setup/source-Bjp4UQij.mjs} +7 -6
  95. package/dist/{thread-archive-guard-DfpBr-Sz.js → .setup/thread-archive-guard-jmecf6OJ.mjs} +1 -1
  96. package/dist/.setup/thread-history-page-BTx-4xsg.mjs +83 -0
  97. package/dist/{thread-lifecycle-DXl1-I6b.js → .setup/thread-lifecycle-Cik28qWn.mjs} +256 -128
  98. package/dist/{thread-ownership-BsDRTsyp.js → .setup/thread-ownership-skomxnIt.mjs} +4 -4
  99. package/dist/{thread-policy-BuEQfE0g.js → .setup/thread-policy-Cjs4B8xf.mjs} +2 -2
  100. package/dist/{thread-resume-DsDOZpFg.js → .setup/thread-resume-BkNpj9Pz.mjs} +8 -5
  101. package/dist/.setup/timeout-DZF05XrR.mjs +63 -0
  102. package/dist/{transcript-history-projection-v17wXgdK.js → .setup/transcript-history-projection-DHNBDhCU.mjs} +8 -3
  103. package/dist/{transcript-mirror-C5CKgNy6.js → .setup/transcript-mirror-D4qp_leP.mjs} +15 -6
  104. package/dist/{transcript-mirror-attestation-DibE0krH.js → .setup/transcript-mirror-attestation-CzM-94NC.mjs} +4 -1
  105. package/dist/{transport-stdio-BGjHoYLr.js → .setup/transport-stdio-Cmx94Oiy.mjs} +149 -44
  106. package/dist/{upstream-session-fork-BZerMte_.js → .setup/upstream-session-fork-D3UKxgVD.mjs} +27 -26
  107. package/dist/{usage-tCk-mg_x.js → .setup/usage-BOgBEKso.mjs} +4 -4
  108. package/dist/.setup/usage-limit-error-C0ow7DOc.mjs +166 -0
  109. package/dist/{version-omm6IPI3.js → .setup/version-CoqzXPgK.mjs} +1 -1
  110. package/dist/{web-search-provider.runtime-B7bGbGWq.js → .setup/web-search-provider.runtime-CTGuJt6i.mjs} +3 -3
  111. package/dist/api.js +6 -6
  112. package/dist/cli-metadata.js +1 -1
  113. package/dist/doctor-contract-api.js +8 -528
  114. package/dist/harness.js +1 -1
  115. package/dist/index.js +123 -83
  116. package/dist/media-understanding-provider.js +3 -3
  117. package/dist/migration-provider-api.js +1 -1
  118. package/dist/native-tool-policy.js +12 -0
  119. package/dist/provider-discovery.js +18 -0
  120. package/dist/session-history-worker-runtime.js +23 -5
  121. package/dist/session-history.worker.js +2 -2
  122. package/dist/web-search-contract-api.js +1 -1
  123. package/openclaw.plugin.json +354 -69
  124. package/package.json +11 -8
  125. package/dist/binding-connection-D3udKbIE.js +0 -60
  126. package/dist/event-projector-usage-BfXmpOec.js +0 -102
  127. package/dist/native-subagent-history-owner-Pcp7JuVF.js +0 -34
  128. package/dist/native-subagent-monitor-fQ7eIXEf.js +0 -2978
  129. package/dist/rpc-error-ttN_QjEm.js +0 -30
  130. package/dist/session-catalog-ct-AH01I.js +0 -1477
  131. package/dist/session-catalog-home-id-CwhLdC03.js +0 -18
  132. package/dist/session-catalog-provenance-D-dIfRAH.js +0 -96
  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/{config-utils-DujwEnhg.js → .setup/config-utils-DujwEnhg.mjs} +0 -0
  136. package/dist/{context-compaction-activity-CMla5FPJ.js → .setup/context-compaction-activity-CMla5FPJ.mjs} +0 -0
  137. package/dist/{elicitation-input-DPoK8F7w.js → .setup/elicitation-input-DPoK8F7w.mjs} +0 -0
  138. package/dist/{history-rejection-B4nOXNXF.js → .setup/history-rejection-B4nOXNXF.mjs} +0 -0
  139. package/dist/{image-payload-sanitizer-tupAr-2o.js → .setup/image-payload-sanitizer-tupAr-2o.mjs} +0 -0
  140. package/dist/{incognito-session-uhrBF6wJ.js → .setup/incognito-session-uhrBF6wJ.mjs} +0 -0
  141. package/dist/{local-runtime-attribution-B_2mnqhb.js → .setup/local-runtime-attribution-B_2mnqhb.mjs} +0 -0
  142. package/dist/{native-execution-policy-umd0tgh4.js → .setup/native-execution-policy-YBMHSzC4.mjs} +1 -1
  143. /package/dist/{plugin-marketplace-discovery-P-Vndfqq.js → .setup/plugin-marketplace-discovery-P-Vndfqq.mjs} +0 -0
  144. /package/dist/{rolldown-runtime-8H4AJuhK.js → .setup/rolldown-runtime-8H4AJuhK.mjs} +0 -0
  145. /package/dist/{session-binding-meta-B7aEMU7g.js → .setup/session-binding-meta-B7aEMU7g.mjs} +0 -0
  146. /package/dist/{session-upstream-marker-D15C9NHp.js → .setup/session-upstream-marker-D15C9NHp.mjs} +0 -0
  147. /package/dist/{upstream-prompt-provenance-LphB8slG.js → .setup/upstream-prompt-provenance-LphB8slG.mjs} +0 -0
  148. /package/dist/{web-search-provider.shared-BrZmlqyR.js → .setup/web-search-provider.shared-BrZmlqyR.mjs} +0 -0
@@ -1,63 +1,64 @@
1
- import { s as resolveRecoverableCodexPluginConfigKeys } from "./plugin-inventory-oL4Na1ZG.js";
2
- import { l as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced } from "./session-binding-record-Bcvslnhf.js";
3
- import { n as defineCodexBuildState } from "./build-state-BCmg9-5p.js";
4
- 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-CXMq1T-C.js";
5
- 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-5bh1G-H7.js";
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, 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-B57KWPQx.js";
7
- import { c as resolveCodexAppServerPreparedApiKeyCacheKey, m as retireSharedCodexAppServerClientIfCurrent, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-7orQae_j.js";
8
- import { t as isIncognitoSessionKey } from "./incognito-session-uhrBF6wJ.js";
9
- import { a as shouldRefreshCodexRateLimitsForUsageLimitMessage, i as resolveCodexUsageLimitResetAtMs, n as formatCodexUsageLimitErrorMessage } from "./rate-limits-CBMmWBr9.js";
10
- import { o as formatCodexDisplayText } from "./command-formatters-lxlkNZgU.js";
11
- import { t as CodexAppServerRpcError } from "./rpc-error-ttN_QjEm.js";
12
- import { t as CODEX_CONTROL_METHODS } from "./capabilities-8vx68WLH.js";
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-5VhsECCO.js";
14
- import { r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.js";
15
- import { n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey, s as defaultCodexAppInventoryCache } from "./plugin-app-cache-key-d0eKxy7b.js";
16
- import { t as withAbortableTimeout } from "./timeout-BVw8aaM1.js";
17
- import { n as resolveOpenClawExecPolicyForCodexAppServer, t as canUseCodexModelBackedApprovalsReviewerForModel } from "./config-oIORaQ5T.js";
18
- import { o as hasCodexMirrorOrigin, t as applyCodexTranscriptTaint } from "./transcript-mirror-attestation-DibE0krH.js";
19
- import { r as prepareCodexAppServerAuthBinding } from "./auth-binding-CWlKVccJ.js";
20
- import { i as resolveCodexBindingAppServerConnection, t as assertCodexSessionRuntimeOwnership } from "./binding-connection-D3udKbIE.js";
21
- import { i as resolveCodexAppServerAuthProfileIdForAgent, r as resolveCodexAppServerAuthProfileId } from "./auth-profile-CwzO4_RG.js";
22
- import { A as CodexAppServerStartupError, F as resolveCodexStartupTimeoutMs, G as protectCodexAppServerLiveThread, I as withCodexStartupTimeout, M as TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS, N as isCodexAppServerStartupError, O as getCodexInferenceThread, Q as rememberCodexRateLimitsRead, W as prepareCodexWorkspaceReferences, X as readCodexRateLimitsRevision, Z as readRecentCodexRateLimits, a as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, c as getLeasedSharedCodexAppServerClient, et as resolveCodexAppServerAuthAccountCacheKey, f as readCodexAppServerClientDesktopGenerationFingerprint, h as releaseLeasedSharedCodexAppServerClient, i as clearSharedCodexAppServerClientIfCurrent, j as TURN_FINALIZE_DRAIN_ABORT_GRACE_MS, l as getSharedCodexAppServerClient, s as createIsolatedCodexAppServerClient, tt as resolveCodexAppServerPreparedAuthHandoff, u as isCodexAppServerStartSelectionChangedError, v as retainSharedCodexAppServerClientIfCurrent, z as ensureCodexAppServerClientRuntime } from "./shared-client-CscigXXL.js";
23
- import { a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, f as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, g as readCodexNotificationThreadId, h as isCodexNotificationForTurn, l as retireUnsafeCodexTurnClientBestEffort, m as CodexProjectionDiagnostics, o as interruptCodexTurnAndWaitBestEffort, p as getCodexAppServerTurnRouter, r as CodexAppServerUnsafeSubscriptionError, u as terminateCodexBackgroundTerminals } from "./attempt-client-cleanup-DKHzbwt5.js";
24
- 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-C9XufG6l.js";
25
- import { t as CodexUsageProjection } from "./event-projector-usage-BfXmpOec.js";
26
- import { $ as codexDynamicToolsFingerprint, A as readCodexMcpToolConnectorId, B as createCodexNativeHookRelay, C as resolveCodexWebSearchPlan, Ct as buildCodexPluginThreadConfigInputFingerprint, Et as mergeCodexThreadConfigs, F as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, H as resolveCodexNativeHookRelayEvents, J as loadCodexNativeToolCatalog, L as buildCodexNativeHookRelayConfig, N as isCodexAppServerProfilerEnabled, O as resolveCodexAppServerThreadModelSelection, Ot as shouldBuildCodexPluginThreadConfig, R as buildCodexNativeHookRelayDisabledConfig, St as buildCodexPluginThreadConfig, U as resolveCodexNativeHookRelayTtlMs, V as emitCodexNativePreToolUseFailureDiagnostic, W as scheduleCodexNativeHookRelayUnregister, _t as neutralizeCodexExplicitMentionSigils, a as buildCodexUserInput, bt as resolveCodexContextEngineProjectionReserveTokens, c as startOrResumeThread, d as buildScheduledCodexAppAuthorityInputFingerprint, dt as buildContextEngineBinding, et as codexLegacyDynamicToolsFingerprint, f as buildScheduledCodexAppServerConnectionIdentity, g as resolveScheduledCodexAppCreatorCaptureDecision, gt as isCodexDurableCustomMessage, h as readCurrentCodexScheduledAppPolicy$1, ht as fitCodexProjectedContextForTurnStart, i as buildTurnStartParams, j as readCodexMcpToolUiVisibility, l as assertScheduledCodexAppAuthorityRuntime, m as intersectCodexPluginThreadConfigWithScheduledAuthority, mt as buildCodexContinuityCalibration, p as captureScheduledCodexAppAuthority, pt as CodexContextAttachmentError, q as hasCodexNativeToolCatalog, r as buildTurnCollaborationMode, rt as filterCodexDynamicTools, st as isSystemAgentOnlyCodexDynamicToolAllowlist, t as buildCodexParentLocalInstructions, u as buildLegacyScheduledCodexAppRecoveryPrompt, ut as resolveCodexDynamicToolsLoadingForRuntime, vt as projectContextEngineAssemblyForCodex, w as buildDeveloperInstructions, wt as buildCodexPluginThreadConfigTimeoutFallback, xt as resolveCodexContinuityProjectionMaxChars, yt as resolveCodexContextEngineProjectionMaxChars } from "./thread-lifecycle-DXl1-I6b.js";
27
- import { a as resolveCodexRunSessionBindingAuthority, n as createCodexSessionGenerationSupersededError, o as resolveCodexSessionBinding, s as scopeCodexRunBindingStore } from "./session-binding-CI8UuilT.js";
28
- import { n as CodexThreadPolicyHandoffError } from "./thread-policy-BuEQfE0g.js";
29
- import { r as retainCodexAppServerBindingSubscription } from "./thread-ownership-BsDRTsyp.js";
30
- import { i as mirrorPromptAtTurnStartBestEffort, n as createCodexAppServerUserMessagePersistenceNotifier, o as buildCodexUserPromptMessage, s as promptSnapshot, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-C5CKgNy6.js";
31
- import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.js";
32
- import { t as CODEX_INFERENCE_GENERATION_KEY } from "./inference-context-Dr_mzvk4.js";
33
- import { i as createAssistantReasoningMessage, n as createAssistantCommentaryMessage, r as createAssistantMessage, t as createAssistantAsyncMessage } from "./event-projector-assistant-message-BmBM4qBV.js";
34
- import { _ as sanitizeCodexToolResponse, g as sanitizeCodexToolArguments, h as resolveCodexToolProgressDetailMode, m as isCodexCommandBearingToolCall, p as inferCodexDynamicToolMeta } from "./native-subagent-task-ids-BzTdT0Uw.js";
35
- import { n as createCodexNativeSubagentHistoryOwner } from "./native-subagent-history-owner-Pcp7JuVF.js";
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-CmN5RAip.js";
37
- import { t as resolveCodexProviderWebSearchSupport } from "./provider-capabilities-BvCUL69A.js";
38
- import { a as requestPluginApprovalOutcome } from "./plugin-approval-roundtrip-Bz3FT8W5.js";
39
- import { a as CodexToolProgressProjection, i as CodexToolTranscriptProjection, n as CodexEventProjection, o as shouldEmitTranscriptToolProgress, r as emitCodexAgentEvent, t as codexNativeSubagentMonitorRuntime } from "./native-subagent-monitor-fQ7eIXEf.js";
40
- import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy } from "./session-permission-policy-BBmXA8Eg.js";
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-D44yeDII.js";
42
- import { n as captureCodexSettledTurnFinalizationContext } from "./settled-turn-context-Du6gdUDd.js";
43
- import { a as runCodexComputerUseLiveTest, n as ensureCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-ClPJpRio.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";
44
44
  import { asOptionalRecord, normalizeOptionalString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
45
45
  import { createHash } from "node:crypto";
46
+ import { isDeepStrictEqual } from "node:util";
46
47
  import { resolveAgentConfig, resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
47
48
  import { MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
48
49
  import path from "node:path";
49
50
  import fs from "node:fs/promises";
50
51
  import { addAbortListener } from "node:events";
51
52
  import { truncateUtf16Safe, truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
52
- import { Buffer as Buffer$1 } from "node:buffer";
53
+ import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
53
54
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
55
+ import { Buffer as Buffer$1 } from "node:buffer";
54
56
  import { isPathStrictlyInside, root } from "openclaw/plugin-sdk/file-access-runtime";
55
- import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
56
- 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";
57
59
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
58
- import { isDeepStrictEqual } from "node:util";
59
60
  import { getSessionEntry, parseSqliteSessionFileMarker } from "openclaw/plugin-sdk/session-store-runtime";
60
- import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
61
+ import { acknowledgeInternalToolResult } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
61
62
  import { captureFinalCodexCronCreatorToolAllowlist, formatMcpCodexApprovalRemedy, materializeStaticMcpToolsForHarnessRun, resolveCodexMcpToolOverridesForAgent, resolveCodexTtsProvenanceTransfer } from "openclaw/plugin-sdk/codex-mcp-projection";
62
63
  import { appendSessionYieldContext, hasPromptImageInput } from "openclaw/plugin-sdk/session-transcript-runtime";
63
64
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-local-roots";
@@ -66,7 +67,6 @@ import { generatedImageAssetFromBase64 } from "openclaw/plugin-sdk/image-generat
66
67
  import { resolveGeneratedMediaMaxBytes } from "openclaw/plugin-sdk/media-generation-runtime";
67
68
  import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
68
69
  import { stripInvisibleUnicode } from "openclaw/plugin-sdk/web-content-extractor";
69
- import { acknowledgeInternalToolResult } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
70
70
  import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
71
71
  //#region extensions/codex/src/app-server/attempt-preparation-timing.ts
72
72
  /** Records startup before the native turn owns inference and tool execution. */
@@ -126,6 +126,7 @@ var CodexSteeringAcceptedUnconfirmedError = class extends Error {
126
126
  * app-server `turn/steer` requests.
127
127
  */
128
128
  function createCodexSteeringQueue(params) {
129
+ const acceptedMessages = [];
129
130
  let batchedMessages = [];
130
131
  const dispatchedBatches = /* @__PURE__ */ new Map();
131
132
  const pendingMessages = /* @__PURE__ */ new Set();
@@ -151,9 +152,13 @@ function createCodexSteeringQueue(params) {
151
152
  item.acceptance = accepted ? "accepted" : "rejected";
152
153
  item.onQueueAccepted?.(accepted);
153
154
  };
155
+ const acceptItem = (item) => {
156
+ if (item.acceptance === "open") acceptedMessages.push(item.prepared.message);
157
+ reportItemAcceptance(item, true);
158
+ };
154
159
  const resolveItem = (item) => {
155
160
  if (item.settled) return;
156
- reportItemAcceptance(item, true);
161
+ acceptItem(item);
157
162
  item.settled = true;
158
163
  pendingMessages.delete(item);
159
164
  item.resolve();
@@ -171,7 +176,7 @@ function createCodexSteeringQueue(params) {
171
176
  params.signal.removeEventListener("abort", abortQueue);
172
177
  clearBatchTimer();
173
178
  batchedMessages = [];
174
- 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);
175
180
  dispatchedBatches.clear();
176
181
  for (const item of pendingMessages) rejectItem(item, error);
177
182
  };
@@ -190,13 +195,14 @@ function createCodexSteeringQueue(params) {
190
195
  closeQueue(/* @__PURE__ */ new Error("codex app-server steering queue cancelled"));
191
196
  };
192
197
  const sendBatch = async (items) => {
193
- let liveItems = items.filter((item) => !item.settled);
194
- if (liveItems.length === 0) return;
198
+ const pendingItems = items.filter((item) => !item.settled);
199
+ let liveItems = [];
200
+ if (pendingItems.length === 0) return;
195
201
  let clientUserMessageId;
196
202
  let skippedRevokedBatch = false;
197
203
  try {
198
204
  assertActive();
199
- const prepared = /* @__PURE__ */ new Map();
205
+ const prepared = [];
200
206
  const isCurrent = (item) => {
201
207
  if (item.settled) return false;
202
208
  try {
@@ -207,17 +213,17 @@ function createCodexSteeringQueue(params) {
207
213
  return false;
208
214
  }
209
215
  };
210
- for (const item of liveItems) {
216
+ for (const item of pendingItems) {
211
217
  if (!isCurrent(item)) continue;
212
218
  try {
213
- prepared.set(item, await params.prepareMessage(item.text, item));
219
+ prepared.push(Object.assign(item, { prepared: await params.prepareMessage(item.text, item) }));
214
220
  } catch (error) {
215
221
  if (isCurrent(item)) throw error;
216
222
  }
217
223
  assertActive();
218
224
  isCurrent(item);
219
225
  }
220
- liveItems = liveItems.filter(isCurrent);
226
+ liveItems = prepared.filter(isCurrent);
221
227
  if (liveItems.length === 0) return;
222
228
  if (params.beforeSubmit) {
223
229
  await params.beforeSubmit(liveItems);
@@ -230,7 +236,7 @@ function createCodexSteeringQueue(params) {
230
236
  const request = {
231
237
  threadId: params.threadId,
232
238
  expectedTurnId: params.turnId,
233
- input: liveItems.flatMap((item) => prepared.get(item) ?? []),
239
+ input: liveItems.flatMap((item) => item.prepared.input),
234
240
  clientUserMessageId
235
241
  };
236
242
  await params.client.request("turn/steer", request, {
@@ -239,7 +245,7 @@ function createCodexSteeringQueue(params) {
239
245
  assertCurrent: () => {
240
246
  assertActive();
241
247
  liveItems = liveItems.filter(isCurrent);
242
- request.input = liveItems.flatMap((item) => prepared.get(item) ?? []);
248
+ request.input = liveItems.flatMap((item) => item.prepared.input);
243
249
  dispatchedBatches.set(request.clientUserMessageId, { items: liveItems });
244
250
  if (liveItems.length === 0) {
245
251
  skippedRevokedBatch = true;
@@ -247,15 +253,12 @@ function createCodexSteeringQueue(params) {
247
253
  }
248
254
  }
249
255
  });
250
- for (const item of liveItems) reportItemAcceptance(item, true);
256
+ for (const item of liveItems) acceptItem(item);
251
257
  } catch (error) {
252
258
  if (clientUserMessageId) dispatchedBatches.delete(clientUserMessageId);
253
259
  if (skippedRevokedBatch) return;
254
- const acceptedUnconfirmed = clientUserMessageId !== void 0 && (isCodexAppServerIndeterminateRequestCancellationError(error) || isCodexAppServerIndeterminateTransportError(error));
255
- for (const item of liveItems) {
256
- if (acceptedUnconfirmed) reportItemAcceptance(item, true);
257
- rejectItem(item, error);
258
- }
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);
259
262
  throw error;
260
263
  }
261
264
  };
@@ -328,6 +331,7 @@ function createCodexSteeringQueue(params) {
328
331
  for (const item of batch.items) resolveItem(item);
329
332
  return true;
330
333
  },
334
+ getAcceptedMessages: () => acceptedMessages.slice(),
331
335
  sealAdmission: sealQueueAdmission,
332
336
  cancel: cancelQueue
333
337
  };
@@ -337,9 +341,6 @@ function normalizeCodexSteerDebounceMs(value) {
337
341
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : CODEX_STEER_ALL_DEBOUNCE_MS;
338
342
  }
339
343
  //#endregion
340
- //#region extensions/codex/src/app-server/attempt-terminal.ts
341
- const attemptTerminal = agentHarnessAttemptTerminal;
342
- //#endregion
343
344
  //#region extensions/codex/src/app-server/event-projector-assistant.ts
344
345
  var CodexAssistantProjection = class {
345
346
  constructor(params, emitAgentEvent, matchesToolProgressEcho, nextTranscriptTimestamp, checkpointCommentary) {
@@ -353,6 +354,7 @@ var CodexAssistantProjection = class {
353
354
  this.assistantTimestampByItem = /* @__PURE__ */ new Map();
354
355
  this.assistantPhaseByItem = /* @__PURE__ */ new Map();
355
356
  this.assistantDeliveryByItem = /* @__PURE__ */ new Map();
357
+ this.assistantQuestionsByItem = /* @__PURE__ */ new Map();
356
358
  this.latestTerminalAssistantCandidateSuperseded = false;
357
359
  this.terminalAssistantCandidateEarlierActiveItemIds = /* @__PURE__ */ new Set();
358
360
  this.lastCommentaryProgressEventByItem = /* @__PURE__ */ new Map();
@@ -416,7 +418,7 @@ var CodexAssistantProjection = class {
416
418
  });
417
419
  if (knownFinalAnswer && !replaceable) await this.params.onPartialReply?.(streamPayload);
418
420
  }
419
- recordItemStarted(item, itemId) {
421
+ async recordItemStarted(item, itemId) {
420
422
  this.noteNativeWorkBarrier(item);
421
423
  this.rememberAssistantPhase(item);
422
424
  if (item?.type === "agentMessage" && itemId && !this.isNonTerminalAssistantItem(itemId) && itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
@@ -425,6 +427,10 @@ var CodexAssistantProjection = class {
425
427
  this.markTerminalAssistantCandidateSupersededBy(itemId, { preserveEarlierActiveItem: true });
426
428
  if (this.latestTerminalAssistantCandidateSuperseded) this.pendingRawTerminalAssistantEchoItemId = void 0;
427
429
  }
430
+ if (item?.type === "agentMessage" && itemId && item.text && !this.assistantTextByItem.has(itemId)) await this.handleAssistantDelta({
431
+ itemId,
432
+ delta: item.text
433
+ });
428
434
  }
429
435
  recordItemCompleted(item, itemId, activeItemIds) {
430
436
  if (itemId && item?.type === "agentMessage") this.completedAssistantItemIds.add(itemId);
@@ -528,14 +534,11 @@ var CodexAssistantProjection = class {
528
534
  }
529
535
  collectAsyncMessages() {
530
536
  return this.assistantItemOrder.flatMap((itemId) => {
531
- if (!this.isAsyncAssistantItem(itemId)) return [];
532
- const text = this.assistantTextByItem.get(itemId)?.trim();
533
- const timestamp = this.assistantTimestampByItem.get(itemId);
534
- if (!text || timestamp === void 0) return [];
535
- return [{
537
+ const delivery = this.createAsyncDelivery(itemId);
538
+ return delivery ? [{
536
539
  itemId,
537
- message: createAssistantAsyncMessage(this.params, text, itemId, timestamp)
538
- }];
540
+ message: delivery.message
541
+ }] : [];
539
542
  });
540
543
  }
541
544
  collectCompletedAssistantMessages(completedItemIds, options) {
@@ -616,6 +619,11 @@ var CodexAssistantProjection = class {
616
619
  if (phase) this.assistantPhaseByItem.set(item.id, phase);
617
620
  const delivery = readItemString(item, "delivery");
618
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
+ }
619
627
  }
620
628
  isCommentaryAssistantItem(itemId) {
621
629
  return this.assistantPhaseByItem.get(itemId) === "commentary";
@@ -755,7 +763,7 @@ var CodexAssistantProjection = class {
755
763
  if (!text?.trim() || timestamp === void 0) return;
756
764
  return {
757
765
  itemId,
758
- message: createAssistantAsyncMessage(this.params, text, itemId, timestamp),
766
+ message: createAssistantAsyncMessage(this.params, text, itemId, timestamp, this.assistantQuestionsByItem.get(itemId)),
759
767
  text
760
768
  };
761
769
  }
@@ -974,8 +982,7 @@ var CodexReasoningProjection = class {
974
982
  this.params = params;
975
983
  this.emitAgentEvent = emitAgentEvent;
976
984
  this.onNativePlanUpdate = onNativePlanUpdate;
977
- this.reasoningTextByGroup = /* @__PURE__ */ new Map();
978
- this.reasoningItemOrder = /* @__PURE__ */ new Map();
985
+ this.reasoningTextByItem = /* @__PURE__ */ new Map();
979
986
  this.planTextByItem = /* @__PURE__ */ new Map();
980
987
  this.reasoningStarted = false;
981
988
  this.reasoningEnded = false;
@@ -985,16 +992,14 @@ var CodexReasoningProjection = class {
985
992
  const delta = readStringField(params, "delta") ?? "";
986
993
  if (!delta) return;
987
994
  this.reasoningStarted = true;
988
- 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);
989
1000
  const groupIndex = method === "item/reasoning/textDelta" ? readNonNegativeInteger(params, "contentIndex") ?? 0 : readNonNegativeInteger(params, "summaryIndex") ?? 0;
990
- const groupKey = `${method}\0${itemId}\0${groupIndex}`;
991
- const current = this.reasoningTextByGroup.get(groupKey);
992
- this.reasoningTextByGroup.set(groupKey, {
993
- itemId,
994
- method,
995
- index: groupIndex,
996
- text: `${current?.text ?? ""}${delta}`
997
- });
1001
+ const sections = method === "item/reasoning/textDelta" ? item.content : item.summary;
1002
+ sections.set(groupIndex, `${sections.get(groupIndex) ?? ""}${delta}`);
998
1003
  await this.params.onReasoningStream?.({
999
1004
  text: this.reasoningText(),
1000
1005
  isReasoningSnapshot: true
@@ -1034,10 +1039,27 @@ var CodexReasoningProjection = class {
1034
1039
  });
1035
1040
  this.emitPlanUpdate({
1036
1041
  explanation,
1042
+ ...params.explanationFormat === "plain" ? { explanationFormat: "plain" } : {},
1037
1043
  steps: plan
1038
1044
  }, source);
1039
1045
  }
1040
- 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
+ }
1041
1063
  if (item?.type === "plan" && typeof item.text === "string" && item.text) {
1042
1064
  this.planTextByItem.set(item.id, item.text);
1043
1065
  this.emitPlanUpdate({
@@ -1055,7 +1077,7 @@ var CodexReasoningProjection = class {
1055
1077
  await this.params.onReasoningEnd?.();
1056
1078
  }
1057
1079
  reasoningText() {
1058
- 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");
1059
1081
  }
1060
1082
  planText() {
1061
1083
  return this.turnPlanText ?? [...this.planTextByItem.values()].filter((text) => text.trim().length > 0).join("\n\n");
@@ -1069,6 +1091,7 @@ var CodexReasoningProjection = class {
1069
1091
  title: "Plan updated",
1070
1092
  source,
1071
1093
  ...params.explanation ? { explanation: params.explanation } : {},
1094
+ ...params.explanationFormat ? { explanationFormat: params.explanationFormat } : {},
1072
1095
  ...params.steps ? { steps: params.steps } : {}
1073
1096
  }
1074
1097
  });
@@ -1078,16 +1101,12 @@ function normalizePlanStepStatus(status) {
1078
1101
  if (status === "inProgress" || status === "in_progress") return "in_progress";
1079
1102
  return status === "completed" ? "completed" : "pending";
1080
1103
  }
1081
- function collectReasoningTextValues(groups, itemOrder) {
1082
- return [...groups.values()].toSorted((left, right) => {
1083
- const itemDelta = (itemOrder.get(left.itemId) ?? Number.MAX_SAFE_INTEGER) - (itemOrder.get(right.itemId) ?? Number.MAX_SAFE_INTEGER);
1084
- if (itemDelta !== 0) return itemDelta;
1085
- const methodDelta = reasoningMethodOrder(left.method) - reasoningMethodOrder(right.method);
1086
- return methodDelta !== 0 ? methodDelta : left.index - right.index;
1087
- }).map((group) => group.text).filter((text) => text.trim().length > 0);
1088
- }
1089
- function reasoningMethodOrder(method) {
1090
- 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;
1091
1110
  }
1092
1111
  //#endregion
1093
1112
  //#region extensions/codex/src/app-server/event-projector-settlement.ts
@@ -1156,7 +1175,8 @@ function buildCodexMessagesSnapshot(params) {
1156
1175
  ...commentaryMessages,
1157
1176
  ...asyncMessages,
1158
1177
  ...(params.assistantMessages ?? []).map(({ itemId, message }) => attachCodexMirrorIdentity(message, `${params.turnId}:assistant:${itemId}`)),
1159
- ...params.toolMessages
1178
+ ...params.toolMessages,
1179
+ ...params.steeringMessages ?? []
1160
1180
  ].toSorted((left, right) => (asDateTimestampMs(left.timestamp) ?? 0) - (asDateTimestampMs(right.timestamp) ?? 0));
1161
1181
  messages.push(...visibleWorkMessages);
1162
1182
  if (params.lastAssistant) {
@@ -1166,6 +1186,7 @@ function buildCodexMessagesSnapshot(params) {
1166
1186
  const taint = { tainted: false };
1167
1187
  return messages.map((message) => projectAgentHarnessTranscriptMessageForDisplay({
1168
1188
  hidden: params.runParams.trigger === "memory",
1189
+ inputProvenance: params.runParams.inputProvenance,
1169
1190
  message: applyCodexTranscriptTaint(message, taint)
1170
1191
  }));
1171
1192
  }
@@ -1193,164 +1214,6 @@ function buildCodexSteeringMessagesSnapshot(params) {
1193
1214
  };
1194
1215
  }
1195
1216
  //#endregion
1196
- //#region extensions/codex/src/app-server/usage-limit-error.ts
1197
- /**
1198
- * Enriches Codex usage-limit failures with current rate-limit information and
1199
- * marks blocked auth profiles when Codex exposes a reset time.
1200
- */
1201
- const CODEX_USAGE_LIMIT_RATE_LIMIT_REFRESH_TIMEOUT_MS = 5e3;
1202
- var CodexUsageLimitPromptError = class extends Error {
1203
- constructor(..._args) {
1204
- super(..._args);
1205
- this.status = 429;
1206
- }
1207
- };
1208
- function resolveCodexPromptError(source) {
1209
- const usageLimitMessage = formatCodexUsageLimitErrorMessage(source);
1210
- if (usageLimitMessage) return new CodexUsageLimitPromptError(usageLimitMessage);
1211
- const info = source.codexErrorInfo;
1212
- let status = info === "rateLimitExceeded" ? 429 : info === "serverOverloaded" ? 503 : info === "internalServerError" ? 500 : void 0;
1213
- if (isJsonObject(info)) for (const variant of [
1214
- "httpConnectionFailed",
1215
- "responseStreamConnectionFailed",
1216
- "responseStreamDisconnected",
1217
- "responseTooManyFailedAttempts"
1218
- ]) {
1219
- const detail = info[variant];
1220
- if (isJsonObject(detail) && typeof detail.httpStatusCode === "number") {
1221
- status = detail.httpStatusCode;
1222
- break;
1223
- }
1224
- }
1225
- return status === void 0 ? source.message ?? void 0 : Object.assign(new Error(source.message ?? "codex app-server error"), {
1226
- status,
1227
- ...info === "serverOverloaded" ? { code: "OVERLOADED" } : {}
1228
- });
1229
- }
1230
- /** Marks a Codex auth profile blocked until the reset time advertised by rate limits. */
1231
- async function markCodexAuthProfileBlockedFromRateLimits(params) {
1232
- const authProfileId = params.authProfileId?.trim();
1233
- if (!authProfileId || !params.params.authProfileStore) return;
1234
- const blockedUntil = resolveCodexUsageLimitResetAtMs(params.rateLimits);
1235
- if (!blockedUntil) return;
1236
- try {
1237
- await markAuthProfileBlockedUntil({
1238
- store: params.params.authProfileStore,
1239
- profileId: authProfileId,
1240
- blockedUntil,
1241
- source: "codex_rate_limits",
1242
- agentDir: params.params.agentDir,
1243
- runId: params.params.runId,
1244
- modelId: params.params.modelId
1245
- });
1246
- } catch (error) {
1247
- embeddedAgentLog.debug("failed to mark Codex auth profile blocked from app-server limits", {
1248
- authProfileId,
1249
- error: formatErrorMessage(error)
1250
- });
1251
- }
1252
- }
1253
- /** Formats a turn-start usage-limit error, refreshing rate limits when needed. */
1254
- async function formatCodexTurnStartUsageLimitError(params) {
1255
- return refreshCodexUsageLimitError({
1256
- client: params.client,
1257
- source: readCodexTurnStartUsageLimitErrorSource(params.client, params.error, params.errorNotification, params.rateLimitsRevisionBeforeTurnStart),
1258
- timeoutMs: params.timeoutMs,
1259
- signal: params.signal
1260
- });
1261
- }
1262
- /** Refreshes a generic prompt usage-limit message into a reset-aware message. */
1263
- async function refreshCodexUsageLimitPromptError(params) {
1264
- if (!shouldRefreshCodexRateLimitsForUsageLimitMessage(params.message)) return;
1265
- return refreshCodexUsageLimitError({
1266
- client: params.client,
1267
- source: {
1268
- message: params.message,
1269
- codexErrorInfo: "usageLimitExceeded",
1270
- rateLimits: readRecentCodexRateLimits(params.client)
1271
- },
1272
- timeoutMs: params.timeoutMs,
1273
- signal: params.signal
1274
- });
1275
- }
1276
- async function refreshCodexUsageLimitError(params) {
1277
- const initialMessage = formatCodexUsageLimitErrorMessage(params.source);
1278
- if (!shouldRefreshCodexRateLimitsForUsageLimitMessage(initialMessage)) return initialMessage ? {
1279
- message: initialMessage,
1280
- ...params.source.rateLimitsTrustedForProfile ? { rateLimitsForProfile: params.source.rateLimits } : {}
1281
- } : void 0;
1282
- const rateLimits = await readCodexRateLimitsFromAppServerForUsageLimitError({
1283
- client: params.client,
1284
- timeoutMs: params.timeoutMs,
1285
- signal: params.signal
1286
- });
1287
- if (!rateLimits) return initialMessage ? {
1288
- message: initialMessage,
1289
- ...params.source.rateLimitsTrustedForProfile ? { rateLimitsForProfile: params.source.rateLimits } : {}
1290
- } : void 0;
1291
- const message = formatCodexUsageLimitErrorMessage({
1292
- message: params.source.message,
1293
- codexErrorInfo: params.source.codexErrorInfo,
1294
- rateLimits,
1295
- rateLimitsAuthoritative: true
1296
- }) ?? initialMessage;
1297
- return message ? {
1298
- message,
1299
- rateLimitsForProfile: rateLimits
1300
- } : void 0;
1301
- }
1302
- async function readCodexRateLimitsFromAppServerForUsageLimitError(params) {
1303
- if (params.signal?.aborted) return;
1304
- try {
1305
- const rateLimits = await params.client.request(CODEX_CONTROL_METHODS.rateLimits, void 0, {
1306
- timeoutMs: resolveCodexUsageLimitRateLimitRefreshTimeoutMs(params.timeoutMs),
1307
- signal: params.signal
1308
- });
1309
- rememberCodexRateLimitsRead(params.client, rateLimits);
1310
- return rateLimits;
1311
- } catch (error) {
1312
- embeddedAgentLog.debug("codex app-server rate-limit refresh failed after usage-limit error", { error: formatErrorMessage(error) });
1313
- return;
1314
- }
1315
- }
1316
- function resolveCodexUsageLimitRateLimitRefreshTimeoutMs(timeoutMs) {
1317
- if (timeoutMs === void 0 || !Number.isFinite(timeoutMs) || timeoutMs <= 0) return CODEX_USAGE_LIMIT_RATE_LIMIT_REFRESH_TIMEOUT_MS;
1318
- return Math.max(100, Math.min(timeoutMs, CODEX_USAGE_LIMIT_RATE_LIMIT_REFRESH_TIMEOUT_MS));
1319
- }
1320
- function readCodexTurnStartUsageLimitErrorSource(client, error, errorNotification, rateLimitsRevisionBeforeTurnStart) {
1321
- const notificationError = readCodexErrorNotification(errorNotification);
1322
- const errorPayload = readCodexErrorPayload(error);
1323
- const rateLimits = errorPayload.rateLimits ?? readRecentCodexRateLimits(client);
1324
- const cacheUpdatedDuringTurnStart = rateLimitsRevisionBeforeTurnStart !== void 0 && readCodexRateLimitsRevision(client) > rateLimitsRevisionBeforeTurnStart;
1325
- return {
1326
- message: notificationError?.message ?? errorPayload.message ?? formatErrorMessage(error),
1327
- codexErrorInfo: notificationError?.codexErrorInfo ?? errorPayload.codexErrorInfo,
1328
- rateLimits,
1329
- rateLimitsTrustedForProfile: errorPayload.rateLimits !== void 0 || cacheUpdatedDuringTurnStart
1330
- };
1331
- }
1332
- function readCodexErrorNotification(notification) {
1333
- if (notification?.method !== "error" || !isJsonObject(notification.params)) return;
1334
- const error = notification.params.error;
1335
- return isJsonObject(error) ? {
1336
- message: readStringField(error, "message"),
1337
- codexErrorInfo: error.codexErrorInfo
1338
- } : void 0;
1339
- }
1340
- function readCodexErrorPayload(error) {
1341
- const message = error instanceof Error ? error.message : void 0;
1342
- if (!error || typeof error !== "object" || !("data" in error)) return { message };
1343
- const data = error.data;
1344
- if (!isJsonObject(data)) return { message };
1345
- const nestedError = isJsonObject(data.error) ? data.error : data;
1346
- const rateLimits = nestedError.rateLimits ?? data.rateLimits;
1347
- return {
1348
- message: readStringField(nestedError, "message") ?? message,
1349
- codexErrorInfo: nestedError.codexErrorInfo,
1350
- rateLimits
1351
- };
1352
- }
1353
- //#endregion
1354
1217
  //#region extensions/codex/src/app-server/event-projector-terminal-failure.ts
1355
1218
  var CodexTerminalFailureProjection = class {
1356
1219
  constructor() {
@@ -1417,6 +1280,7 @@ var CodexTranscriptCheckpoint = class {
1417
1280
  const message = entry.read();
1418
1281
  return message ? [projectAgentHarnessTranscriptMessageForDisplay({
1419
1282
  hidden: this.params.trigger === "memory",
1283
+ inputProvenance: this.params.inputProvenance,
1420
1284
  message: applyCodexTranscriptTaint(message, taint)
1421
1285
  })] : [];
1422
1286
  });
@@ -1486,7 +1350,7 @@ var CodexTurnProjection = class {
1486
1350
  trajectoryRecorder: options.trajectoryRecorder,
1487
1351
  checkpointMessage: this.transcriptCheckpoint.enqueue
1488
1352
  });
1489
- 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);
1490
1354
  this.assistantProjection = new CodexAssistantProjection(this.settlement.params, (event) => this.emitAgentEvent(event), (text) => this.toolProgressProjection.matchesEcho(text), this.transcriptCheckpoint.nextTimestamp, this.transcriptCheckpoint.enqueueCommentary);
1491
1355
  this.reasoningProjection = new CodexReasoningProjection(this.settlement.params, (event) => this.emitAgentEvent(event), options.onNativePlanUpdate);
1492
1356
  }
@@ -1543,6 +1407,7 @@ var CodexTurnProjection = class {
1543
1407
  asyncMessages,
1544
1408
  commentaryMessages,
1545
1409
  toolMessages: this.toolTranscriptProjection.transcriptMessages,
1410
+ steeringMessages: options?.steeringMessages,
1546
1411
  lastAssistant,
1547
1412
  turnTainted
1548
1413
  });
@@ -1689,6 +1554,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1689
1554
  this.assistantProjection.handleNotification(notification.method, params);
1690
1555
  switch (notification.method) {
1691
1556
  case "item/agentMessage/delta":
1557
+ if (readStringField(params, "delta")) this.eventProjection.markSafetyBufferingAssistantStarted();
1692
1558
  await this.assistantProjection.handleAssistantDelta(params);
1693
1559
  break;
1694
1560
  case "item/reasoning/summaryTextDelta":
@@ -1752,6 +1618,9 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1752
1618
  case "model/rerouted":
1753
1619
  this.eventProjection.handleModelRerouted(params);
1754
1620
  break;
1621
+ case "model/safetyBuffering/updated":
1622
+ this.eventProjection.handleSafetyBuffering(params);
1623
+ break;
1755
1624
  case "error": {
1756
1625
  this.usageProjection.invalidateContext();
1757
1626
  if (params.willRetry === true) {
@@ -1759,6 +1628,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1759
1628
  break;
1760
1629
  }
1761
1630
  const codexErrorInfo = isJsonObject(params.error) ? params.error.codexErrorInfo : void 0;
1631
+ this.eventProjection.handleCyberPolicyError(codexErrorInfo, this.params.modelId);
1762
1632
  const compactionFailure = codexErrorInfo === "other" && this.isCompacting();
1763
1633
  this.settledTurnFailureFinalizationAllowed = codexErrorInfo === "serverOverloaded" || compactionFailure;
1764
1634
  this.terminalFailure.record({
@@ -1779,8 +1649,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1779
1649
  case "item/fileChange/patchUpdated":
1780
1650
  case "item/mcpToolCall/progress":
1781
1651
  case "model/verification":
1782
- case "turn/moderationMetadata":
1783
- case "model/safetyBuffering/updated": break;
1652
+ case "turn/moderationMetadata": break;
1784
1653
  default: this.diagnostics.warnUnknownEvent(notification, params);
1785
1654
  }
1786
1655
  if (!this.projectionClosed && [
@@ -1789,6 +1658,23 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1789
1658
  "rawResponseItem/completed"
1790
1659
  ].includes(notification.method)) await this.settlement.project("transcript/checkpoint", () => this.transcriptCheckpoint.flush());
1791
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
+ }
1792
1678
  recordDynamicToolCall(params) {
1793
1679
  this.toolTranscriptProjection.recordDynamicToolCall(params);
1794
1680
  }
@@ -1798,7 +1684,8 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1798
1684
  if (update) {
1799
1685
  const projected = {
1800
1686
  plan: update.steps,
1801
- ...update.explanation ? { explanation: update.explanation } : {}
1687
+ ...update.explanation ? { explanation: update.explanation } : {},
1688
+ ...update.explanationFormat ? { explanationFormat: update.explanationFormat } : {}
1802
1689
  };
1803
1690
  await this.reasoningProjection.handleTurnPlanUpdated(projected, "openclaw");
1804
1691
  }
@@ -1825,8 +1712,9 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1825
1712
  }
1826
1713
  async handleItemStarted(params) {
1827
1714
  const item = readItem(params.item);
1715
+ if (item?.type === "agentMessage" && item.text) this.eventProjection.markSafetyBufferingAssistantStarted();
1828
1716
  const itemId = item?.id ?? readStringField(params, "itemId");
1829
- this.assistantProjection.recordItemStarted(item, itemId);
1717
+ await this.assistantProjection.recordItemStarted(item, itemId);
1830
1718
  if (itemId) this.activeItemIds.add(itemId);
1831
1719
  this.recordNativeToolOutcome(item);
1832
1720
  if (item?.type === "contextCompaction" && itemId) {
@@ -1874,10 +1762,12 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1874
1762
  }
1875
1763
  async handleItemCompleted(params) {
1876
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();
1877
1768
  this.diagnostics.warnUnknownItemStatus(item);
1878
1769
  this.recordNativeToolOutcome(item);
1879
1770
  this.nativeToolLifecycleProjector.clearTerminalPresentationForNativeItem(item);
1880
- const itemId = item?.id ?? readStringField(params, "itemId");
1881
1771
  if (itemId) {
1882
1772
  this.activeItemIds.delete(itemId);
1883
1773
  this.completedItemIds.add(itemId);
@@ -1886,7 +1776,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1886
1776
  const asyncMessage = this.assistantProjection.recordItemCompleted(item, itemId, this.activeItemIds);
1887
1777
  if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
1888
1778
  if (this.projectionClosed) return;
1889
- this.reasoningProjection.recordItem(item);
1779
+ await this.reasoningProjection.recordItem(item);
1890
1780
  await this.settlement.project("media_projection", () => this.generatedMediaProjection.recordNative(item));
1891
1781
  if (this.projectionClosed) return;
1892
1782
  if (item?.type === "contextCompaction" && itemId) {
@@ -1947,11 +1837,13 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1947
1837
  const turn = readCodexTurn(params.turn);
1948
1838
  if (!turn || turn.id !== this.turnId) return;
1949
1839
  this.completedTurn = turn;
1840
+ this.eventProjection.endSafetyBuffering();
1950
1841
  const compactionFailure = turn.status === "failed" && (this.terminalFailure.promptErrorSource === "compaction" || turn.error?.codexErrorInfo === "other" && this.isCompacting());
1951
1842
  this.settledTurnFailureFinalizationAllowed = turn.status === "failed" && (turn.error?.codexErrorInfo === "serverOverloaded" || compactionFailure);
1952
1843
  if (turn.status !== "completed") this.usageProjection.invalidateContext();
1953
1844
  if (turn.status === "failed") {
1954
1845
  const codexErrorInfo = turn.error?.codexErrorInfo;
1846
+ this.eventProjection.handleCyberPolicyError(codexErrorInfo, this.params.modelId);
1955
1847
  this.terminalFailure.record({
1956
1848
  message: turn.error?.message,
1957
1849
  codexErrorInfo,
@@ -1978,7 +1870,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1978
1870
  const asyncMessage = this.assistantProjection.recordSnapshotItem(item);
1979
1871
  if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
1980
1872
  if (this.projectionClosed) return;
1981
- this.reasoningProjection.recordItem(item);
1873
+ await this.reasoningProjection.recordItem(item);
1982
1874
  await this.settlement.project("media_projection", () => this.generatedMediaProjection.recordNative(item));
1983
1875
  if (this.projectionClosed) return;
1984
1876
  this.toolProgressProjection.recordToolMeta(item);
@@ -2011,6 +1903,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
2011
1903
  async handleRawResponseItemCompleted(params) {
2012
1904
  const item = isJsonObject(params.item) ? params.item : void 0;
2013
1905
  if (!item) return;
1906
+ if (item.role === "assistant" && extractRawAssistantText(item)) this.eventProjection.markSafetyBufferingAssistantStarted();
2014
1907
  this.toolTranscriptProjection.recordRawNativeToolItem(item);
2015
1908
  this.assistantProjection.handleRawResponseItemCompleted(item, this.activeItemIds);
2016
1909
  await this.settlement.project("media_projection", () => this.generatedMediaProjection.recordRaw(item));
@@ -2292,7 +2185,9 @@ function createCodexUserInputBridge(params) {
2292
2185
  embeddedAgentLog.warn("failed to bridge codex operator input", { error });
2293
2186
  return job.abort.signal.aborted ? job.cancelValue : job.failureValue;
2294
2187
  }).then((value) => {
2295
- 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);
2296
2191
  }).finally(() => {
2297
2192
  if (jobs[0] === job) jobs.shift();
2298
2193
  activeCompletion = void 0;
@@ -2355,6 +2250,11 @@ function createCodexUserInputBridge(params) {
2355
2250
  abort: new AbortController(),
2356
2251
  cancelValue,
2357
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
+ }),
2358
2258
  run: async (signal) => {
2359
2259
  const result = await execute(input, timeoutMs, signal);
2360
2260
  return result.status === "answered" ? gatewayAnswersToCodexResponse(result.answers) : cancelValue;
@@ -2381,7 +2281,7 @@ function createCodexUserInputBridge(params) {
2381
2281
  });
2382
2282
  }
2383
2283
  if (readOwnDataString(requestSnapshot, "threadId") !== params.threadId) return;
2384
- const { compileCodexOrdinaryElicitation } = await import("./elicitation-input-DPoK8F7w.js");
2284
+ const { compileCodexOrdinaryElicitation } = await import("./elicitation-input-DPoK8F7w.mjs");
2385
2285
  const compiled = compileCodexOrdinaryElicitation({
2386
2286
  snapshot: requestSnapshot,
2387
2287
  turnId: params.turnId
@@ -2439,6 +2339,7 @@ function readUserInputParams(value) {
2439
2339
  return {
2440
2340
  threadId,
2441
2341
  turnId,
2342
+ itemId,
2442
2343
  questions: parsed,
2443
2344
  isBlocking: readValue(snapshot, "isBlocking") !== false
2444
2345
  };
@@ -2550,6 +2451,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2550
2451
  emitExecutionPhaseOnce("turn_accepted", { phase: "turn_accepted" });
2551
2452
  userInputBridgeRef.current = createCodexUserInputBridge({
2552
2453
  paramsForRun: params,
2454
+ onOrdinaryResponse: (response) => projectorRef.current?.recordUserInputResponse(response),
2553
2455
  threadId: resourceState.thread.threadId,
2554
2456
  turnId: activeTurnId,
2555
2457
  signal: runAbortController.signal
@@ -2637,7 +2539,10 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2637
2539
  state.terminalTurnNotificationQueued = true;
2638
2540
  deadlines.beginSettlement(Date.now());
2639
2541
  }
2640
- emitLifecycleStart();
2542
+ emitLifecycleStart({
2543
+ provider: projectionParams.provider,
2544
+ model: projectionParams.modelId
2545
+ });
2641
2546
  const activeProjector = projectorRef.current;
2642
2547
  noteProgress("turn:start");
2643
2548
  const abortListener = () => {
@@ -2733,12 +2638,33 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2733
2638
  userTurnTranscriptRecorder: options.userTurnTranscriptRecorder
2734
2639
  });
2735
2640
  if (result.failedMediaCount) throw new Error(`failed to hydrate ${result.failedMediaCount} structured image attachment(s) for Codex steering`);
2736
- 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
+ };
2737
2662
  },
2738
2663
  beforeSubmit: async (items) => {
2739
2664
  const transcriptItems = items.filter((item) => item.isInboundUserMessage === true || item.userTurnTranscriptRecorder !== void 0);
2740
2665
  if (transcriptItems.length === 0) return;
2741
- await promptMirrorPromise;
2666
+ await projectionReady;
2667
+ await notifications.drainNotificationQueue();
2742
2668
  assertSteeringActive();
2743
2669
  const messages = activeProjector.buildSteeringTranscriptPrefix();
2744
2670
  if (params.sessionTarget && messages.length > 0) {
@@ -2862,6 +2788,11 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2862
2788
  cancel: () => abortExplicitly("cancelled"),
2863
2789
  abort: () => abortExplicitly("aborted")
2864
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();
2865
2796
  params.replyOperation?.attachBackend(handle);
2866
2797
  setActiveEmbeddedRun(params.sessionId, handle, params.sessionKey, params.sessionFile, sessionAgentId);
2867
2798
  const freezeRunTerminalOutcome = () => {
@@ -2882,7 +2813,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2882
2813
  freezeRunTerminalOutcome,
2883
2814
  notifyUserMessagePersisted,
2884
2815
  abortListener,
2885
- ready: bindProjection()
2816
+ ready: projectionReady
2886
2817
  };
2887
2818
  }
2888
2819
  //#endregion
@@ -2906,6 +2837,7 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2906
2837
  else await state.abortCleanup?.catch(() => {});
2907
2838
  if (params.oneShotCliRun) await runCleanupStep("codex-one-shot-terminals", () => terminateCodexBackgroundTerminals(resourceState.client, resourceState.thread.threadId, true));
2908
2839
  try {
2840
+ await state.pluginRuntimeRefreshStop;
2909
2841
  steeringQueueRef.current?.cancel();
2910
2842
  if (params.isFinalFallbackAttempt !== false) await maybeEmitFastModeAutoResetBestEffort();
2911
2843
  codexModelCallDiagnostics.emitError("codex app-server run completed without model-call terminal event");
@@ -2925,8 +2857,9 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2925
2857
  aborted: runAbortController.signal.aborted && !state.clientClosedAbort
2926
2858
  });
2927
2859
  await runCleanupStep("codex-trajectory-flush", () => trajectoryRecorder?.flush());
2928
- const retainLiveIncognitoThread = (terminalState.settledTurnStatus === "completed" || state.permissionChangeRestart === "confirmed" && !params.abortSignal?.aborted) && isIncognitoSessionKey(params.sessionKey);
2929
- 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 () => {
2930
2863
  if (bindingStore.read(bindingIdentity)?.threadId !== resourceState.thread.threadId) return false;
2931
2864
  return await retainCodexAppServerBindingSubscription(resourceState.client, resourceState.thread.threadId, {
2932
2865
  release: resourceState.thread.liveThreadOwnership?.release,
@@ -2935,20 +2868,42 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2935
2868
  ephemeralPolicy: resourceState.thread.liveThreadEphemeralPolicy
2936
2869
  });
2937
2870
  }) : false) || retainLiveIncognitoThread && resourceState.thread.liveThreadEphemeralPolicy === void 0;
2938
- const bindingReleased = isIncognitoSessionKey(params.sessionKey) && !retainLiveThread ? await bindingStore.mutate(bindingIdentity, {
2939
- kind: "clear",
2940
- threadId: resourceState.thread.threadId
2941
- }) : true;
2942
- if (!retainLiveThread) {
2943
- 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.");
2944
2877
  if (!await unsubscribeCodexThreadBestEffort(resourceState.client, {
2945
2878
  threadId: resourceState.thread.threadId,
2946
- timeoutMs: 5e3
2879
+ timeoutMs: 5e3,
2880
+ assertCurrent: connection.assertCurrent
2947
2881
  })) {
2948
2882
  await closeCodexStartupClientBestEffort(resourceState.client);
2949
- if (params.oneShotCliRun) await runCleanupStep("codex-one-shot-unsubscribe", async () => {
2950
- throw new Error("Codex one-shot thread unsubscribe was not confirmed");
2951
- });
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
+ }
2952
2907
  }
2953
2908
  }
2954
2909
  }
@@ -2966,13 +2921,14 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2966
2921
  await runCleanupStep("codex-shared-client-release", releaseSharedClientLeaseAndRetireOneShotClient);
2967
2922
  const nativeHookRelay = resourceState.nativeHookRelay;
2968
2923
  resourceState.nativeHookRelay = void 0;
2969
- await runCleanupStep("codex-native-hook-relay-release", () => {
2924
+ await runCleanupStep("codex-native-hook-relay-release", async () => {
2970
2925
  if (!nativeHookRelay) return;
2971
2926
  if (state.shouldDelayNativeHookRelayUnregister && !params.oneShotCliRun) scheduleCodexNativeHookRelayUnregister({
2972
2927
  relay: nativeHookRelay,
2973
2928
  hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec
2974
2929
  });
2975
2930
  else nativeHookRelay.unregister();
2931
+ await nativeHookRelay.drain();
2976
2932
  });
2977
2933
  await runCleanupStep("codex-sandbox-release", releaseSandboxExecEnvironment);
2978
2934
  await runCleanupStep("codex-abort-listener-remove", () => {
@@ -2987,72 +2943,6 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2987
2943
  await state.abortCleanup;
2988
2944
  }
2989
2945
  //#endregion
2990
- //#region extensions/codex/src/app-server/workspace-dir-cache.ts
2991
- /** Process-local cache of Codex workspaces already created by the run loop. */
2992
- const codexWorkspaceDirCache = /* @__PURE__ */ new Set();
2993
- //#endregion
2994
- //#region extensions/codex/src/app-server/run-attempt-lifecycle.ts
2995
- const CODEX_APP_SERVER_PROJECTED_CHARS_PER_TOKEN = 4;
2996
- function shouldKeepCodexSharedAbortOpen(params) {
2997
- const terminal = attemptTerminal.project(params.result.terminal);
2998
- if (params.explicitCancellationObserved || terminal.aborted || terminal.externalAbort) return false;
2999
- return params.trigger === "memory" || !params.attemptSucceeded;
3000
- }
3001
- function withCodexAppServerFastModeServiceTier(appServer, params) {
3002
- const fastMode = typeof params.fastMode === "function" ? params.fastMode() : params.fastMode;
3003
- const serviceTier = fastMode === void 0 ? appServer.serviceTier : fastMode ? "priority" : void 0;
3004
- if (serviceTier === appServer.serviceTier) return appServer;
3005
- if (serviceTier) return {
3006
- ...appServer,
3007
- serviceTier
3008
- };
3009
- return {
3010
- ...appServer,
3011
- serviceTier: null
3012
- };
3013
- }
3014
- function estimateCodexAppServerProjectedTurnTokens(params) {
3015
- const inputChars = params.prompt.length + (params.developerInstructions?.length ?? 0);
3016
- return Math.max(1, Math.ceil(inputChars / CODEX_APP_SERVER_PROJECTED_CHARS_PER_TOKEN));
3017
- }
3018
- async function ensureCodexWorkspaceDirOnce(workspaceDir) {
3019
- const normalized = path.resolve(workspaceDir);
3020
- if (codexWorkspaceDirCache.has(normalized)) return;
3021
- await fs.mkdir(normalized, { recursive: true });
3022
- codexWorkspaceDirCache.add(normalized);
3023
- }
3024
- async function emitCodexAppServerEvent(params, event) {
3025
- try {
3026
- emitAgentEvent({
3027
- runId: params.runId,
3028
- stream: event.stream,
3029
- data: event.data,
3030
- ...params.sessionKey ? { sessionKey: params.sessionKey } : {}
3031
- });
3032
- } catch (error) {
3033
- embeddedAgentLog.debug("codex app-server global agent event emit failed", { error });
3034
- }
3035
- try {
3036
- await params.onAgentEvent?.(event);
3037
- } catch (error) {
3038
- embeddedAgentLog.debug("codex app-server agent event handler threw", { error });
3039
- }
3040
- }
3041
- async function runCodexAgentEndHook(params, hookParams) {
3042
- const sideEffectParams = {
3043
- ...hookParams,
3044
- ctx: {
3045
- ...hookParams.ctx,
3046
- config: params.config
3047
- }
3048
- };
3049
- if (!params.messageChannel && !params.messageProvider) {
3050
- await awaitAgentEndSideEffects(sideEffectParams);
3051
- return;
3052
- }
3053
- runAgentEndSideEffects(sideEffectParams);
3054
- }
3055
- //#endregion
3056
2946
  //#region extensions/codex/src/app-server/startup-binding.ts
3057
2947
  const CODEX_APP_SERVER_NATIVE_THREAD_FALLBACK_MAX_TOKENS = 3e5;
3058
2948
  const CODEX_APP_SERVER_NATIVE_THREAD_DEFAULT_RESERVE_TOKENS = 2e4;
@@ -3473,7 +3363,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3473
3363
  const usesSupervisionConnection = startupBinding?.connectionScope === "supervision";
3474
3364
  if (usesSupervisionConnection) activeContextEngine = void 0;
3475
3365
  if (usesSupervisionConnection && pluginConfig.supervision?.enabled !== true) throw new Error("Codex supervision is disabled; refusing to open a native user-home supervised session");
3476
- const resolveRuntimeOptionsForBinding = (binding, selection) => resolveCodexBindingAppServerConnection({
3366
+ const resolveRuntimeOptionsForBinding = async (binding, selection) => (await resolveCodexBindingAppServerConnection({
3477
3367
  binding,
3478
3368
  pluginConfig,
3479
3369
  execPolicy,
@@ -3483,8 +3373,9 @@ async function prepareCodexAttemptConnection({ params, options }) {
3483
3373
  agentDir,
3484
3374
  requirementsToml,
3485
3375
  openClawSandboxActive: sandbox?.enabled === true,
3486
- sessionPermissionMode: params.permissionMode
3487
- }).appServer;
3376
+ sessionPermissionMode: params.permissionMode,
3377
+ assertCurrent
3378
+ })).appServer;
3488
3379
  const initialStartupBindingHadInactiveThreadBootstrap = isInactiveThreadBootstrapBinding(startupBinding);
3489
3380
  const appServerHomeScope = resolveCodexAppServerHomeScope({ appServer: pluginConfig.appServer });
3490
3381
  const preparedAuthRoute = usesSupervisionConnection ? void 0 : params.runtimePlan?.auth.modelRoute;
@@ -3527,7 +3418,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3527
3418
  };
3528
3419
  let reviewerPolicyContext = resolveReviewerPolicyContext(startupBinding);
3529
3420
  preDynamicStartupStages.mark("auth-profile");
3530
- let configuredAppServer = resolveRuntimeOptionsForBinding(startupBinding, {
3421
+ let configuredAppServer = await resolveRuntimeOptionsForBinding(startupBinding, {
3531
3422
  modelProvider: reviewerPolicyContext.modelProvider,
3532
3423
  model: reviewerPolicyContext.model
3533
3424
  });
@@ -3638,7 +3529,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3638
3529
  preDynamicStartupStages.mark("rotate-binding");
3639
3530
  if (startupBinding !== startupBindingBeforeRotation) {
3640
3531
  reviewerPolicyContext = resolveReviewerPolicyContext(startupBinding);
3641
- configuredAppServer = resolveRuntimeOptionsForBinding(startupBinding, {
3532
+ configuredAppServer = await resolveRuntimeOptionsForBinding(startupBinding, {
3642
3533
  modelProvider: reviewerPolicyContext.modelProvider,
3643
3534
  model: reviewerPolicyContext.model
3644
3535
  });
@@ -3666,7 +3557,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3666
3557
  pluginAppServer: appServer,
3667
3558
  continuityCalibration: startupBindingBeforeRotation?.continuityCalibration
3668
3559
  };
3669
- const resolveRuntimeOptionsForCurrentBinding = (selection) => resolveFinalAppServer(resolveRuntimeOptionsForBinding(mutable.startupBinding, selection), selection).appServer;
3560
+ const resolveRuntimeOptionsForCurrentBinding = async (selection) => resolveFinalAppServer(await resolveRuntimeOptionsForBinding(mutable.startupBinding, selection), selection).appServer;
3670
3561
  assertCurrent();
3671
3562
  return {
3672
3563
  params,
@@ -3784,6 +3675,7 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
3784
3675
  const messages = await readMirroredSessionHistoryMessages({
3785
3676
  ...activeTranscriptTarget,
3786
3677
  signal: connection.runAbortController.signal,
3678
+ contextTokenBudget: effectiveContextTokenBudget,
3787
3679
  ...transcriptReadFence ? { admission: transcriptReadFence } : {}
3788
3680
  });
3789
3681
  connection.runAbortController.signal.throwIfAborted();
@@ -3853,6 +3745,7 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
3853
3745
  });
3854
3746
  historyState.messages = await readFencedHistory() ?? historyState.messages;
3855
3747
  }
3748
+ historyState.messages.push(...params.pluginRuntimeRefreshMessages ?? []);
3856
3749
  const memoryToolNames = getCodexWorkspaceMemoryToolNames(toolBridge.availableSpecs);
3857
3750
  const workspaceBootstrapContext = await buildCodexWorkspaceBootstrapContext({
3858
3751
  params: runtimeParams,
@@ -4219,6 +4112,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4219
4112
  clearTimeout(drainGraceTimer);
4220
4113
  deadlines.dispose();
4221
4114
  };
4115
+ if (state.pluginRuntimeRefreshStop) await state.pluginRuntimeRefreshStop.catch(() => void 0);
4222
4116
  const settlement = drainNotificationQueue().then(async () => {
4223
4117
  await closeProjection();
4224
4118
  await activeProjector.settlement.drain();
@@ -4238,7 +4132,10 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4238
4132
  } finally {
4239
4133
  if (!state.projectionClosed) await resources.runCleanupStep("codex-transcript-checkpoint", closeProjection);
4240
4134
  }
4241
- 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
+ });
4242
4139
  const projectedTerminal = attemptTerminal.project(result.terminal);
4243
4140
  const isFinalAborted = () => terminalState.explicitCancellationObserved || !resourceState.executionDisconnectError && (projectedTerminal.aborted || runAbortController.signal.aborted && !state.clientClosedAbort);
4244
4141
  const currentPromptError = (fallback) => resourceState.executionDisconnectError ?? state.clientClosedPromptError ?? (state.timeout ? `codex app-server ${state.timeout.kind === "execution" ? "execution budget" : "terminal settlement"} timed out` : fallback);
@@ -4483,7 +4380,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4483
4380
  hookRunner
4484
4381
  });
4485
4382
  state.shouldDelayNativeHookRelayUnregister = completedTurnStatus === "completed" && !effectiveTimedOut && !runAbortController.signal.aborted && !finalAborted && !finalPromptError;
4486
- if (turnSucceeded && !runAbortController.signal.aborted) try {
4383
+ if (turnSucceeded && !runAbortController.signal.aborted && !state.pluginRuntimeRefreshStop) try {
4487
4384
  const continuityCalibration = context.promptState.noEngineContinuityProjectionApplied ? buildCodexContinuityCalibration({
4488
4385
  promptChars: prompt.turnState.codexTurnPromptText.length,
4489
4386
  inputTokens: result.attemptUsage?.contextUsage?.state === "available" ? result.attemptUsage.contextUsage.promptTokens ?? 0 : 0
@@ -4528,27 +4425,30 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4528
4425
  });
4529
4426
  markTrajectoryEndRecorded();
4530
4427
  const terminalAssistantText = collectTerminalAssistantText(result);
4531
- if (terminalAssistantText && (!streamState.eventEmitted || streamState.needsTerminalSnapshot) && !finalAborted && !finalPromptError) emitCodexAppServerEvent(params, {
4428
+ if (terminalAssistantText && (assistantTranscriptIdempotencyKey || (!streamState.eventEmitted || streamState.needsTerminalSnapshot) && !finalAborted && !finalPromptError)) emitCodexAppServerEvent(params, {
4532
4429
  stream: "assistant",
4533
- data: { text: terminalAssistantText }
4430
+ data: {
4431
+ text: terminalAssistantText,
4432
+ ...assistantTranscriptIdempotencyKey ? {
4433
+ itemId: assistantTranscriptIdempotencyKey,
4434
+ replace: true,
4435
+ replaceable: true
4436
+ } : {}
4437
+ }
4534
4438
  });
4535
- emitLifecycleTerminal(finalPromptError ? {
4536
- phase: "error",
4537
- error: formatErrorMessage(finalPromptError),
4538
- ...buildLifecycleTerminalMeta({
4539
- aborted: finalAborted,
4540
- timedOut: effectiveTimedOut
4541
- })
4542
- } : {
4543
- phase: "end",
4439
+ emitLifecycleTerminal({
4440
+ phase: finalPromptError ? "error" : "end",
4441
+ ...finalPromptError ? { error: formatErrorMessage(finalPromptError) } : {},
4442
+ ...assistantTranscriptIdempotencyKey ? { assistantTranscriptIdempotencyKey } : {},
4544
4443
  ...buildLifecycleTerminalMeta({
4545
4444
  aborted: finalAborted,
4546
4445
  timedOut: effectiveTimedOut,
4547
- yielded: toolState.yieldDetected
4446
+ yielded: finalPromptError ? void 0 : toolState.yieldDetected
4548
4447
  })
4549
4448
  });
4550
4449
  const finalizedResult = Object.assign(result, {
4551
4450
  ...runtimeModelSelection ? { runtimeModelSelection } : {},
4451
+ ...turnSucceeded && params.pluginRuntimeRefreshPending?.() ? { pluginRuntimeRefreshMessages: params.suppressNextUserMessagePersistence && !params.pluginRuntimeRefreshMessages ? [params.userTurnTranscriptRecorder?.getPersistedMessage?.() ?? buildCodexUserPromptMessage(params), ...result.messagesSnapshot] : result.messagesSnapshot } : {},
4552
4452
  ...toolState.yieldAcknowledgment ? { yieldAcknowledgment: toolState.yieldAcknowledgment } : {},
4553
4453
  ...codexAppServerFailure ? { codexAppServerFailure } : {},
4554
4454
  ...promptTimeoutOutcome ? { promptTimeoutOutcome } : {},
@@ -4675,7 +4575,7 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
4675
4575
  state.pendingTerminalDynamicToolRelease = value;
4676
4576
  scheduleTerminalDynamicToolReleaseCheck();
4677
4577
  };
4678
- const emitLifecycleStart = () => {
4578
+ const emitLifecycleStart = (model) => {
4679
4579
  emitCodexAppServerEvent(params, {
4680
4580
  stream: "lifecycle",
4681
4581
  data: {
@@ -4683,10 +4583,17 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
4683
4583
  startedAt: attemptStartedAt
4684
4584
  }
4685
4585
  });
4586
+ emitCodexAppServerEvent(params, {
4587
+ stream: "lifecycle",
4588
+ data: {
4589
+ phase: "model",
4590
+ ...model
4591
+ }
4592
+ });
4686
4593
  state.lifecycleStarted = true;
4687
4594
  };
4688
4595
  const emitLifecycleTerminal = (data) => {
4689
- if (!state.lifecycleStarted || state.lifecycleTerminalEmitted || state.permissionChangeRestart) return;
4596
+ if (!state.lifecycleStarted || state.lifecycleTerminalEmitted || state.permissionChangeRestart || params.pluginRuntimeRefreshPending?.()) return;
4690
4597
  emitCodexAppServerEvent(params, {
4691
4598
  stream: "lifecycle",
4692
4599
  data: {
@@ -4784,13 +4691,29 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
4784
4691
  //#endregion
4785
4692
  //#region extensions/codex/src/app-server/run-attempt-notification-controller.ts
4786
4693
  function createCodexAttemptNotificationController(resources, turnRuntime, lifecycle) {
4787
- const { prompt, state: resourceState, projectorRef, registerNativeSubagentMonitor } = resources;
4694
+ const { prompt, state: resourceState, projectorRef } = resources;
4788
4695
  const { context, turnState } = prompt;
4789
4696
  const { attemptTools, runtime } = context;
4790
4697
  const { appServer, runAbortController } = runtime.connection;
4791
4698
  const { allocateCodexToolOutcomeOrdinal } = attemptTools;
4792
4699
  const { state, turnIdRef, userInputBridgeRef, steeringQueueRef, activeTurnItemIds, pendingOpenClawDynamicToolCompletionIds, openClawDynamicToolExecutions, completeTurn, noteProgress, deadlines } = turnRuntime;
4793
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
+ };
4794
4717
  const isTerminalTurnNotificationForTurn = (notification, notificationTurnId) => isTerminalCodexTurnNotificationForTurn({
4795
4718
  notification,
4796
4719
  threadId: resourceState.thread.threadId,
@@ -4845,6 +4768,11 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
4845
4768
  });
4846
4769
  } finally {
4847
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();
4848
4776
  if (isTerminal) {
4849
4777
  if ((readCodexTurnCompletedNotification(notification.params)?.turn)?.status === "interrupted" && state.sawCodexInterruptMarker) projector.markAborted();
4850
4778
  completeTurn();
@@ -4883,6 +4811,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
4883
4811
  const modelToolCallId = readRawResponseToolCallId(notification);
4884
4812
  if (modelToolCallId) allocateCodexToolOutcomeOrdinal?.(modelToolCallId);
4885
4813
  const nativeItem = readCodexNotificationItem(notification.params);
4814
+ if (notification.method === "item/started" && nativeItem?.type === "commandExecution" && typeof nativeItem.id === "string") pendingNativeCommandItems.add(nativeItem.id);
4886
4815
  if (nativeItem?.type === "webSearch") {
4887
4816
  projector.settlement.turnTainted ||= notification.method === "item/completed";
4888
4817
  projector.recordNativeToolOutcome(nativeItem);
@@ -4899,9 +4828,9 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
4899
4828
  const drainNotificationQueue = async () => {
4900
4829
  await resourceState.turnRoute?.drain();
4901
4830
  };
4902
- registerNativeSubagentMonitor(resourceState.thread.threadId);
4903
4831
  return {
4904
4832
  waitForActiveNativeTurnCompletion,
4833
+ waitForNativeTerminalItems,
4905
4834
  noteNotificationReceived,
4906
4835
  enqueueNotification,
4907
4836
  drainNotificationQueue
@@ -4917,13 +4846,24 @@ async function prepareCodexAttemptPrompt(context) {
4917
4846
  const { connection, buildActiveRunAttemptParams, effectiveContextTokenBudget, effectiveRuntimeModelId, effectiveRuntimeProviderId } = runtime;
4918
4847
  const { params, activeContextEngine, usesSupervisionConnection, mutable, isInactiveThreadBootstrapBinding, bindingStore, bindingIdentity, agentDir, appServer, contextSessionKey, effectiveWorkspace, sandbox } = connection;
4919
4848
  const { toolBridge } = attemptTools;
4920
- let contextImages = [];
4921
- 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 = [];
4922
4859
  const assertProjectionCurrent = () => {
4923
4860
  params.hostCapabilities.assertActive();
4924
4861
  connection.assertCurrent();
4925
4862
  connection.runAbortController.signal.throwIfAborted();
4926
4863
  };
4864
+ const admittedMessage = params.userTurnTranscriptRecorder?.message ?? await params.userTurnTranscriptRecorder?.resolveMessage();
4865
+ assertProjectionCurrent();
4866
+ const currentUserTurnIdempotencyKey = params.pluginRuntimeRefreshMessages ? void 0 : admittedMessage?.idempotencyKey;
4927
4867
  const prepareFileContext = async (message, maxChars) => {
4928
4868
  const prepare = params.hostCapabilities.prepareContextMedia;
4929
4869
  if (!prepare) {
@@ -4949,11 +4889,12 @@ async function prepareCodexAttemptPrompt(context) {
4949
4889
  originalHistoryMessages: historyState.messages,
4950
4890
  prompt: params.prompt,
4951
4891
  maxRenderedContextChars: codexContinuityProjectionMaxChars,
4892
+ toolPayloadMode: params.pluginRuntimeRefreshMessages || preserveForkedToolResults ? "preserve" : "elide",
4952
4893
  prepareFileContext,
4953
4894
  currentUserTurnIdempotencyKey
4954
4895
  });
4955
4896
  assertProjectionCurrent();
4956
- contextImages = projection.images ?? [];
4897
+ contextImageGroups = projection.imageGroups ?? [];
4957
4898
  promptState.promptText = projection.promptText;
4958
4899
  promptState.promptContextRange = projection.promptContextRange;
4959
4900
  promptState.prePromptMessageCount = projection.prePromptMessageCount;
@@ -4998,12 +4939,12 @@ async function prepareCodexAttemptPrompt(context) {
4998
4939
  prompt: params.prompt,
4999
4940
  systemPromptAddition: assembled.systemPromptAddition,
5000
4941
  maxRenderedContextChars: codexContextProjectionMaxChars,
5001
- toolPayloadMode: contextEngineProjection ? "preserve" : "elide",
4942
+ toolPayloadMode: contextEngineProjection || params.pluginRuntimeRefreshMessages || preserveForkedToolResults ? "preserve" : "elide",
5002
4943
  ...projectionDecision.project ? { prepareFileContext } : {},
5003
4944
  currentUserTurnIdempotencyKey
5004
4945
  });
5005
4946
  assertProjectionCurrent();
5006
- contextImages = projectionDecision.project ? projection.images ?? [] : [];
4947
+ contextImageGroups = projectionDecision.project ? projection.imageGroups ?? [] : [];
5007
4948
  const decisionBinding = decisionStartupBinding;
5008
4949
  embeddedAgentLog.info("codex app-server context-engine projection decision", {
5009
4950
  sessionId: params.sessionId,
@@ -5031,13 +4972,17 @@ async function prepareCodexAttemptPrompt(context) {
5031
4972
  if (activeContextEngine) try {
5032
4973
  await applyActiveContextEngineProjection(runtime.nativeToolSurfaceEnabled ? mutable.startupBinding : void 0);
5033
4974
  } catch (assembleErr) {
5034
- if (assembleErr instanceof CodexContextAttachmentError) throw assembleErr;
4975
+ if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
5035
4976
  assertProjectionCurrent();
5036
4977
  embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
5037
4978
  }
5038
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;
5039
4982
  const buildPromptFromCurrentInputs = async () => {
5040
4983
  return await resolveAgentHarnessBeforePromptBuildResult({
4984
+ currentUserMessage,
4985
+ currentUserMessageId: admittedMessage?.idempotencyKey,
5041
4986
  prompt: prependCurrentInboundContext(promptState.promptText, params.currentInboundContext),
5042
4987
  developerInstructions: { build: ({ toolsAllow }) => {
5043
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.");
@@ -5087,12 +5032,21 @@ async function prepareCodexAttemptPrompt(context) {
5087
5032
  promptInputRange: promptBuildResult.promptInputRange,
5088
5033
  decoratedPrompt: turnPromptText
5089
5034
  });
5090
- return fitCodexProjectedContextForTurnStart({
5035
+ const imageOffset = projectedRanges && promptState.promptContextRange ? projectedRanges.contextRange.start - promptState.promptContextRange.start : void 0;
5036
+ const fitted = fitCodexProjectedContextForTurnStart({
5091
5037
  promptText: turnPromptText,
5038
+ maxChars: CODEX_TURN_START_TEXT_INPUT_MAX_CHARS - (nativeHistoryProvenancePrefix?.length ?? 0),
5092
5039
  contextRange: projectedRanges?.contextRange,
5093
5040
  requestRange: projectedRanges?.requestRange,
5094
- 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
+ }))
5095
5047
  });
5048
+ turnContextImageGroups = fitted.imageGroups ?? [];
5049
+ return fitted.promptText;
5096
5050
  };
5097
5051
  const firstPromptBuild = await buildPromptFromCurrentInputs();
5098
5052
  const turnState = {
@@ -5149,7 +5103,7 @@ async function prepareCodexAttemptPrompt(context) {
5149
5103
  };
5150
5104
  const applyNoContextEngineContinuityProjection = async (action, binding) => {
5151
5105
  const hasContinuity = historyState.messages.some((message) => message.role === "user" || isCodexDurableCustomMessage(message) || action === "started" && (message.role === "compactionSummary" || message.role === "branchSummary"));
5152
- if (activeContextEngine || !hasContinuity) return false;
5106
+ if (activeContextEngine || !hasContinuity && !params.pluginRuntimeRefreshMessages?.length) return false;
5153
5107
  if (action === "resumed" && promptState.precomputedStaleBindingContinuityProjectionApplied) return true;
5154
5108
  if (action === "started" && promptState.staleBindingContinuityForcedFreshStart) return true;
5155
5109
  if (action === "started" && promptState.inactiveThreadBootstrapBindingForcedFreshStart) return false;
@@ -5193,7 +5147,7 @@ async function prepareCodexAttemptPrompt(context) {
5193
5147
  try {
5194
5148
  await applyActiveContextEngineProjection(void 0);
5195
5149
  } catch (assembleErr) {
5196
- if (assembleErr instanceof CodexContextAttachmentError) throw assembleErr;
5150
+ if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
5197
5151
  assertProjectionCurrent();
5198
5152
  embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
5199
5153
  }
@@ -5222,10 +5176,11 @@ async function prepareCodexAttemptPrompt(context) {
5222
5176
  let workspaceReferencesIncluded = true;
5223
5177
  return {
5224
5178
  context,
5225
- get contextImages() {
5226
- return contextImages;
5179
+ get contextImageGroups() {
5180
+ return turnContextImageGroups;
5227
5181
  },
5228
5182
  codexModelInputHistoryMessages,
5183
+ nativeHistoryProvenancePrefix,
5229
5184
  turnState,
5230
5185
  refreshWorkspaceReferences: (include) => {
5231
5186
  turnState.codexTurnPromptText = decorateCodexTurnPromptText(turnState.promptBuild, include);
@@ -5380,12 +5335,16 @@ function prepareCodexAttemptResources(prompt) {
5380
5335
  await operation();
5381
5336
  }
5382
5337
  });
5383
- const unregisterNativeSubagentMonitor = () => {
5384
- state.nativeSubagentMonitor?.unregister();
5338
+ let nativeSubagentMonitorSettlement;
5339
+ const unregisterNativeSubagentMonitor = async () => {
5340
+ const registration = state.nativeSubagentMonitor;
5385
5341
  state.nativeSubagentMonitor = void 0;
5342
+ if (registration) nativeSubagentMonitorSettlement = registration.unregister();
5343
+ await nativeSubagentMonitorSettlement;
5386
5344
  };
5387
- const registerNativeSubagentMonitor = (parentThreadId) => {
5388
- unregisterNativeSubagentMonitor();
5345
+ const registerNativeSubagentMonitor = async (parentThreadId) => {
5346
+ await unregisterNativeSubagentMonitor();
5347
+ connection.assertCurrent();
5389
5348
  const sessionKey = params.sessionKey;
5390
5349
  const storePath = params.sessionTarget?.storePath;
5391
5350
  const parentSession = sessionKey && storePath ? getSessionEntry({
@@ -5395,17 +5354,46 @@ function prepareCodexAttemptResources(prompt) {
5395
5354
  readConsistency: "latest",
5396
5355
  hydrateSkillPromptRefs: false
5397
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;
5398
5390
  state.nativeSubagentMonitor = codexNativeSubagentMonitorRuntime.register({
5399
5391
  client: state.client,
5400
5392
  parentThreadId,
5401
5393
  requesterSessionKey: params.sessionKey,
5402
5394
  taskRuntimeScope: params.agentHarnessTaskRuntimeScope,
5403
- historyOwner: createCodexNativeSubagentHistoryOwner({
5404
- parentThreadId,
5405
- sessionId: params.sessionId,
5406
- ...parentSession?.sessionId === params.sessionId ? { lifecycleRevision: parentSession.lifecycleRevision } : {},
5407
- binding: state.thread
5408
- }),
5395
+ historyOwner,
5396
+ submissionStore,
5409
5397
  agentId: sessionAgentId,
5410
5398
  retainClient: () => retainSharedCodexAppServerClientIfCurrent(state.client),
5411
5399
  retainParentThread: (protectedThreadId) => protectCodexAppServerLiveThread(state.client, protectedThreadId),
@@ -5416,7 +5404,7 @@ function prepareCodexAttemptResources(prompt) {
5416
5404
  } } : {}
5417
5405
  });
5418
5406
  };
5419
- const releaseCurrentRoute = () => {
5407
+ const releaseCurrentRoute = async () => {
5420
5408
  state.releaseInferenceContext?.();
5421
5409
  state.releaseInferenceContext = void 0;
5422
5410
  state.detachRouteAbort();
@@ -5424,7 +5412,7 @@ function prepareCodexAttemptResources(prompt) {
5424
5412
  state.turnRoute?.release();
5425
5413
  state.turnRoute = void 0;
5426
5414
  state.routeActivated = false;
5427
- unregisterNativeSubagentMonitor();
5415
+ await unregisterNativeSubagentMonitor();
5428
5416
  };
5429
5417
  const startupTimeoutMs = resolveCodexStartupTimeoutMs({
5430
5418
  timeoutMs: params.timeoutMs,
@@ -5432,8 +5420,11 @@ function prepareCodexAttemptResources(prompt) {
5432
5420
  });
5433
5421
  const requesterChannel = params.messageChannel ?? params.messageProvider;
5434
5422
  const requester = buildCodexHookRequester(params);
5435
- const buildNativeHookRelayFinalConfigPatch = (decision) => {
5436
- state.nativeHookRelay?.unregister();
5423
+ const buildNativeHookRelayFinalConfigPatch = async (decision) => {
5424
+ const previousRelay = state.nativeHookRelay;
5425
+ previousRelay?.unregister();
5426
+ await previousRelay?.drain();
5427
+ connection.assertCurrent();
5437
5428
  if (params.pluginHarnessToolPolicyRestricted === true) {
5438
5429
  state.nativeHookRelay = void 0;
5439
5430
  return {
@@ -5477,6 +5468,8 @@ function prepareCodexAttemptResources(prompt) {
5477
5468
  else pendingNativePreToolUseFailures.push(failure);
5478
5469
  }
5479
5470
  });
5471
+ await state.nativeHookRelay?.prepareInvocation();
5472
+ connection.assertCurrent();
5480
5473
  return {
5481
5474
  configPatch: state.nativeHookRelay ? buildCodexNativeHookRelayConfig({
5482
5475
  relay: state.nativeHookRelay,
@@ -5509,7 +5502,7 @@ function prepareCodexAttemptResources(prompt) {
5509
5502
  //#endregion
5510
5503
  //#region extensions/codex/src/app-server/run-attempt-route.ts
5511
5504
  async function prepareCodexAttemptRoute(resources, turnRuntime, notifications, handleServerRequest) {
5512
- const { prompt, state: resourceState, trajectoryRecorder, releaseCurrentRoute, registerNativeSubagentMonitor, activateNativePreToolUseFailureFallback, releaseSandboxExecEnvironment, releaseSharedClientLeaseOnce } = resources;
5505
+ const { prompt, state: resourceState, trajectoryRecorder, releaseCurrentRoute, registerNativeSubagentMonitor, activateNativePreToolUseFailureFallback, releaseSandboxExecEnvironment, releaseSharedClientLeaseOnce, runCleanupStep } = resources;
5513
5506
  const { connection } = prompt.context.runtime;
5514
5507
  const { runAbortController } = connection;
5515
5508
  const { state, turnIdRef, completeTurn } = turnRuntime;
@@ -5542,12 +5535,12 @@ async function prepareCodexAttemptRoute(resources, turnRuntime, notifications, h
5542
5535
  };
5543
5536
  const ensureCurrentThreadRoute = async () => {
5544
5537
  if (resourceState.turnRoute?.threadId !== resourceState.thread.threadId) {
5545
- releaseCurrentRoute();
5538
+ await releaseCurrentRoute();
5546
5539
  resourceState.turnRoute = resourceState.turnRouter.reserveThread({ threadId: resourceState.thread.threadId });
5547
5540
  }
5548
5541
  if (!resourceState.turnRoute) throw new Error("codex app-server turn route was not reserved");
5549
5542
  if (!resourceState.routeActivated) {
5550
- if (!resourceState.nativeSubagentMonitor) registerNativeSubagentMonitor(resourceState.thread.threadId);
5543
+ if (!resourceState.nativeSubagentMonitor) await registerNativeSubagentMonitor(resourceState.thread.threadId);
5551
5544
  resourceState.detachRouteAbort = attachRouteAbort(resourceState.turnRoute);
5552
5545
  await resourceState.turnRoute.activate({
5553
5546
  onNotificationReceived: noteNotificationReceived,
@@ -5562,8 +5555,18 @@ async function prepareCodexAttemptRoute(resources, turnRuntime, notifications, h
5562
5555
  await ensureCurrentThreadRoute();
5563
5556
  } catch (error) {
5564
5557
  activateNativePreToolUseFailureFallback();
5565
- releaseCurrentRoute();
5566
- 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
+ });
5567
5570
  await releaseSandboxExecEnvironment();
5568
5571
  releaseSharedClientLeaseOnce();
5569
5572
  throw error;
@@ -5690,7 +5693,7 @@ async function prepareCodexAttemptRuntime(connection) {
5690
5693
  const authenticatedScheduledMode = params.trigger === "cron" && params.scheduledToolPolicy !== void 0 && Array.isArray(params.toolsAllow);
5691
5694
  const scheduledConfiguredMcpSurface = authenticatedScheduledMode && (bundleMcpThreadConfig.staticServerNames.length > 0 || mutable.startupBinding?.configuredMcpOwnershipVersion === 1);
5692
5695
  const cronCreatorAuthorityCapability = params.cronCreatorAuthorityCapability;
5693
- 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;
5694
5697
  const mayResolveScheduledConfiguredMcpCreatorAuthority = !authenticatedScheduledMode && canResolveScheduledConfiguredMcpCreatorAuthority({
5695
5698
  trigger: params.trigger,
5696
5699
  connectionClass: appServer.connectionClass,
@@ -5868,7 +5871,7 @@ const DYNAMIC_TOOL_TERMINAL_DIAGNOSTIC_TYPES = [
5868
5871
  "tool.execution.error",
5869
5872
  "tool.execution.blocked"
5870
5873
  ];
5871
- function createCodexAttemptServerRequestController(resources, turnRuntime, lifecycle) {
5874
+ function createCodexAttemptServerRequestController(resources, turnRuntime, lifecycle, waitForNativeItems) {
5872
5875
  const { prompt, state: resourceState, projectorRef, trajectoryRecorder } = resources;
5873
5876
  const { context } = prompt;
5874
5877
  const { runtime, attemptTools } = context;
@@ -5878,7 +5881,24 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
5878
5881
  const { compactionPlanState, toolBridge, toolOutcomeOrdinals, suppressedDynamicToolOutcomeOrdinals, allocateCodexToolOutcomeOrdinal } = attemptTools;
5879
5882
  const { state, turnIdRef, userInputBridgeRef, openClawDynamicToolExecutions, pendingOpenClawDynamicToolCompletionIds, noteProgress } = turnRuntime;
5880
5883
  const { emitExecutionPhaseOnce, scheduleTurnReleaseAfterTerminalDynamicTool, scheduleTerminalDynamicToolReleaseCheck } = lifecycle;
5881
- 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) => {
5882
5902
  const signal = AbortSignal.any([runAbortController.signal, requestSignal]);
5883
5903
  const turnId = turnIdRef.current;
5884
5904
  const projector = projectorRef.current;
@@ -5939,7 +5959,9 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
5939
5959
  const replayedExecution = openClawDynamicToolExecutions.get(call);
5940
5960
  if (replayedExecution) {
5941
5961
  markCurrentTurnRequestProgress();
5942
- return toCodexDynamicToolProtocolResponse(await replayedExecution);
5962
+ const response = await replayedExecution;
5963
+ await settlePluginRuntimeRefresh(turnId);
5964
+ return toCodexDynamicToolProtocolResponse(response);
5943
5965
  }
5944
5966
  const toolCallOrdinal = allocateCodexToolOutcomeOrdinal?.(call.callId);
5945
5967
  markCurrentTurnRequestProgress();
@@ -5979,8 +6001,10 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
5979
6001
  });
5980
6002
  const dynamicToolTimeoutMs = resolveDynamicToolCallTimeoutMs({
5981
6003
  call,
5982
- config: params.config
6004
+ config: params.config,
6005
+ toolBridge
5983
6006
  });
6007
+ setExecutionTimeoutMs?.(dynamicToolTimeoutMs);
5984
6008
  const toolStartedAt = Date.now();
5985
6009
  let terminalDiagnosticObserved = false;
5986
6010
  const unsubscribeToolDiagnosticObserver = onInternalDiagnosticEvent((event) => {
@@ -6086,7 +6110,8 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6086
6110
  durationMs: toolDurationMs
6087
6111
  });
6088
6112
  pendingOpenClawDynamicToolCompletionIds.delete(call.callId);
6089
- if (response.terminate === true && response.success) scheduleTurnReleaseAfterTerminalDynamicTool({
6113
+ if (params.pluginRuntimeRefreshPending?.()) await settlePluginRuntimeRefresh(turnId);
6114
+ else if (response.terminate === true && response.success) scheduleTurnReleaseAfterTerminalDynamicTool({
6090
6115
  call,
6091
6116
  response,
6092
6117
  durationMs: toolDurationMs
@@ -6112,6 +6137,7 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6112
6137
  sessionKey: params.sessionKey,
6113
6138
  durationMs: Math.max(0, Date.now() - toolStartedAt)
6114
6139
  });
6140
+ await settlePluginRuntimeRefresh(turnId);
6115
6141
  throw error;
6116
6142
  } finally {
6117
6143
  toolOutcomeOrdinals.delete(call.callId);
@@ -6131,7 +6157,7 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6131
6157
  //#region extensions/codex/src/app-server/attempt-runtime-artifact.ts
6132
6158
  async function verifyStartupArtifact(params) {
6133
6159
  if (!params.request) return;
6134
- const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-BJ0rXBZ_.js");
6160
+ const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-Dy38Z5iU.mjs");
6135
6161
  const runtimeArtifact = readCodexAppServerClientRuntimeArtifact(params.client);
6136
6162
  const expected = params.request.expected;
6137
6163
  const matchesExpected = !expected || runtimeArtifact?.id === expected.id && runtimeArtifact.fingerprint === expected.fingerprint;
@@ -6154,7 +6180,7 @@ function startCodexComputerUseHealthMonitor(params) {
6154
6180
  reason: params.config.enabled ? "health_disabled" : "disabled"
6155
6181
  };
6156
6182
  }
6157
- const fingerprint = buildComputerUseHealthMonitorFingerprint(params.config);
6183
+ const fingerprint = buildComputerUseHealthMonitorFingerprint(params.config, params.tools);
6158
6184
  const intervalMs = params.config.healthCheckIntervalMinutes * 6e4;
6159
6185
  if (existing?.fingerprint === fingerprint) return {
6160
6186
  started: false,
@@ -6166,7 +6192,7 @@ function startCodexComputerUseHealthMonitor(params) {
6166
6192
  fingerprint,
6167
6193
  intervalMs,
6168
6194
  timer: setInterval(() => {
6169
- runCodexComputerUseHealthProbe(params.client, params.config, monitor);
6195
+ runCodexComputerUseHealthProbe(params.client, params.config, monitor, params.tools);
6170
6196
  }, intervalMs),
6171
6197
  disposeCloseHandler: () => void 0,
6172
6198
  running: false
@@ -6182,21 +6208,23 @@ function startCodexComputerUseHealthMonitor(params) {
6182
6208
  intervalMs
6183
6209
  };
6184
6210
  }
6185
- function buildComputerUseHealthMonitorFingerprint(config) {
6211
+ function buildComputerUseHealthMonitorFingerprint(config, tools) {
6186
6212
  return JSON.stringify({
6187
6213
  autoRepair: config.autoRepair,
6188
6214
  healthCheckIntervalMinutes: config.healthCheckIntervalMinutes,
6189
6215
  liveTestTimeoutMs: config.liveTestTimeoutMs,
6190
6216
  mcpServerName: config.mcpServerName,
6191
- toolCallTimeoutMs: config.toolCallTimeoutMs
6217
+ toolCallTimeoutMs: config.toolCallTimeoutMs,
6218
+ tools: tools?.toSorted()
6192
6219
  });
6193
6220
  }
6194
- async function runCodexComputerUseHealthProbe(client, config, monitor) {
6221
+ async function runCodexComputerUseHealthProbe(client, config, monitor, tools) {
6195
6222
  if (monitor.running) return;
6196
6223
  monitor.running = true;
6197
6224
  try {
6198
6225
  const { liveTest, repair } = await runCodexComputerUseLiveTest({
6199
6226
  config,
6227
+ tools,
6200
6228
  request: async (method, requestParams, requestOptions) => await client.request(method, requestParams, { timeoutMs: requestOptions?.timeoutMs ?? config.liveTestTimeoutMs })
6201
6229
  });
6202
6230
  if (!liveTest.ok) {
@@ -6399,6 +6427,7 @@ async function startCodexAttemptThread(params) {
6399
6427
  try {
6400
6428
  const attemptParams = params.buildAttemptParams();
6401
6429
  params.assertCurrent?.();
6430
+ if (startupAbandonController.signal.aborted) throw new CodexAppServerStartupError("aborted");
6402
6431
  startupClient = await params.attemptClientFactory({
6403
6432
  assertCurrent: params.assertCurrent,
6404
6433
  startOptions: params.appServer.start,
@@ -6447,15 +6476,16 @@ async function startCodexAttemptThread(params) {
6447
6476
  config: params.config
6448
6477
  });
6449
6478
  const turnRouter = getCodexAppServerTurnRouter(activeStartupClient);
6479
+ let computerUseTools = [];
6450
6480
  try {
6451
- await ensureCodexComputerUse({
6481
+ computerUseTools = (await ensureCodexComputerUse({
6452
6482
  client: activeStartupClient,
6453
6483
  pluginConfig: params.pluginConfig,
6454
6484
  config: params.config,
6455
6485
  agentDir: params.agentDir,
6456
6486
  timeoutMs: params.appServer.requestTimeoutMs,
6457
6487
  signal: startupAbandonController.signal
6458
- });
6488
+ })).tools;
6459
6489
  } catch (error) {
6460
6490
  if (startupAbandonController.signal.aborted || isCodexAppServerStartSelectionChangedError(error)) throw error;
6461
6491
  throw new AgentHarnessPreflightError(`Codex Computer Use readiness failed: ${formatErrorMessage(error)}`, {
@@ -6617,7 +6647,8 @@ async function startCodexAttemptThread(params) {
6617
6647
  startupSandboxEnvironmentAcquired = false;
6618
6648
  startCodexComputerUseHealthMonitor({
6619
6649
  client: activeStartupClient,
6620
- config: params.computerUseConfig
6650
+ config: params.computerUseConfig,
6651
+ tools: computerUseTools
6621
6652
  });
6622
6653
  startupAttemptSucceeded = true;
6623
6654
  return {
@@ -6652,7 +6683,6 @@ async function startCodexAttemptThread(params) {
6652
6683
  const sharedClient = clearSharedCodexAppServerClientIfCurrentAndUnclaimed(startupClientForAbandonedRequestCleanup);
6653
6684
  if (sharedClient.found && !sharedClient.closed) startupClientForAbandonedRequestCleanup = void 0;
6654
6685
  }
6655
- throw error;
6656
6686
  } finally {
6657
6687
  if (!startupAttemptSucceeded) {
6658
6688
  if (releaseSharedClientLease === startupClientLease) releaseSharedClientLease = void 0;
@@ -6663,13 +6693,20 @@ async function startCodexAttemptThread(params) {
6663
6693
  }
6664
6694
  }
6665
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;
6666
6700
  };
6701
+ let replacedSettledFailureClient = false;
6667
6702
  for (let attempt = 1; attempt <= CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS; attempt += 1) try {
6668
6703
  return await startupAttempt();
6669
6704
  } catch (error) {
6670
6705
  const selectionChanged = isCodexAppServerStartSelectionChangedError(error);
6671
- if (startupAbandonController.signal.aborted || !selectionChanged && !isCodexAppServerConnectionClosedError(error)) throw error;
6672
- 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);
6673
6710
  if (startupClientForAbandonedRequestCleanup === attemptedClient) startupClientForAbandonedRequestCleanup = void 0;
6674
6711
  if (attempt >= CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS) {
6675
6712
  embeddedAgentLog.warn(selectionChanged ? "codex app-server executable selection kept changing during startup; retries exhausted" : "codex app-server connection closed during startup; retries exhausted", {
@@ -6680,8 +6717,8 @@ async function startCodexAttemptThread(params) {
6680
6717
  });
6681
6718
  throw error;
6682
6719
  }
6683
- const retryDelayMs = selectionChanged ? 0 : 1e3 * 2 ** (attempt - 1);
6684
- 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", {
6685
6722
  attempt,
6686
6723
  nextAttempt: attempt + 1,
6687
6724
  maxAttempts: CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS,
@@ -6712,10 +6749,6 @@ async function startCodexAttemptThread(params) {
6712
6749
  params.signal.removeEventListener("abort", abandonStartupAcquire);
6713
6750
  }
6714
6751
  }
6715
- function shouldRetireCodexStartupClient(error, spawnedBy, signal) {
6716
- if (signal.aborted || isCodexAppServerStartupError(error) || isCodexAppServerRequestTimeoutError(error)) return true;
6717
- return !isCodexAppServerStartSelectionChangedError(error) && !isCodexAppServerOverloadError(error) && !(error instanceof AgentHarnessPreflightError && error.scope === void 0) && (isCodexAppServerBrokenPipeError(error) || !spawnedBy);
6718
- }
6719
6752
  //#endregion
6720
6753
  //#region extensions/codex/src/app-server/run-attempt-start.ts
6721
6754
  async function startCodexAttemptRuntime(resources) {
@@ -6803,10 +6836,11 @@ async function startCodexAttemptRuntime(resources) {
6803
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");
6804
6837
  if (state.thread.lifecycle.action === "started" || state.thread.lifecycle.action === "forked") {
6805
6838
  const activePolicy = resolveReviewerPolicyContext(state.thread);
6806
- const activeConfig = resolveRuntimeOptionsForCurrentBinding({
6839
+ const activeConfig = await resolveRuntimeOptionsForCurrentBinding({
6807
6840
  modelProvider: activePolicy.modelProvider,
6808
6841
  model: activePolicy.model
6809
6842
  });
6843
+ connection.assertCurrent();
6810
6844
  const activeAppServer = resolveCodexAppServerForModelProvider({
6811
6845
  appServer: activeConfig,
6812
6846
  provider: activePolicy.modelProvider,
@@ -6847,12 +6881,16 @@ async function startCodexAttemptRuntime(resources) {
6847
6881
  toolCount: flattenCodexDynamicToolFunctions(toolBridge.specs).length
6848
6882
  });
6849
6883
  connection.mutable.pluginAppServer = pluginAppServer;
6884
+ await resources.registerNativeSubagentMonitor(state.thread.threadId);
6850
6885
  } catch (error) {
6851
6886
  await runCleanupStep("codex-start-failure-hook-fallback", activateNativePreToolUseFailureFallback);
6852
6887
  await runCleanupStep("codex-start-failure-route-release", releaseCurrentRoute);
6853
6888
  const nativeHookRelay = state.nativeHookRelay;
6854
6889
  state.nativeHookRelay = void 0;
6855
- 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
+ });
6856
6894
  await runCleanupStep("codex-start-failure-sandbox-release", releaseSandboxExecEnvironment);
6857
6895
  await runCleanupStep("codex-start-failure-shared-client-release", releaseSharedClientLeaseAndRetireOneShotClient);
6858
6896
  throw error instanceof CodexThreadPolicyHandoffError ? error : state.executionDisconnectError ?? error;
@@ -7078,6 +7116,45 @@ async function prepareCodexAttemptTools(runtime) {
7078
7116
  ...params.memberRoleIds?.length ? { roleIds: [...params.memberRoleIds] } : {}
7079
7117
  };
7080
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
+ };
7081
7158
  const configuredMcp = configuredMcpSurface ? await materializeStaticMcpToolsForHarnessRun({
7082
7159
  sessionId: params.sessionId,
7083
7160
  sessionKey: params.sessionKey,
@@ -7091,28 +7168,7 @@ async function prepareCodexAttemptTools(runtime) {
7091
7168
  toolOverrides: codexMcpToolOverrides,
7092
7169
  autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
7093
7170
  projectedMcpServers: bundleMcpThreadConfig.configPatch?.mcp_servers,
7094
- ...configuredMcpSurface === "transient" ? { requestInteractiveCodexApproval: async (approval) => {
7095
- const allowedDecisions = approval.mode === "prompt" ? ["allow-once", "deny"] : [
7096
- "allow-once",
7097
- "allow-always",
7098
- "deny"
7099
- ];
7100
- const outcome = await requestPluginApprovalOutcome({
7101
- hostCapabilities: params.hostCapabilities,
7102
- signal: approval.signal,
7103
- title: `Run MCP tool ${approval.serverName}/${approval.toolName}`,
7104
- description: `Codex approval mode "${approval.mode}" requires an operator decision before this MCP tool runs. ${formatMcpCodexApprovalRemedy(approval.serverName)}`,
7105
- allowedDecisions,
7106
- toolName: approval.safeToolName,
7107
- toolCallId: approval.toolCallId,
7108
- mcpTool: {
7109
- server: approval.serverName,
7110
- tool: approval.toolName
7111
- },
7112
- isMcpToolApprovalActive: approval.isActive
7113
- });
7114
- if (outcome !== "approved-once" && outcome !== "approved-session") throw new Error(`${approval.serverName}/${approval.toolName}: interactive Codex approval (${approval.mode}) was not granted: ${outcome}`);
7115
- } } : {},
7171
+ ...configuredMcpSurface === "transient" ? { requestInteractiveCodexApproval: requestInteractiveMcpApproval } : {},
7116
7172
  policyContext,
7117
7173
  warn: (message) => embeddedAgentLog.warn(message)
7118
7174
  }) : void 0;
@@ -7135,6 +7191,8 @@ async function prepareCodexAttemptTools(runtime) {
7135
7191
  cfg: params.config,
7136
7192
  manifestRegistry: bundleManifestRegistry,
7137
7193
  toolOverrides: codexMcpToolOverrides,
7194
+ autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
7195
+ requestInteractiveCodexApproval: requestRequesterMcpApproval,
7138
7196
  requesterSenderId: params.senderId,
7139
7197
  agentAccountId: params.agentAccountId,
7140
7198
  messageChannel: params.messageChannel ?? params.messageProvider,
@@ -7305,7 +7363,7 @@ async function resolveCodexExplicitSkillInputs(params) {
7305
7363
  //#region extensions/codex/src/app-server/run-attempt-turn-request.ts
7306
7364
  async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurrentThreadRoute, waitForActiveNativeTurnCompletion) {
7307
7365
  const { prompt, state: resourceState, releaseCurrentRoute } = resources;
7308
- const { context, turnState, buildRenderedCodexDeveloperInstructions } = prompt;
7366
+ const { context, turnState, buildRenderedCodexDeveloperInstructions, nativeHistoryProvenancePrefix } = prompt;
7309
7367
  const { runtime, attemptTools, hookContextWindowFields, workspaceBootstrapContext } = context;
7310
7368
  const { connection, runtimeParams, effectiveRuntimeProviderId, effectiveRuntimeModelId } = runtime;
7311
7369
  const { tools, toolBridge } = attemptTools;
@@ -7364,14 +7422,13 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7364
7422
  const references = prepareWorkspaceReferences();
7365
7423
  const referencesRetained = turnState.codexTurnPromptText.includes(workspaceBootstrapContext.promptContext ?? "");
7366
7424
  const inferenceRoute = usesSupervisionConnection ? void 0 : getCodexInferenceThread(resourceState.client, resourceState.thread.threadId);
7367
- const turnStartParams = buildTurnStartParams({
7368
- ...runtimeParams,
7369
- images: [...prompt.contextImages, ...runtimeParams.images ?? []]
7370
- }, {
7425
+ const turnStartParams = buildTurnStartParams(runtimeParams, {
7371
7426
  threadId: resourceState.thread.threadId,
7372
7427
  cwd: resourceState.codexExecutionCwd,
7373
7428
  appServer: turnAppServer,
7374
7429
  promptText: turnState.codexTurnPromptText,
7430
+ historyProvenancePrefix: nativeHistoryProvenancePrefix,
7431
+ contextImageGroups: prompt.contextImageGroups,
7375
7432
  explicitSkillInputs,
7376
7433
  sandboxPolicy: resourceState.codexSandboxPolicy,
7377
7434
  environmentSelection: resourceState.codexEnvironmentSelection,
@@ -7469,7 +7526,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7469
7526
  });
7470
7527
  if (resourceState.startupClientUnsafe) await retireUnsafeCodexTurnClientBestEffort(resourceState.client, "startup interrupt");
7471
7528
  } finally {
7472
- releaseCurrentRoute();
7529
+ await releaseCurrentRoute();
7473
7530
  }
7474
7531
  else await activeTurnRoute.cancelTurn();
7475
7532
  throw error;
@@ -7496,7 +7553,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7496
7553
  systemPrompt: buildRenderedCodexDeveloperInstructions(),
7497
7554
  prompt: turnState.codexTurnPromptText,
7498
7555
  historyMessages: prompt.codexModelInputHistoryMessages,
7499
- imagesCount: prompt.contextImages.length + (params.images?.length ?? 0),
7556
+ imagesCount: prompt.contextImageGroups.reduce((count, group) => count + group.images.length, 0) + (params.images?.length ?? 0),
7500
7557
  tools
7501
7558
  });
7502
7559
  return {
@@ -7676,9 +7733,19 @@ async function startCodexAttemptTurn(resources, turnRuntime, notifications, requ
7676
7733
  cleanup: async () => closeCodexStartupClientBestEffort(resourceState.client)
7677
7734
  });
7678
7735
  }
7679
- releaseCurrentRoute();
7736
+ await releaseCurrentRoute();
7680
7737
  activateNativePreToolUseFailureFallback();
7681
- 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
+ });
7682
7749
  await releaseSandboxExecEnvironment();
7683
7750
  await runAgentCleanupStep({
7684
7751
  runId: params.runId,
@@ -7791,36 +7858,30 @@ function createCodexAttemptDeadlineController(params) {
7791
7858
  //#endregion
7792
7859
  //#region extensions/codex/src/app-server/run-attempt-turn-state.ts
7793
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
+ };
7794
7880
  function createCodexAttemptTurnState(resources) {
7795
7881
  const { prompt, state: resourceState, projectorRef, trajectoryRecorder, startupTimeoutMs } = resources;
7796
7882
  const { connection } = prompt.context.runtime;
7797
7883
  const { params, options, runAbortController } = connection;
7798
- const state = {
7799
- latestStartupErrorNotification: void 0,
7800
- rateLimitsRevisionBeforeLastTurnStart: void 0,
7801
- completed: false,
7802
- abortCleanup: Promise.resolve(),
7803
- permissionChangeRestart: void 0,
7804
- localCompletionRequested: false,
7805
- terminalTurnNotificationQueued: false,
7806
- sawCodexInterruptMarker: false,
7807
- timeout: void 0,
7808
- settlementWarning: void 0,
7809
- pendingSettlementStage: void 0,
7810
- clientClosedPromptError: void 0,
7811
- clientClosedDiagnostic: void 0,
7812
- clientClosedAbort: false,
7813
- shouldDelayNativeHookRelayUnregister: false,
7814
- lifecycleStarted: false,
7815
- lifecycleTerminalEmitted: false,
7816
- nativeHookRelayLastRenewedAt: 0,
7817
- activeAppServerTurnRequests: 0,
7818
- activeLocalProjections: 0,
7819
- projectionClosed: false,
7820
- pendingTerminalDynamicToolRelease: void 0,
7821
- terminalDynamicToolReleaseCheckScheduled: false,
7822
- currentTurnHadNonTerminalDynamicToolResult: false
7823
- };
7884
+ const state = new CodexAttemptState();
7824
7885
  const { promise: completion, resolve: resolveCompletion } = createDeferred();
7825
7886
  const settlementExpired = createDeferred();
7826
7887
  const pendingOpenClawDynamicToolCompletionIds = /* @__PURE__ */ new Set();
@@ -7846,19 +7907,28 @@ function createCodexAttemptTurnState(resources) {
7846
7907
  if (!completed) await closeCodexStartupClientBestEffort(resourceState.client);
7847
7908
  return completed;
7848
7909
  };
7910
+ let pendingNativeHookRenewal;
7849
7911
  const renewNativeHookRelayForTurnProgress = () => {
7850
- if (!resourceState.nativeHookRelay || options.nativeHookRelay?.ttlMs !== void 0) return;
7912
+ if (!resourceState.nativeHookRelay || options.nativeHookRelay?.ttlMs !== void 0 || pendingNativeHookRenewal) return;
7851
7913
  const now = Date.now();
7852
7914
  const renewsRecently = now - state.nativeHookRelayLastRenewedAt < CODEX_NATIVE_HOOK_RELAY_RENEW_INTERVAL_MS;
7853
7915
  const expiresSoon = now >= resourceState.nativeHookRelay.expiresAtMs - CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS;
7854
7916
  if (renewsRecently && !expiresSoon) return;
7855
- state.nativeHookRelayLastRenewedAt = now;
7856
- resourceState.nativeHookRelay.renew(resolveCodexNativeHookRelayTtlMs({
7917
+ const relay = resourceState.nativeHookRelay;
7918
+ relay.renew(resolveCodexNativeHookRelayTtlMs({
7857
7919
  explicitTtlMs: void 0,
7858
7920
  attemptTimeoutMs: params.timeoutMs,
7859
7921
  startupTimeoutMs,
7860
7922
  turnStartTimeoutMs: params.timeoutMs
7861
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
+ });
7862
7932
  };
7863
7933
  const noteProgress = (reason) => {
7864
7934
  if (state.completed || state.projectionClosed || runAbortController.signal.aborted) return;
@@ -7953,7 +8023,7 @@ async function runCodexAppServerAttempt(params, options) {
7953
8023
  try {
7954
8024
  const lifecycle = createCodexAttemptLifecycleController(resources, turnRuntime);
7955
8025
  const notifications = createCodexAttemptNotificationController(resources, turnRuntime, lifecycle);
7956
- const serverRequests = createCodexAttemptServerRequestController(resources, turnRuntime, lifecycle);
8026
+ const serverRequests = createCodexAttemptServerRequestController(resources, turnRuntime, lifecycle, notifications.waitForNativeTerminalItems);
7957
8027
  const { ensureCurrentThreadRoute } = await preparation.measure("thread-route", () => prepareCodexAttemptRoute(resources, turnRuntime, notifications, serverRequests.handleServerRequest));
7958
8028
  const turnRequest = await preparation.measure("turn-request", () => prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurrentThreadRoute, notifications.waitForActiveNativeTurnCompletion));
7959
8029
  preparation.ready();
@@ -7962,10 +8032,22 @@ async function runCodexAppServerAttempt(params, options) {
7962
8032
  const activeTurn = activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notifications, turnStart.turn);
7963
8033
  let finalizedResult;
7964
8034
  try {
7965
- await activeTurn.ready;
7966
- finalizedResult = await finalizeCodexAttempt(resources, turnRuntime, lifecycle, notifications, turnRequest, activeTurn);
7967
- } finally {
7968
- 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;
7969
8051
  }
7970
8052
  if (resources.state.executionDisconnectError && !connection.terminalState.explicitCancellationObserved) throw resources.state.executionDisconnectError;
7971
8053
  return finalizedResult;