@openclaw/codex 2026.9.6 → 2026.9.8

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 (158) hide show
  1. package/README.md +2 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/.setup/{account-usage-runtime-Eem_WGqY.mjs → account-usage-runtime-G348lY1q.mjs} +5 -5
  4. package/dist/.setup/{apply-DDOi8uNx.mjs → apply-Cqb-YoCS.mjs} +22 -36
  5. package/dist/.setup/{attempt-client-cleanup-CEv1cKwF.mjs → attempt-client-cleanup-B-S7ngS_.mjs} +128 -37
  6. package/dist/.setup/attempt-workspace-context-BJ5Z_olH.mjs +164 -0
  7. package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
  8. package/dist/.setup/{auth-cache-key-B2mpaI9D.mjs → auth-cache-key-Dnps4W4_.mjs} +36 -34
  9. package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
  10. package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
  11. package/dist/.setup/{binding-connection-ThoatDcb.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
  12. package/dist/.setup/{binding-connection.runtime-yoHrABt-.mjs → binding-connection.runtime-6TpgD1M6.mjs} +4 -4
  13. package/dist/.setup/{bounded-turn-B2HScEgT.mjs → bounded-turn-BNunZPtz.mjs} +15 -18
  14. package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
  15. package/dist/.setup/{build-state-C7EnDVgr.mjs → build-state-DIQ5O_-S.mjs} +1 -1
  16. package/dist/.setup/{capabilities-CDXOOFdZ.mjs → capabilities-B3WEZl4e.mjs} +2 -10
  17. package/dist/.setup/{client-catalog-response-BMgt_4q4.mjs → client-catalog-response-DRvx_wCC.mjs} +1 -1
  18. package/dist/.setup/{client-Cs08OXVQ.mjs → client-qyUBJlGZ.mjs} +138 -399
  19. package/dist/.setup/{command-dispatch-B4JuOsOk.mjs → command-dispatch-Btrs1D6f.mjs} +5 -8
  20. package/dist/.setup/{command-formatters-Bmqvr9tO.mjs → command-formatters-R3ckE3Co.mjs} +29 -61
  21. package/dist/.setup/{command-handlers-DW7Lx9oH.mjs → command-handlers-DvlCHJch.mjs} +222 -343
  22. package/dist/.setup/{command-rpc-DixIj3HW.mjs → command-rpc-skzRq4wD.mjs} +15 -18
  23. package/dist/.setup/compact-8ttks5U5.mjs +776 -0
  24. package/dist/.setup/{config-BoTP_mrL.mjs → config-DKhXquav.mjs} +26 -28
  25. package/dist/.setup/{config-options-BvaRs51b.mjs → config-options-CzyWLTJt.mjs} +24 -37
  26. package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
  27. package/dist/.setup/{config-runtime-C8Rw1m1m.mjs → config-runtime-C0NbLms1.mjs} +2 -2
  28. package/dist/.setup/{config-security-BEReZ6go.mjs → config-security-CE-FcGw9.mjs} +32 -111
  29. package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
  30. package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
  31. package/dist/.setup/{conversation-binding-DP-gMrBP.mjs → conversation-binding-74LaGGH-.mjs} +67 -90
  32. package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
  33. package/dist/.setup/{conversation-control-uK9Jomlc.mjs → conversation-control-OrN6zuaY.mjs} +8 -8
  34. package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
  35. package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
  36. package/dist/.setup/{dynamic-tools-BDXl-8Cw.mjs → dynamic-tools-Db2sY5cZ.mjs} +2305 -2606
  37. package/dist/.setup/{effective-mcp-catalog-CvnvnGIe.mjs → effective-mcp-catalog-Bi6-SQ7i.mjs} +8 -17
  38. package/dist/.setup/{ephemeral-turn-poidXgek.mjs → ephemeral-turn-DiCS1ijR.mjs} +3 -3
  39. package/dist/.setup/event-projector-assistant-message-MV_1dj-3.mjs +69 -0
  40. package/dist/.setup/{event-projector-usage-CnBS8Wa3.mjs → event-projector-usage-03R0I2dM.mjs} +3 -25
  41. package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
  42. package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
  43. package/dist/.setup/{inference-context-D96l9-ew.mjs → inference-context-D-9gWlTR.mjs} +16 -18
  44. package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
  45. package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
  46. package/dist/.setup/{inference-proxy-b-aJMSxm.mjs → inference-proxy-DhcXOgUE.mjs} +174 -214
  47. package/dist/.setup/{isolated-completion-BIZFhTNG.mjs → isolated-completion-D80IXfQF.mjs} +9 -12
  48. package/dist/.setup/{managed-binary-BnshlFag.mjs → managed-binary-kiWRhNRE.mjs} +8 -12
  49. package/dist/.setup/{model-catalog-CfXJf9Ay.mjs → model-catalog-DiC0Tkha.mjs} +11 -10
  50. package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
  51. package/dist/.setup/{models-KnqBv0hE.mjs → models-DfLmPV0k.mjs} +9 -18
  52. package/dist/.setup/{native-auth-rWbGbMn3.mjs → native-auth-CuG53tu4.mjs} +4 -4
  53. package/dist/.setup/{native-execution-policy-umd0tgh4.mjs → native-execution-policy-BxZJy5mP.mjs} +5 -30
  54. package/dist/.setup/{native-subagent-monitor-D3filLY2.mjs → native-subagent-monitor-BwkQXf9e.mjs} +4395 -3609
  55. package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
  56. package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
  57. package/dist/.setup/{node-cli-sessions-r3avj02l.mjs → node-cli-sessions-HC4W6FLI.mjs} +19 -49
  58. package/dist/.setup/{node-exec-server.runtime-BDwWXVpK.mjs → node-exec-server.runtime-BgBfWQqo.mjs} +3 -6
  59. package/dist/.setup/{plan-CN3VwfNU.mjs → plan-DPdMk1Oy.mjs} +49 -92
  60. package/dist/.setup/{plugin-activation-DT3MNtqj.mjs → plugin-activation-cNHRfaxU.mjs} +8 -36
  61. package/dist/.setup/{plugin-app-cache-key-B2CsSdnV.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +6 -23
  62. package/dist/.setup/{plugin-inventory-BoRei8Z4.mjs → plugin-inventory-Cky2XJUw.mjs} +21 -21
  63. package/dist/.setup/{plugin-marketplace-discovery-CDOi8IFs.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +18 -24
  64. package/dist/.setup/{plugin-metadata-cache-Ctmo83k_.mjs → plugin-metadata-cache-BRwtRct9.mjs} +116 -176
  65. package/dist/.setup/{provider-BOsxQHOM.mjs → provider-D6F_7p1I.mjs} +11 -14
  66. package/dist/.setup/{provider-capabilities-BfE88FZ5.mjs → provider-capabilities-DG5qbsUZ.mjs} +13 -18
  67. package/dist/.setup/{rate-limits-CMU3DUD0.mjs → rate-limits-B7-X2TgG.mjs} +9 -31
  68. package/dist/.setup/{request-D2L0zMrq.mjs → request-BZOfsSXW.mjs} +7 -6
  69. package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
  70. package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
  71. package/dist/.setup/{run-attempt-BHu11r7h.mjs → run-attempt-dYJhjZrp.mjs} +1035 -1023
  72. package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
  73. package/dist/.setup/{runtime-artifact-CLZ8udh-.mjs → runtime-artifact-DDQ-HGXf.mjs} +16 -4
  74. package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
  75. package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
  76. package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
  77. package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
  78. package/dist/.setup/{session-binding-record-BGoz8wOK.mjs → session-binding-record-Oe9L-CNY.mjs} +52 -130
  79. package/dist/.setup/{session-binding-sidecars-BlB5EvIS.mjs → session-binding-sidecars-jo6H8dFr.mjs} +196 -17
  80. package/dist/.setup/{session-catalog-Pno1xGcl.mjs → session-catalog-BFafIiF6.mjs} +185 -350
  81. package/dist/.setup/{session-catalog-adoption-BI6UTDZT.mjs → session-catalog-adoption-BU_pHWG7.mjs} +7 -6
  82. package/dist/.setup/{session-catalog-archive-lHBqzhaO.mjs → session-catalog-archive-spHfihri.mjs} +6 -6
  83. package/dist/.setup/session-catalog-events-BMCFMZw-.mjs +139 -0
  84. package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
  85. package/dist/.setup/{session-catalog-index-B9_VQIUz.mjs → session-catalog-index-DwJjnF5k.mjs} +126 -122
  86. package/dist/.setup/{session-catalog-index-order-hcdz07yN.mjs → session-catalog-index-order-BcQpHks3.mjs} +1 -1
  87. package/dist/.setup/{session-catalog-index-state-Dgh8ORJm.mjs → session-catalog-index-state-TeO7EyO-.mjs} +3 -2
  88. package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
  89. package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
  90. package/dist/.setup/session-catalog-native-projection-CuaFZuQE.mjs +178 -0
  91. package/dist/.setup/{session-catalog-node-adoption-ITddWx_X.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +10 -27
  92. package/dist/.setup/{session-catalog-node-continue-6g6qi4A9.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +8 -10
  93. package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
  94. package/dist/.setup/{session-catalog-native-projection-DowriLid.mjs → session-catalog-parsing-CPGaPYr-.mjs} +11 -194
  95. package/dist/.setup/{session-catalog-projection-zK_PUsiE.mjs → session-catalog-projection-CGfzfP93.mjs} +6 -4
  96. package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
  97. package/dist/.setup/{session-cli-irrD-uo7.mjs → session-cli-DlmBHYIe.mjs} +9 -22
  98. package/dist/.setup/{session-history-BrqhSCf9.mjs → session-history-D83lJWHG.mjs} +4 -6
  99. package/dist/.setup/{session-history-import-D-3wAgOP.mjs → session-history-import-WhX-X33a.mjs} +7 -10
  100. package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
  101. package/dist/.setup/{session-history.worker-CaCh0xF_.mjs → session-history.worker-MnPKncqP.mjs} +9 -5
  102. package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
  103. package/dist/.setup/{session-permission-policy-BI1QK_98.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
  104. package/dist/.setup/{session-retirement-BH-S6qkJ.mjs → session-retirement-LlYWBKTJ.mjs} +17 -17
  105. package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
  106. package/dist/.setup/{settled-turn-finalizer-DiAi6Kx6.mjs → settled-turn-finalizer-DW9W3gza.mjs} +14 -10
  107. package/dist/.setup/{shared-client-DA4VR4Eb.mjs → shared-client-CJCTeFpQ.mjs} +783 -412
  108. package/dist/.setup/shared-client-lifecycle-7xgtlo15.mjs +153 -0
  109. package/dist/.setup/{side-question-BJ1wSDcB.mjs → side-question-BLeGj7TQ.mjs} +79 -143
  110. package/dist/.setup/{source-CUzJq5WN.mjs → source-CJis_1EF.mjs} +80 -137
  111. package/dist/.setup/{thread-lifecycle-B3mfz1TG.mjs → thread-lifecycle-_bAbjedG.mjs} +294 -737
  112. package/dist/.setup/{thread-ownership-DcTtAcXj.mjs → thread-ownership-B6pPt21M.mjs} +45 -10
  113. package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
  114. package/dist/.setup/{thread-policy-DGuQsuFC.mjs → thread-policy-gNPzzpVp.mjs} +46 -7
  115. package/dist/.setup/{thread-requests-BLvGkP2R.mjs → thread-requests-OWGOiDaV.mjs} +199 -302
  116. package/dist/.setup/{thread-resume-DIBXwOpE.mjs → thread-resume-GOry0AYh.mjs} +6 -6
  117. package/dist/.setup/{timeout-C910MdAB.mjs → timeout-CXOfNoaX.mjs} +1 -35
  118. package/dist/.setup/{transcript-history-projection-ZZpkFkJ_.mjs → transcript-history-projection-DRSifI-1.mjs} +17 -89
  119. package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
  120. package/dist/.setup/{transcript-mirror-BtHDBp1G.mjs → transcript-mirror-kxmCYsuF.mjs} +7 -9
  121. package/dist/.setup/{transport-stdio-h2VHOskC.mjs → transport-stdio-Bdegpn2V.mjs} +5 -22
  122. package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
  123. package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
  124. package/dist/.setup/{upstream-session-fork-BUr4OUbC.mjs → upstream-session-fork-gkdRj2yH.mjs} +23 -23
  125. package/dist/.setup/{usage-BML0r-ua.mjs → usage-CApUvLOV.mjs} +4 -4
  126. package/dist/.setup/{usage-limit-error-DUMbefVY.mjs → usage-limit-error-wSMQkbpV.mjs} +4 -19
  127. package/dist/.setup/{web-search-provider.runtime-CDKlN-Rv.mjs → web-search-provider.runtime-UKgeiBUG.mjs} +8 -19
  128. package/dist/api.js +9 -11
  129. package/dist/catalog-page.worker.js +1 -1
  130. package/dist/cli-metadata.js +1 -1
  131. package/dist/doctor-contract-api.js +50 -8
  132. package/dist/harness.js +344 -1
  133. package/dist/index.js +193 -245
  134. package/dist/media-understanding-provider.js +9 -22
  135. package/dist/migration-provider-api.js +1 -1
  136. package/dist/provider-discovery.js +1 -1
  137. package/dist/session-history-worker-runtime.js +3 -3
  138. package/dist/session-history.worker.js +1 -1
  139. package/openclaw.plugin.json +14 -2
  140. package/package.json +7 -6
  141. package/dist/.setup/attempt-workspace-context-DUVEn_CS.mjs +0 -331
  142. package/dist/.setup/compact-Du5UvtxA.mjs +0 -680
  143. package/dist/.setup/event-projector-assistant-message-BsruvNrH.mjs +0 -103
  144. package/dist/.setup/event-projector-items-C6L_5ZiT.mjs +0 -234
  145. package/dist/.setup/harness-a_MsE4-_.mjs +0 -355
  146. package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
  147. package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
  148. package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
  149. package/dist/.setup/native-subagent-history-0nYYgo0k.mjs +0 -148
  150. package/dist/.setup/native-subagent-task-ids-wb8CKZGN.mjs +0 -441
  151. package/dist/.setup/plugin-approval-roundtrip-C0MZzCuP.mjs +0 -122
  152. package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
  153. package/dist/.setup/sandbox-guard-C2sRMOEY.mjs +0 -166
  154. package/dist/.setup/session-binding-Cm0apEbd.mjs +0 -692
  155. package/dist/.setup/session-catalog-events-Bj6j94E_.mjs +0 -347
  156. package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
  157. package/dist/.setup/session-initialization-rcgbZiid.mjs +0 -75
  158. package/dist/.setup/thread-history-page-DoVpnHim.mjs +0 -83
@@ -1,83 +1,95 @@
1
- import { s as resolveRecoverableCodexPluginConfigKeys } from "./plugin-inventory-BoRei8Z4.mjs";
2
- import { i as matchesCodexNativeSubagentSubmissionBinding, m as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced, x as createCodexNativeSubagentHistoryOwner } from "./session-binding-record-BGoz8wOK.mjs";
3
- import { n as defineCodexBuildState } from "./build-state-C7EnDVgr.mjs";
4
- import { d as resolveCodexAppServerHomeDir, l as shouldAutoApproveCodexAppServerApprovals, n as hasCodexMcpToolApprovalOverrides, u as withMcpElicitationsApprovalPolicy, y as readCodexRequirementsToml } from "./config-security-BEReZ6go.mjs";
5
- import { c as isCodexPairedNodeRemoteExecPlacementSandbox, d as readCodexPluginConfig, f as resolveCodexPluginsPolicy, l as isCodexRemoteExecPlacementSandbox, u as isCodexSandboxExecServerEnabled } from "./config-parsing-CcB9iPoq.mjs";
1
+ import { n as readCodexRuntimeModelId } from "./model-runtime-BdqzOMkU.mjs";
2
+ import { c as resolveRecoverableCodexPluginConfigKeys } from "./plugin-inventory-Cky2XJUw.mjs";
3
+ import { g as createCodexNativeSubagentHistoryOwner } from "./native-subagent-pending-assignments-DwkCzLvD.mjs";
6
4
  import { i as isJsonObject, r as flattenCodexDynamicToolFunctions } from "./protocol-CANUwXJ3.mjs";
7
- import { i as resolveCodexAppServerHomeScope, l as resolveCodexModelBackedReviewerPolicyContext, o as resolveCodexComputerUseConfig } from "./config-options-BvaRs51b.mjs";
8
- import { c as resolveCodexAppServerPreparedApiKeyCacheKey, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-B2mpaI9D.mjs";
9
- import { h as retireSharedCodexAppServerClientIfCurrent } from "./session-catalog-events-Bj6j94E_.mjs";
10
- import { t as isIncognitoSessionKey } from "./incognito-session-uhrBF6wJ.mjs";
11
- import { o as formatCodexDisplayText } from "./command-formatters-Bmqvr9tO.mjs";
12
- import { n as waitForPromiseOrAbort, o as CodexAppServerRpcError, r as withAbortableTimeout } from "./timeout-C910MdAB.mjs";
5
+ import { i as matchesCodexNativeSubagentSubmissionBinding, n as assertCodexBindingMayBeReplaced, v as sessionBindingIdentity } from "./session-binding-record-Oe9L-CNY.mjs";
6
+ import { n as defineCodexBuildState } from "./build-state-DIQ5O_-S.mjs";
7
+ import { c as shouldAutoApproveCodexAppServerApprovals, l as withMcpElicitationsApprovalPolicy, m as readCodexRequirementsToml, n as hasCodexMcpToolApprovalOverrides } from "./config-security-CE-FcGw9.mjs";
8
+ import { c as isCodexPairedNodeRemoteExecPlacementSandbox, d as readCodexPluginConfig, f as resolveCodexPluginsPolicy, l as isCodexRemoteExecPlacementSandbox, u as isCodexSandboxExecServerEnabled } from "./config-parsing-b088LyhT.mjs";
9
+ import { n as isCodexAppServerProxyLaunch } from "./launch-args-DbFCehO7.mjs";
10
+ import { t as resolveCodexAppServerHomeDir } from "./auth-start-options-BPIPeEX8.mjs";
11
+ import { i as resolveCodexAppServerHomeScope, l as resolveCodexModelBackedReviewerPolicyContext, o as resolveCodexComputerUseConfig } from "./config-options-CzyWLTJt.mjs";
12
+ import { c as resolveCodexAppServerPreparedApiKeyCacheKey, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-Dnps4W4_.mjs";
13
+ import { d as retireSharedCodexAppServerClientIfCurrent } from "./shared-client-lifecycle-7xgtlo15.mjs";
14
+ import { o as formatCodexDisplayText } from "./command-formatters-R3ckE3Co.mjs";
15
+ import { t as isIncognitoSessionKey } from "./incognito-session-DWYapfwf.mjs";
16
+ import { n as CodexAppServerRpcError } from "./rpc-error-BlD2vuzn.mjs";
17
+ import { n as waitForPromiseOrAbort, r as withAbortableTimeout } from "./timeout-CXOfNoaX.mjs";
13
18
  import { t as readCodexAsyncQuestions } from "./async-questions-DdhOCwGi.mjs";
14
- import { C as readItemString, D as readNullableString, E as readNonNegativeInteger, O as splitPlanText, S as readItem, _ as extractRawAssistantText, b as readCodexProviderRefusal, d as matchesCodexSnapshotTurn, f as shouldClearTerminalPresentationForNativeItem, y as readCodexErrorNotificationMessage } from "./event-projector-items-C6L_5ZiT.mjs";
15
- import { r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.mjs";
16
- import { a as defaultCodexAppInventoryCache, n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-B2CsSdnV.mjs";
17
- import { i as resolveCodexBindingAppServerConnection, t as assertCodexSessionRuntimeOwnership } from "./binding-connection-ThoatDcb.mjs";
18
- import { n as resolveOpenClawExecPolicyForCodexAppServer, t as canUseCodexModelBackedApprovalsReviewerForModel } from "./config-BoTP_mrL.mjs";
19
- import { o as hasCodexMirrorOrigin, t as applyCodexTranscriptTaint } from "./transcript-mirror-attestation-CzM-94NC.mjs";
20
- import { t as readCodexMirroredSessionHistoryMessages } from "./session-history-BrqhSCf9.mjs";
21
- import { i as resolveCodexAppServerAuthProfileIdForAgent, r as resolveCodexAppServerAuthProfileId } from "./auth-profile-WqZtZfXN.mjs";
22
- 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-DA4VR4Eb.mjs";
23
- import { A as isMatchingDynamicToolTerminalDiagnostic, B as CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS, C as readCodexDynamicToolCallParams, 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 assertCodexTurnStartResponse, T as readCodexTurnCompletedNotification, c as isCodexAppServerIndeterminateTransportError, i as isCodexAppServerApprovalRequest, j as resolveDynamicToolCallTimeoutMs, k as isDynamicToolTerminalDiagnosticEvent, m as CodexServerRequestResolvedError, o as isCodexAppServerConnectionClosedError, p as resolveCodexAppServerClientInstanceId, r as getCodexAppServerClientInstanceId, s as isCodexAppServerIndeterminateRequestCancellationError } from "./client-Cs08OXVQ.mjs";
24
- import { _ as CodexProjectionDiagnostics, d as shouldRetireCodexStartupClient, f as terminateCodexBackgroundTerminals, h as getCodexAppServerTurnRouter, m as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, o as closeCodexStartupClientBestEffort, p as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError, s as interruptCodexTurnAndWaitBestEffort, u as retireUnsafeCodexTurnClientBestEffort, v as isCodexNotificationForTurn, y as readCodexNotificationThreadId } from "./attempt-client-cleanup-CEv1cKwF.mjs";
25
- import { r as prepareCodexAppServerAuthBinding } from "./auth-binding-DhLWa_7K.mjs";
26
- 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-CnBS8Wa3.mjs";
27
- import { A as emitCodexNativePreToolUseFailureDiagnostic, C as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, Ct as shouldBuildCodexPluginThreadConfig, D as buildCodexNativeHookRelayDisabledConfig, E as buildCodexNativeHookRelayConfig, K as codexDynamicToolsFingerprint, M as resolveCodexNativeHookRelayTtlMs, N as scheduleCodexNativeHookRelayUnregister, R as hasCodexNativeToolCatalog, T as assertCodexNativeHookRelayAllowed, U as areCodexDynamicToolFingerprintsCompatible, X as fingerprintJsonObject, at as filterCodexDynamicTools, ft as resolveCodexDynamicToolsLoadingForRuntime, gt as buildCodexPluginThreadConfigTimeoutFallback, ht as buildCodexPluginThreadConfigInputFingerprint, j as resolveCodexNativeHookRelayEvents, k as createCodexNativeHookRelay, lt as isSystemAgentOnlyCodexDynamicToolAllowlist, m as buildDeveloperInstructions, mt as buildCodexPluginThreadConfig, p as resolveCodexWebSearchPlan, q as codexLegacyDynamicToolsFingerprint, v as resolveCodexAppServerThreadModelSelection, w as CodexManagedHooksOnlyError, xt as mergeCodexThreadConfigs, z as loadCodexNativeToolCatalog } from "./thread-requests-BLvGkP2R.mjs";
28
- import { A as resolveCodexContinuityProjectionMaxChars, C as buildCodexContinuityCalibration, D as projectContextEngineAssemblyForCodex, E as neutralizeCodexExplicitMentionSigils, O as resolveCodexContextEngineProjectionMaxChars, S as CodexContextAttachmentError, T as isCodexDurableCustomMessage, _ as readCodexMcpToolUiVisibility, a as buildTurnStartParams, b as isContextEngineBindingCompatible, c as assertScheduledCodexAppAuthorityRuntime, d as buildScheduledCodexAppServerConnectionIdentity, f as captureScheduledCodexAppAuthority, g as readCodexMcpToolConnectorId, h as resolveScheduledCodexAppCreatorCaptureDecision, i as buildTurnCollaborationMode, k as resolveCodexContextEngineProjectionReserveTokens, l as buildLegacyScheduledCodexAppRecoveryPrompt, m as readCurrentCodexScheduledAppPolicy$1, n as buildCodexParentLocalInstructions, o as buildCodexUserInput, p as intersectCodexPluginThreadConfigWithScheduledAuthority, s as startOrResumeThread, t as buildCodexHistoryProvenancePrefix, u as buildScheduledCodexAppAuthorityInputFingerprint, v as isCodexAppServerProfilerEnabled, w as fitCodexProjectedContextForTurnStart, x as CODEX_TURN_START_TEXT_INPUT_MAX_CHARS, y as buildContextEngineBinding } from "./thread-lifecycle-B3mfz1TG.mjs";
29
- import { a as resolveCodexRunSessionBindingAuthority, n as createCodexSessionGenerationSupersededError, o as resolveCodexSessionBinding } from "./session-binding-Cm0apEbd.mjs";
30
- import { n as CodexThreadPolicyHandoffError } from "./thread-policy-DGuQsuFC.mjs";
31
- import { r as retainCodexAppServerBindingSubscription, s as withExclusiveCodexAppServerThread, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-DcTtAcXj.mjs";
32
- import { c as promptSnapshot, i as mirrorPromptAtTurnStartBestEffort, n as createCodexAppServerUserMessagePersistenceNotifier, o as buildCodexUserPromptMessage, s as buildResolvedCodexUserPromptMessage, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-BtHDBp1G.mjs";
33
- import { a as resolveCodexPromptError, i as refreshCodexUsageLimitPromptError, n as formatCodexTurnStartUsageLimitError, r as markCodexAuthProfileBlockedFromRateLimits, t as CodexUsageLimitPromptError } from "./usage-limit-error-DUMbefVY.mjs";
19
+ import { a as readCodexProviderRefusal, d as splitPlanText, i as readCodexErrorNotificationMessage, l as readNonNegativeInteger, n as extractRawAssistantText, s as readItem, u as readNullableString } from "./event-projector-values-DJSz8BTk.mjs";
20
+ import { r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-fXkKbPVC.mjs";
21
+ import { a as defaultCodexAppInventoryCache, n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-BL9B5H0L.mjs";
22
+ import { i as resolveCodexBindingAppServerConnection, r as requireCodexSupervisionModelSelection, t as assertCodexSessionRuntimeOwnership } from "./binding-connection-DTtN1KrX.mjs";
23
+ import { r as requestCodexAppServerClientJson, t as CodexAppServerScopedRequestRejectedError } from "./request-BZOfsSXW.mjs";
24
+ import { n as canUseCodexModelBackedApprovalsReviewerForModel, r as resolveOpenClawExecPolicyForCodexAppServer } from "./config-DKhXquav.mjs";
25
+ import { a as isCodexDurableCustomMessage, c as resolveCodexContextEngineProjectionMaxChars, i as fitCodexProjectedContextForTurnStart, l as resolveCodexContinuityProjectionMaxChars, n as CodexContextAttachmentError, o as neutralizeCodexExplicitMentionSigils, r as buildCodexContinuityCalibration, s as projectContextEngineAssemblyForCodex, t as CODEX_TURN_START_TEXT_INPUT_MAX_CHARS } from "./context-engine-projection-PezSESth.mjs";
26
+ import { o as hasCodexMirrorOrigin, t as applyCodexTranscriptTaint } from "./transcript-mirror-attestation-YSegaktH.mjs";
27
+ import { t as readCodexMirroredSessionHistoryMessages } from "./session-history-D83lJWHG.mjs";
28
+ import { i as resolveCodexAppServerAuthProfileIdForAgent, r as resolveCodexAppServerAuthProfileId } from "./auth-profile-B0okYl2D.mjs";
29
+ import { E as isCodexContextRestartSelectionChangedError, H as prepareCodexWorkspaceReferences, I as ensureCodexAppServerClientRuntime, M as getCodexInferenceThreadQualification, U as protectCodexAppServerLiveThread, X as readRecentCodexRateLimits, Y as readCodexRateLimitsRevision, _ as retainSharedCodexAppServerClientIfCurrent, a as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, c as getLeasedSharedCodexAppServerClient, dt as TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS, et as resolveCodexAppServerAuthAccountCacheKey, f as readCodexAppServerClientDesktopGenerationFingerprint, h as releaseLeasedSharedCodexAppServerClient, ht as withCodexStartupTimeout, i as clearSharedCodexAppServerClientIfCurrent, j as getCodexInferenceThread, l as getSharedCodexAppServerClient, lt as CodexAppServerStartupError, mt as resolveCodexStartupTimeoutMs, s as createIsolatedCodexAppServerClient, tt as resolveCodexAppServerPreparedAuthHandoff, u as isCodexAppServerStartSelectionChangedError, ut as TURN_FINALIZE_DRAIN_ABORT_GRACE_MS, w as CodexThreadClientReplacementError, x as CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED } from "./shared-client-CJCTeFpQ.mjs";
30
+ import { a as isCodexResponsesOAuthRun, r as isCodexResponsesOAuth } from "./responses-oauth-twnuTaAa.mjs";
31
+ import { A as handleDynamicToolCallWithTimeout, E as readCodexTurnCompletedNotification, F as resolveTerminalDynamicToolBatchAction, I as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, L as shouldReleaseTurnAfterTerminalDynamicTool, M as isDynamicToolTerminalDiagnosticEvent, N as isMatchingDynamicToolTerminalDiagnostic, P as resolveDynamicToolCallTimeoutMs, R as toCodexDynamicToolProgressResponse, S as assertCodexTurnStartResponse, U as CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS, c as isCodexAppServerIndeterminateTransportError, i as isCodexAppServerApprovalRequest, j as hasPendingDynamicToolTerminalDiagnostic, k as createCodexElicitationResponse, m as CodexServerRequestResolvedError, o as isCodexAppServerConnectionClosedError, p as resolveCodexAppServerClientInstanceId, r as getCodexAppServerClientInstanceId, s as isCodexAppServerIndeterminateRequestCancellationError, w as readCodexDynamicToolCallParams, z as toCodexDynamicToolProtocolResponse } from "./client-qyUBJlGZ.mjs";
32
+ import { n as isCodexWebSocketOpenFailure } from "./transport-websocket-BTBE-LD9.mjs";
33
+ import { M as matchesCodexSnapshotTurn, N as shouldClearTerminalPresentationForNativeItem, _ as CodexProjectionDiagnostics, d as shouldRetireCodexStartupClient, f as terminateCodexBackgroundTerminals, h as getCodexAppServerTurnRouter, k as itemName, m as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, o as closeCodexStartupClientBestEffort, p as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError, s as interruptCodexTurnAndWaitBestEffort, u as retireUnsafeCodexTurnClientBestEffort, v as isCodexNotificationForTurn, y as readCodexNotificationThreadId } from "./attempt-client-cleanup-B-S7ngS_.mjs";
34
+ import { r as prepareCodexAppServerAuthBinding } from "./auth-binding-BLWz7stm.mjs";
35
+ import { a as isRawFunctionToolOutputCompletionNotification, c as readNotificationItemId, i as isPendingOpenClawDynamicToolCompletionNotification, l as readRawResponseToolCallId, o as isTerminalTurnStatus, r as isCodexTurnAbortMarkerNotification, s as readCodexNotificationItem, t as CodexUsageProjection, u as updateActiveTurnItemIds } from "./event-projector-usage-03R0I2dM.mjs";
36
+ import { n as listAllCodexAppServerModels } from "./models-DfLmPV0k.mjs";
37
+ import { A as createCodexNativeHookRelay, B as loadCodexNativeToolCatalog, D as buildCodexNativeHookRelayConfig, E as assertCodexNativeHookRelayAllowed, K as codexDynamicToolsFingerprint, M as resolveCodexNativeHookRelayEvents, N as resolveCodexNativeHookRelayTtlMs, O as buildCodexNativeHookRelayDisabledConfig, P as scheduleCodexNativeHookRelayUnregister, St as mergeCodexThreadConfigs, T as CodexManagedHooksOnlyError, W as areCodexDynamicToolFingerprintsCompatible, X as fingerprintJsonObject, _t as buildCodexPluginThreadConfigTimeoutFallback, gt as buildCodexPluginThreadConfigInputFingerprint, h as buildDeveloperInstructions, ht as buildCodexPluginThreadConfig, ot as filterCodexDynamicTools, p as resolveCodexWebSearchPlan, pt as resolveCodexDynamicToolsLoadingForRuntime, q as codexLegacyDynamicToolsFingerprint, tt as stabilizeJsonValue, ut as isSystemAgentOnlyCodexDynamicToolAllowlist, w as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, wt as shouldBuildCodexPluginThreadConfig, x as joinPresentSections, y as resolveCodexAppServerThreadModelSelection, z as hasCodexNativeToolCatalog } from "./thread-requests-OWGOiDaV.mjs";
38
+ import { _ as readCodexMcpToolUiVisibility, a as buildTurnStartParams, b as isContextEngineBindingCompatible, c as assertScheduledCodexAppAuthorityRuntime, d as buildScheduledCodexAppServerConnectionIdentity, f as captureScheduledCodexAppAuthority, g as readCodexMcpToolConnectorId, h as resolveScheduledCodexAppCreatorCaptureDecision, i as buildTurnCollaborationMode, l as buildLegacyScheduledCodexAppRecoveryPrompt, m as readCurrentCodexScheduledAppPolicy, n as buildCodexParentLocalInstructions, o as buildCodexUserInput, p as intersectCodexPluginThreadConfigWithScheduledAuthority, s as startOrResumeThread, t as buildCodexHistoryProvenancePrefix, u as buildScheduledCodexAppAuthorityInputFingerprint, v as isCodexAppServerProfilerEnabled, y as buildContextEngineBinding } from "./thread-lifecycle-_bAbjedG.mjs";
39
+ import { a as resolveCodexRunSessionBindingAuthority, n as createCodexSessionGenerationSupersededError, o as resolveCodexSessionBinding } from "./session-binding-DGCYAfvD.mjs";
40
+ import { a as CodexToolTranscriptProjection, b as sanitizeCodexAgentEventRecord, c as shouldEmitTranscriptToolProgress, i as emitCodexAgentEvent, p as requestPluginApprovalOutcome, r as CodexEventProjection, s as CodexToolProgressProjection, t as codexNativeSubagentMonitorRuntime, v as isCodexCommandBearingToolCall, x as sanitizeCodexToolArguments, y as resolveCodexToolProgressDetailMode } from "./native-subagent-monitor-BwkQXf9e.mjs";
41
+ import { n as CodexThreadPolicyHandoffError, s as restoreCodexThreadSkillsCatalogAfterCompaction } from "./thread-policy-gNPzzpVp.mjs";
42
+ import { c as withExclusiveCodexAppServerThread, r as retainCodexAppServerBindingSubscription, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-B6pPt21M.mjs";
43
+ import { c as promptSnapshot, i as mirrorPromptAtTurnStartBestEffort, n as createCodexAppServerUserMessagePersistenceNotifier, o as buildCodexUserPromptMessage, s as buildResolvedCodexUserPromptMessage, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-kxmCYsuF.mjs";
44
+ import { a as resolveCodexPromptError, i as refreshCodexUsageLimitPromptError, n as formatCodexTurnStartUsageLimitError, r as markCodexAuthProfileBlockedFromRateLimits, t as CodexUsageLimitPromptError } from "./usage-limit-error-wSMQkbpV.mjs";
34
45
  import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.mjs";
35
46
  import { t as attemptTerminal } from "./attempt-terminal-gZrxQ35N.mjs";
36
- 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";
37
- import { t as CODEX_INFERENCE_GENERATION_KEY } from "./inference-context-D96l9-ew.mjs";
38
- import { i as createAssistantReasoningMessage, n as createAssistantCommentaryMessage, r as createAssistantMessage, t as createAssistantAsyncMessage } from "./event-projector-assistant-message-BsruvNrH.mjs";
39
- import { C as sanitizeCodexToolArguments, S as resolveCodexToolProgressDetailMode, b as inferCodexDynamicToolMeta, w as sanitizeCodexToolResponse, x as isCodexCommandBearingToolCall } from "./native-subagent-task-ids-wb8CKZGN.mjs";
40
- import { C as shouldEnableCodexAppServerNativeToolSurface, E as mapCodexAppServerRemoteWorkspacePath, S as resolveCodexSandboxEnvironmentSelection, T as shouldWarnCodexDynamicToolBuildStageSummary, _ as formatCodexDynamicToolBuildStageSummary, a as emitDynamicToolStartedDiagnostic, b as resolveCodexExternalSandboxPolicyForOpenClawSandbox, c as ensureCodexSandboxExecServerEnvironment, d as hasCodexNativeBackgroundProcesses, f as readBoundedCodexRemoteWorkspaceFile, g as disableCodexPluginThreadConfig, h as createCodexDynamicToolBuildStageTracker, i as emitDynamicToolErrorDiagnostic, l as releaseCodexSandboxExecServerEnvironment, m as buildDynamicTools, n as projectCodexExecutableDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as CodexNativeToolLifecycleProjector, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as CodexNativeProcessAuthority, v as resolveCodexAppServerExecutionCwd, w as shouldRequireCodexSandboxExecServerEnvironment, x as resolveCodexMessageToolProvider, y as resolveCodexAppServerHookChannelId } from "./dynamic-tools-BDXl-8Cw.mjs";
41
- import { t as resolveCodexProviderWebSearchSupport } from "./provider-capabilities-BfE88FZ5.mjs";
42
- import { a as requestPluginApprovalOutcome } from "./plugin-approval-roundtrip-C0MZzCuP.mjs";
43
- import { a as CodexToolProgressProjection, i as CodexToolTranscriptProjection, n as CodexEventProjection, o as shouldEmitTranscriptToolProgress, r as emitCodexAgentEvent, t as codexNativeSubagentMonitorRuntime } from "./native-subagent-monitor-D3filLY2.mjs";
44
- import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy } from "./session-permission-policy-BI1QK_98.mjs";
45
- import { a as getCodexContextFileDisplayBasename, c as normalizeCodexContextFilePath, d as shouldInjectCodexOpenClawPromptContext, i as getCodexContextFileBasename, l as normalizeCodexDynamicToolName, n as CODEX_NATIVE_PROJECT_DOC_BASENAMES, o as getCodexWorkspaceMemoryToolNames, r as buildCodexWorkspaceBootstrapContext, s as isNonEmptyString$1 } from "./attempt-workspace-context-DUVEn_CS.mjs";
46
- import { n as captureCodexSettledTurnFinalizationContext } from "./settled-turn-context-fmwouT5I.mjs";
47
- import { a as runCodexComputerUseLiveTest, n as ensureCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-Ctmo83k_.mjs";
47
+ import { a as shouldKeepCodexSharedAbortOpen, i as runCodexAgentEndHook, n as ensureCodexWorkspaceDirOnce, o as withCodexAppServerFastModeServiceTier, r as estimateCodexAppServerProjectedTurnTokens, t as emitCodexAppServerEvent } from "./run-attempt-lifecycle-C-6O3Exn.mjs";
48
+ import { t as CODEX_INFERENCE_GENERATION_KEY } from "./inference-metadata-CgIf7sOx.mjs";
49
+ import "./inference-context-D-9gWlTR.mjs";
50
+ import { i as createAssistantReasoningMessage, n as createAssistantCommentaryMessage, r as createAssistantMessage, t as createAssistantAsyncMessage } from "./event-projector-assistant-message-MV_1dj-3.mjs";
51
+ import { C as readCodexRetainedBackgroundCommands, E as CodexNativeToolLifecycleProjector, S as hasCodexNativeBackgroundProcesses, T as mapCodexAppServerRemoteWorkspacePath, _ as shouldWarnCodexDynamicToolBuildStageSummary, a as emitDynamicToolStartedDiagnostic, b as createCodexNativePreToolUseFailureBuffer, c as buildDynamicTools, d as resolveCodexAppServerHookChannelId, f as resolveCodexExternalSandboxPolicyForOpenClawSandbox, g as shouldRequireCodexSandboxExecServerEnvironment, h as shouldEnableCodexAppServerNativeToolSurface, i as emitDynamicToolErrorDiagnostic, l as disableCodexPluginThreadConfig, m as resolveCodexSandboxEnvironmentSelection, n as projectCodexExecutableDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as resolveCodexMessageToolProvider, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as resolveCodexAppServerExecutionCwd, v as ensureCodexSandboxExecServerEnvironment, w as readBoundedCodexRemoteWorkspaceFile, x as CodexNativeProcessAuthority, y as releaseCodexSandboxExecServerEnvironment } from "./dynamic-tools-Db2sY5cZ.mjs";
52
+ import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy } from "./session-permission-policy-Ci_fVX6y.mjs";
53
+ import { a as getCodexContextFileDisplayBasename, c as normalizeCodexDynamicToolName, i as getCodexContextFileBasename, n as CODEX_NATIVE_PROJECT_DOC_BASENAMES, o as isNonEmptyString, r as buildCodexWorkspaceBootstrapContext, s as normalizeCodexContextFilePath } from "./attempt-workspace-context-BJ5Z_olH.mjs";
54
+ import { n as captureCodexSettledTurnFinalizationContext } from "./settled-turn-context-D4yj4rxf.mjs";
55
+ import { t as resolveCodexProviderWebSearchSupport } from "./provider-capabilities-DG5qbsUZ.mjs";
56
+ import { a as createComputerUseRequest, n as ensureCodexComputerUse, o as runCodexComputerUseLiveTest, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-BRwtRct9.mjs";
48
57
  import { asOptionalRecord, normalizeOptionalString, readNonBlankString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
49
58
  import { createHash } from "node:crypto";
50
59
  import { isDeepStrictEqual } from "node:util";
51
60
  import { resolveAgentConfig, resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
52
- import { MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
61
+ import { asDateTimestampMs } from "openclaw/plugin-sdk/number-runtime";
53
62
  import path from "node:path";
54
63
  import fs from "node:fs/promises";
55
64
  import { isPathStrictlyInside, readFileWindowFully, root } from "openclaw/plugin-sdk/file-access-runtime";
56
65
  import { addAbortListener } from "node:events";
66
+ import { Type } from "typebox";
57
67
  import { truncateUtf16Safe, truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
58
68
  import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
59
69
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
70
+ import { createStageTimingTracker, formatStageTimings } from "openclaw/plugin-sdk/time-runtime";
60
71
  import { Buffer as Buffer$1 } from "node:buffer";
61
72
  import { resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
62
- import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, agentHarnessStructuredInput, assembleHarnessContextEngine, assertContextEngineHostSupport, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedForegroundPromptContext, buildHarnessContextEngineRuntimeContext, buildWatchedSessionsHarnessContext, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, hasBeforeToolCallPolicy, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, projectAgentToolActivity, 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";
73
+ import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, HEARTBEAT_RESPONSE_TOOL_NAME, agentHarnessStructuredInput, applyEmbeddedAttemptToolsAllow, assembleHarnessContextEngine, assertContextEngineHostSupport, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedForegroundPromptContext, buildHarnessContextEngineRuntimeContext, buildWatchedSessionsHarnessContext, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, hasBeforeToolCallPolicy, inferToolMetaFromArgs, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, normalizeHeartbeatToolResponse, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, projectAgentToolActivity, 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";
63
74
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
75
+ import { AgentHarnessProjectionSettlement, createAgentHarnessAttemptCancellation, createAgentHarnessAttemptDeadlineController, createAgentHarnessAttemptLifecycle, shouldIncludeAgentHarnessRuntimeContext } from "openclaw/plugin-sdk/agent-harness-attempt-runtime";
64
76
  import { getSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
65
- import { acknowledgeInternalToolResult } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
77
+ import { acknowledgeInternalToolResult, createAgentHarnessToolExecutionRegistry } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
78
+ import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
66
79
  import { captureFinalCodexCronCreatorToolAllowlist, formatMcpCodexApprovalRemedy, materializeStaticMcpToolsForHarnessRun, resolveCodexMcpToolOverridesForAgent, resolveCodexTtsProvenanceTransfer } from "openclaw/plugin-sdk/codex-mcp-projection";
67
80
  import { appendSessionYieldContext, hasPromptImageInput } from "openclaw/plugin-sdk/session-transcript-runtime";
68
- import { prepareAgentWorkspaceAttachments } from "openclaw/plugin-sdk/agent-workspace-runtime";
69
81
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-local-roots";
70
82
  import { isSilentReplyPayloadText } from "openclaw/plugin-sdk/reply-chunking";
71
83
  import { generatedImageAssetFromBase64 } from "openclaw/plugin-sdk/image-generation";
72
84
  import { resolveGeneratedMediaMaxBytes } from "openclaw/plugin-sdk/media-generation-runtime";
73
85
  import { normalizeMediaReferenceForComparison, saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
74
86
  import { stripInvisibleUnicode } from "openclaw/plugin-sdk/web-content-extractor";
87
+ import { prepareAgentWorkspaceAttachments } from "openclaw/plugin-sdk/agent-workspace-runtime";
75
88
  import { MESSAGE_TOOL_DELIVERY_HINTS } from "openclaw/plugin-sdk/message-tool-delivery-hints";
76
- import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
77
89
  //#region extensions/codex/src/app-server/attempt-preparation-timing.ts
78
90
  /** Records startup before the native turn owns inference and tool execution. */
79
91
  function createCodexAttemptPreparationTiming(params) {
80
- const tracker = createCodexDynamicToolBuildStageTracker();
92
+ const tracker = createStageTimingTracker();
81
93
  const profilerEnabled = isCodexAppServerProfilerEnabled(params.config);
82
94
  const totalWarnMs = profilerEnabled ? 1e3 : 1e4;
83
95
  const stageWarnMs = profilerEnabled ? 500 : 5e3;
@@ -87,7 +99,7 @@ function createCodexAttemptPreparationTiming(params) {
87
99
  const slowTotal = outcome !== "completed" && summary.totalMs >= totalWarnMs;
88
100
  const slowStage = outcome !== "ready" && (lastStage?.durationMs ?? 0) >= stageWarnMs;
89
101
  if (!slowTotal && !slowStage) return;
90
- embeddedAgentLog.warn(`codex app-server preparation timings runId=${params.runId} sessionId=${params.sessionId} stage=${stage} outcome=${outcome} totalMs=${summary.totalMs} stages=${formatCodexDynamicToolBuildStageSummary(summary)}`, {
102
+ embeddedAgentLog.warn(`codex app-server preparation timings runId=${params.runId} sessionId=${params.sessionId} stage=${stage} outcome=${outcome} totalMs=${summary.totalMs} stages=${formatStageTimings(summary.stages)}`, {
91
103
  runId: params.runId,
92
104
  sessionId: params.sessionId,
93
105
  sessionKey: params.sessionKey,
@@ -116,10 +128,6 @@ function createCodexAttemptPreparationTiming(params) {
116
128
  }
117
129
  //#endregion
118
130
  //#region extensions/codex/src/app-server/attempt-steering.ts
119
- /**
120
- * Debounced steering queue for forwarding user messages to an active Codex
121
- * app-server turn.
122
- */
123
131
  const CODEX_STEER_ALL_DEBOUNCE_MS = 500;
124
132
  var CodexSteeringAcceptedUnconfirmedError = class extends Error {
125
133
  constructor(message, options) {
@@ -182,7 +190,7 @@ function createCodexSteeringQueue(params) {
182
190
  params.signal.removeEventListener("abort", abortQueue);
183
191
  clearBatchTimer();
184
192
  batchedMessages = [];
185
- for (const batch of dispatchedBatches.values()) for (const item of batch.items) acceptItem(item);
193
+ for (const batch of dispatchedBatches.values()) for (const item of batch) acceptItem(item);
186
194
  dispatchedBatches.clear();
187
195
  for (const item of pendingMessages) rejectItem(item, error);
188
196
  };
@@ -191,7 +199,7 @@ function createCodexSteeringQueue(params) {
191
199
  sealedError = /* @__PURE__ */ new Error("codex app-server steering queue admission sealed");
192
200
  clearBatchTimer();
193
201
  batchedMessages = [];
194
- const dispatchedItems = new Set([...dispatchedBatches.values()].flatMap((batch) => batch.items));
202
+ const dispatchedItems = new Set([...dispatchedBatches.values()].flat());
195
203
  for (const item of pendingMessages) if (!dispatchedItems.has(item)) rejectItem(item, sealedError);
196
204
  };
197
205
  const abortQueue = () => {
@@ -241,7 +249,7 @@ function createCodexSteeringQueue(params) {
241
249
  if (liveItems.length === 0) return;
242
250
  }
243
251
  clientUserMessageId = `openclaw:${params.turnId}:steer:${++batchSequence}`;
244
- dispatchedBatches.set(clientUserMessageId, { items: liveItems });
252
+ dispatchedBatches.set(clientUserMessageId, liveItems);
245
253
  const request = {
246
254
  threadId: params.threadId,
247
255
  expectedTurnId: params.turnId,
@@ -255,7 +263,7 @@ function createCodexSteeringQueue(params) {
255
263
  assertActive();
256
264
  liveItems = liveItems.filter(isCurrent);
257
265
  request.input = liveItems.flatMap((item) => item.prepared.input);
258
- dispatchedBatches.set(request.clientUserMessageId, { items: liveItems });
266
+ dispatchedBatches.set(request.clientUserMessageId, liveItems);
259
267
  if (liveItems.length === 0) {
260
268
  skippedRevokedBatch = true;
261
269
  throw new Error("Codex steering batch has no authorized inputs");
@@ -290,19 +298,14 @@ function createCodexSteeringQueue(params) {
290
298
  return send;
291
299
  };
292
300
  const createPendingMessage = (text, options, assertCurrent = () => {}) => {
293
- let resolveDelivery;
294
- let rejectDelivery;
295
- const delivery = new Promise((resolve, reject) => {
296
- resolveDelivery = resolve;
297
- rejectDelivery = reject;
298
- });
301
+ const { promise: delivery, resolve, reject } = createDeferred();
299
302
  const item = {
300
303
  ...options,
301
304
  assertCurrent,
302
305
  acceptance: "open",
303
306
  text,
304
- resolve: resolveDelivery,
305
- reject: rejectDelivery,
307
+ resolve,
308
+ reject,
306
309
  settled: false
307
310
  };
308
311
  pendingMessages.add(item);
@@ -337,7 +340,7 @@ function createCodexSteeringQueue(params) {
337
340
  const batch = dispatchedBatches.get(clientUserMessageId);
338
341
  if (!batch) return false;
339
342
  dispatchedBatches.delete(clientUserMessageId);
340
- for (const item of batch.items) resolveItem(item);
343
+ for (const item of batch) resolveItem(item);
341
344
  return true;
342
345
  },
343
346
  getAcceptedMessages: () => acceptedMessages.slice(),
@@ -573,11 +576,15 @@ var CodexAssistantProjection = class {
573
576
  this.supersedeVisibleAnswerCandidate();
574
577
  return;
575
578
  }
579
+ for (const itemId of this.assistantItemOrder) if (!this.completedAssistantItemIds.has(itemId) && !this.isAsyncAssistantItem(itemId) && (this.isFinalAnswerAssistantItem(itemId) || this.isCommentaryAssistantItem(itemId))) {
580
+ if (itemId === this.visibleAnswerCandidateItemId) this.supersedeVisibleAnswerCandidate();
581
+ this.assistantTextByItem.delete(itemId);
582
+ }
576
583
  const turnItems = turn.items ?? [];
577
584
  const authoritativeIndex = turnItems.findLastIndex((item) => {
578
585
  if (item.type !== "agentMessage" || typeof item.text !== "string" || item.text.trim().length === 0) return false;
579
- const phase = readItemString(item, "phase");
580
- return readItemString(item, "delivery") !== "async" && (phase === "final_answer" || phase === void 0);
586
+ const phase = readStringField(item, "phase");
587
+ return readStringField(item, "delivery") !== "async" && (phase === "final_answer" || phase === void 0);
581
588
  });
582
589
  const authoritative = authoritativeIndex >= 0 ? turnItems[authoritativeIndex] : void 0;
583
590
  if (turnItems.slice(authoritativeIndex + 1).some(shouldClearTerminalPresentationForNativeItem) || authoritative?.id === this.latestTerminalAssistantCandidateItemId && this.latestTerminalAssistantCandidateSuperseded) {
@@ -620,9 +627,9 @@ var CodexAssistantProjection = class {
620
627
  }
621
628
  rememberAssistantPhase(item) {
622
629
  if (item?.type !== "agentMessage") return;
623
- const phase = readItemString(item, "phase");
630
+ const phase = readStringField(item, "phase");
624
631
  if (phase) this.assistantPhaseByItem.set(item.id, phase);
625
- const delivery = readItemString(item, "delivery");
632
+ const delivery = readStringField(item, "delivery");
626
633
  if (delivery) this.assistantDeliveryByItem.set(item.id, delivery);
627
634
  if (item.questions !== void 0) {
628
635
  const questions = readCodexAsyncQuestions(item.questions);
@@ -831,17 +838,17 @@ var CodexGeneratedMediaProjection = class {
831
838
  async recordNative(item) {
832
839
  if (item?.type !== "imageGeneration") return;
833
840
  this.itemIds.add(item.id);
834
- const savedPath = readItemString(item, "savedPath")?.trim();
841
+ const savedPath = readStringField(item, "savedPath")?.trim();
835
842
  if (savedPath) this.mediaByItemId.set(item.id, {
836
843
  ...this.mediaByItemId.get(item.id),
837
844
  savedPath
838
845
  });
839
- const result = readItemString(item, "result");
846
+ const result = readStringField(item, "result");
840
847
  if (result) {
841
848
  await this.recordImage({
842
849
  itemId: item.id,
843
850
  result,
844
- revisedPrompt: readItemString(item, "revisedPrompt"),
851
+ revisedPrompt: readStringField(item, "revisedPrompt"),
845
852
  source: "native"
846
853
  });
847
854
  return;
@@ -866,7 +873,7 @@ var CodexGeneratedMediaProjection = class {
866
873
  await this.recordImage({
867
874
  itemId: item.id,
868
875
  result: response.dataBase64,
869
- revisedPrompt: readItemString(item, "revisedPrompt"),
876
+ revisedPrompt: readStringField(item, "revisedPrompt"),
870
877
  source: "native"
871
878
  });
872
879
  } catch (error) {
@@ -1062,13 +1069,12 @@ var CodexReasoningProjection = class {
1062
1069
  async handleTurnPlanUpdated(params, source = "codex-app-server") {
1063
1070
  const explanation = readNullableString(params, "explanation");
1064
1071
  const plan = Array.isArray(params.plan) ? params.plan.flatMap((entry) => {
1065
- if (!entry || typeof entry !== "object" || Array.isArray(entry)) return [];
1066
- const record = entry;
1067
- const step = readStringField(record, "step");
1072
+ if (!isJsonObject(entry)) return [];
1073
+ const step = readStringField(entry, "step");
1068
1074
  if (!step) return [];
1069
1075
  return [{
1070
1076
  step,
1071
- status: normalizePlanStepStatus(readStringField(record, "status"))
1077
+ status: normalizePlanStepStatus(readStringField(entry, "status"))
1072
1078
  }];
1073
1079
  }) : void 0;
1074
1080
  const planText = [explanation, ...(plan ?? []).map(({ step, status }) => `- [${status}] ${step}`)].filter((part) => Boolean(part)).join("\n");
@@ -1150,38 +1156,10 @@ function readReasoningSections(value) {
1150
1156
  }
1151
1157
  //#endregion
1152
1158
  //#region extensions/codex/src/app-server/event-projector-settlement.ts
1153
- var CodexProjectionSettlement = class {
1159
+ var CodexProjectionSettlement = class extends AgentHarnessProjectionSettlement {
1154
1160
  constructor(params, isActive) {
1161
+ super(params, isActive, { label: "codex app-server" });
1155
1162
  this.turnTainted = false;
1156
- this.pending = /* @__PURE__ */ new Map();
1157
- const detach = (stage, callback) => callback ? (...args) => {
1158
- if (!isActive()) return;
1159
- const completion = createDeferred();
1160
- this.pending.set(completion.promise, stage);
1161
- const settled = () => {
1162
- this.pending.delete(completion.promise);
1163
- completion.resolve();
1164
- };
1165
- const failed = (error) => {
1166
- embeddedAgentLog.warn(`codex app-server ${stage} callback failed: ${String(error)}`);
1167
- settled();
1168
- };
1169
- try {
1170
- Promise.resolve(callback(...args)).then(settled, failed);
1171
- } catch (error) {
1172
- failed(error);
1173
- }
1174
- } : void 0;
1175
- this.params = {
1176
- ...params,
1177
- onAssistantMessageStart: detach("onAssistantMessageStart", params.onAssistantMessageStart),
1178
- onPartialReply: detach("onPartialReply", params.onPartialReply),
1179
- onReasoningStream: detach("onReasoningStream", params.onReasoningStream),
1180
- onReasoningEnd: detach("onReasoningEnd", params.onReasoningEnd)
1181
- };
1182
- }
1183
- get pendingStage() {
1184
- return this.stage ?? this.pending.values().next().value;
1185
1163
  }
1186
1164
  get completedAnswer() {
1187
1165
  const turn = this.terminalReceipt;
@@ -1191,18 +1169,6 @@ var CodexProjectionSettlement = class {
1191
1169
  answer
1192
1170
  } : void 0;
1193
1171
  }
1194
- async project(stage, project) {
1195
- const previous = this.stage;
1196
- this.stage = stage;
1197
- try {
1198
- return await project();
1199
- } finally {
1200
- this.stage = previous;
1201
- }
1202
- }
1203
- async drain() {
1204
- while (this.pending.size > 0) await Promise.all(this.pending.keys());
1205
- }
1206
1172
  };
1207
1173
  //#endregion
1208
1174
  //#region extensions/codex/src/app-server/event-projector-snapshot.ts
@@ -1361,6 +1327,7 @@ var CodexTurnProjection = class {
1361
1327
  this.threadId = threadId;
1362
1328
  this.turnId = turnId;
1363
1329
  this.options = options;
1330
+ this.observedItemIds = /* @__PURE__ */ new Set();
1364
1331
  this.activeItemIds = /* @__PURE__ */ new Set();
1365
1332
  this.completedItemIds = /* @__PURE__ */ new Set();
1366
1333
  this.activeCompactionItemIds = /* @__PURE__ */ new Set();
@@ -1404,11 +1371,17 @@ var CodexTurnProjection = class {
1404
1371
  const { promptError: initialPromptError, promptErrorSource: initialPromptErrorSource, providerRefusal } = this.terminalFailure;
1405
1372
  const upstreamUserText = this.options.upstreamUserText;
1406
1373
  const turnTainted = this.settlement.turnTainted;
1374
+ const observedItemCount = (/* @__PURE__ */ new Set([...this.observedItemIds, ...this.completedItemIds])).size;
1407
1375
  const activeItemCount = this.activeItemIds.size;
1408
1376
  const completedItemCount = this.completedItemIds.size;
1409
1377
  const guardianReviewCount = this.eventProjection.guardianReviewCount;
1410
1378
  const yieldDetected = options?.yieldDetected;
1411
- this.nativeToolLifecycleProjector.finalizeActive();
1379
+ const retainedCommands = /* @__PURE__ */ new Map();
1380
+ if (!aborted && !this.options.runAbortSignal?.aborted && completedTurn?.status === "completed" && !initialPromptError) {
1381
+ const pending = this.nativeToolLifecycleProjector.pendingCommands();
1382
+ for (const [id, processId] of options?.readRetainedNativeCommands?.() ?? []) if (pending.has(id) && (pending.get(id) === null || pending.get(id) === processId)) retainedCommands.set(id, processId);
1383
+ }
1384
+ this.nativeToolLifecycleProjector.finalizeActive(void 0, retainedCommands);
1412
1385
  const assistantTexts = this.assistantProjection.collectAssistantTexts();
1413
1386
  const asyncMessages = this.assistantProjection.collectAsyncMessages();
1414
1387
  const commentaryMessages = this.assistantProjection.collectCommentaryMessages();
@@ -1424,6 +1397,7 @@ var CodexTurnProjection = class {
1424
1397
  const hasDeliverableAssistantOnCompletedTurn = completedTurn?.status === "completed" && assistantTexts.some((text) => text.trim().length > 0);
1425
1398
  const synthesizedMissingToolResultError = this.toolTranscriptProjection.synthesizeMissingToolResults({
1426
1399
  synthesize: legacyFailClosed,
1400
+ retainedCommands,
1427
1401
  terminalDisposition: aborted ? "tool_error" : hasDeliverableAssistantOnCompletedTurn ? "diagnostic_only" : "prompt_error"
1428
1402
  });
1429
1403
  const storedMissingToolResultError = synthesizedMissingToolResultError ?? previousMissingToolResultError;
@@ -1504,7 +1478,7 @@ var CodexTurnProjection = class {
1504
1478
  replaySafe: !hadPotentialSideEffects
1505
1479
  },
1506
1480
  itemLifecycle: {
1507
- startedCount: activeItemCount + completedItemCount,
1481
+ startedCount: observedItemCount,
1508
1482
  completedCount: completedItemCount,
1509
1483
  activeCount: activeItemCount
1510
1484
  },
@@ -1523,13 +1497,21 @@ var CodexTurnProjection = class {
1523
1497
  //#region extensions/codex/src/app-server/event-projector.ts
1524
1498
  const optedOutNotificationMethods = new Set(CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS);
1525
1499
  var CodexAppServerEventProjector = class extends CodexTurnProjection {
1500
+ constructor(..._args) {
1501
+ super(..._args);
1502
+ this.compactionProgress = /* @__PURE__ */ new Map();
1503
+ }
1526
1504
  getCompletedTurnStatus() {
1527
1505
  return this.completedTurn?.status;
1528
1506
  }
1507
+ getPendingNativeCommands() {
1508
+ return !this.projectionClosed && !this.aborted && !this.options.runAbortSignal?.aborted && this.completedTurn?.status === "completed" && !this.terminalFailure.promptError ? this.nativeToolLifecycleProjector.pendingCommands() : /* @__PURE__ */ new Map();
1509
+ }
1529
1510
  /** Native completion owns the answer independently of unfinished host projection. */
1530
1511
  recoverCompletedAnswer() {
1531
1512
  const completed = this.settlement.completedAnswer;
1532
1513
  if (!completed || this.aborted || this.terminalFailure.promptError) return false;
1514
+ this.closeCompactionProgress();
1533
1515
  this.projectionController.abort();
1534
1516
  this.transcriptCheckpoint.abandon();
1535
1517
  this.completedTurn = completed.turn;
@@ -1565,6 +1547,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1565
1547
  }
1566
1548
  /** Fence delayed projections before the turn's final snapshot leaves its owner. */
1567
1549
  closeProjection() {
1550
+ this.closeCompactionProgress();
1568
1551
  this.projectionController.abort();
1569
1552
  return this.settlement.project("transcript/checkpoint", () => this.transcriptCheckpoint.flush(true));
1570
1553
  }
@@ -1747,6 +1730,16 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1747
1730
  isCompacting() {
1748
1731
  return this.activeCompactionItemIds.size > 0;
1749
1732
  }
1733
+ finishCompactionProgress(itemId, completed) {
1734
+ if (this.compactionProgress.get(itemId) === "closed") return;
1735
+ this.compactionProgress.set(itemId, "closed");
1736
+ this.eventProjection.emitCompactionEnd(itemId, completed);
1737
+ }
1738
+ closeCompactionProgress() {
1739
+ for (const itemId of this.activeCompactionItemIds) this.activeItemIds.delete(itemId);
1740
+ this.activeCompactionItemIds.clear();
1741
+ for (const [itemId, progress] of this.compactionProgress) if (progress === "open") this.finishCompactionProgress(itemId, this.completedItemIds.has(itemId));
1742
+ }
1750
1743
  isCompactionProjectionActive() {
1751
1744
  return !this.projectionClosed && !this.aborted && !this.options.runAbortSignal?.aborted;
1752
1745
  }
@@ -1754,20 +1747,26 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1754
1747
  const item = readItem(params.item);
1755
1748
  if (item?.type === "agentMessage" && item.text) this.eventProjection.markSafetyBufferingAssistantStarted();
1756
1749
  const itemId = item?.id ?? readStringField(params, "itemId");
1750
+ if (itemId) this.observedItemIds.add(itemId);
1751
+ if (item?.type === "contextCompaction" && itemId) {
1752
+ if (this.completedTurn || this.activeCompactionItemIds.has(itemId) || this.completedItemIds.has(itemId) || this.compactionProgress.has(itemId)) return;
1753
+ this.activeCompactionItemIds.add(itemId);
1754
+ }
1757
1755
  await this.assistantProjection.recordItemStarted(item, itemId);
1756
+ if (this.projectionClosed || item?.type === "contextCompaction" && itemId && !this.activeCompactionItemIds.has(itemId)) return;
1758
1757
  if (itemId) this.activeItemIds.add(itemId);
1759
1758
  this.recordNativeToolOutcome(item);
1760
1759
  if (item?.type === "contextCompaction" && itemId) {
1761
- if (!this.isCompactionProjectionActive()) return;
1762
- this.activeCompactionItemIds.add(itemId);
1760
+ if (!this.isCompactionProjectionActive() || !this.activeCompactionItemIds.has(itemId)) return;
1763
1761
  const messages = await this.toolTranscriptProjection.readMirroredSessionMessages(this.options.runAbortSignal);
1764
- if (!this.isCompactionProjectionActive()) return;
1762
+ if (!this.isCompactionProjectionActive() || !this.activeCompactionItemIds.has(itemId)) return;
1765
1763
  await runAgentHarnessBeforeCompactionHook({
1766
1764
  sessionFile: this.params.sessionFile,
1767
1765
  messages,
1768
1766
  ctx: this.options.agentHookContext ?? {}
1769
1767
  });
1770
- if (!this.isCompactionProjectionActive()) return;
1768
+ if (!this.isCompactionProjectionActive() || !this.activeCompactionItemIds.has(itemId)) return;
1769
+ this.compactionProgress.set(itemId, "open");
1771
1770
  this.emitAgentEvent({
1772
1771
  stream: "compaction",
1773
1772
  data: {
@@ -1809,9 +1808,14 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1809
1808
  this.recordNativeToolOutcome(item);
1810
1809
  this.nativeToolLifecycleProjector.clearTerminalPresentationForNativeItem(item);
1811
1810
  if (itemId) {
1811
+ this.observedItemIds.add(itemId);
1812
1812
  this.activeItemIds.delete(itemId);
1813
1813
  this.completedItemIds.add(itemId);
1814
1814
  }
1815
+ if (item?.type === "contextCompaction" && itemId) {
1816
+ this.activeCompactionItemIds.delete(itemId);
1817
+ this.completedCompactionCount += 1;
1818
+ }
1815
1819
  if (!this.asyncDeliveryProjection.allows(item, true)) return;
1816
1820
  const asyncMessage = this.assistantProjection.recordItemCompleted(item, itemId, this.activeItemIds);
1817
1821
  if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
@@ -1821,8 +1825,6 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1821
1825
  if (this.projectionClosed) return;
1822
1826
  if (item?.type === "contextCompaction" && itemId) {
1823
1827
  if (!this.isCompactionProjectionActive()) return;
1824
- this.activeCompactionItemIds.delete(itemId);
1825
- this.completedCompactionCount += 1;
1826
1828
  await this.options.onContextCompacted?.();
1827
1829
  if (!this.isCompactionProjectionActive()) return;
1828
1830
  const messages = await this.toolTranscriptProjection.readMirroredSessionMessages(this.options.runAbortSignal);
@@ -1845,7 +1847,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1845
1847
  timestamp: this.transcriptCheckpoint.nextTimestamp()
1846
1848
  });
1847
1849
  if (!this.isCompactionProjectionActive()) return;
1848
- this.eventProjection.emitCompactionEnd(itemId, true);
1850
+ this.finishCompactionProgress(itemId, true);
1849
1851
  }
1850
1852
  this.toolProgressProjection.recordToolMeta(item);
1851
1853
  this.toolProgressProjection.rememberCommandAggregateOutputEcho(item);
@@ -1895,14 +1897,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1895
1897
  promptErrorSource: compactionFailure ? "compaction" : "prompt"
1896
1898
  });
1897
1899
  }
1898
- if (compactionFailure) {
1899
- const failedCompactionItemIds = [...this.activeCompactionItemIds];
1900
- for (const itemId of failedCompactionItemIds) {
1901
- this.activeItemIds.delete(itemId);
1902
- this.activeCompactionItemIds.delete(itemId);
1903
- this.eventProjection.emitCompactionEnd(itemId, false);
1904
- }
1905
- }
1900
+ this.closeCompactionProgress();
1906
1901
  const turnItems = turn.items;
1907
1902
  const unsettledAsyncDeliveries = this.asyncDeliveryProjection.pending();
1908
1903
  const lastToolItem = turnItems.findLast((item) => matchesCodexSnapshotTurn(item, this.turnId) && (item.type === "dynamicToolCall" || shouldClearTerminalPresentationForNativeItem(item)));
@@ -1940,7 +1935,6 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1940
1935
  }
1941
1936
  if (this.projectionClosed) return;
1942
1937
  this.assistantProjection.finalizeAnswerCandidate(turn);
1943
- this.activeCompactionItemIds.clear();
1944
1938
  await this.reasoningProjection.maybeEndReasoning();
1945
1939
  }
1946
1940
  async handleRawResponseItemCompleted(params) {
@@ -1965,9 +1959,6 @@ function readMcpAppResourceUri(item) {
1965
1959
  const uri = normalizeOptionalString(appContext?.resourceUri) ?? normalizeOptionalString(item.mcpAppResourceUri);
1966
1960
  return uri?.startsWith("ui://") ? uri : void 0;
1967
1961
  }
1968
- function readMcpAppConnectorId(item) {
1969
- return normalizeOptionalString(asOptionalRecord(item.appContext)?.connectorId);
1970
- }
1971
1962
  function readMcpToolResult(item) {
1972
1963
  const result = asOptionalRecord(item.result);
1973
1964
  if (!result || !Array.isArray(result.content)) return;
@@ -2071,7 +2062,7 @@ function createCodexNativeMcpAppResultDetailsPreparer(params) {
2071
2062
  const serverName = normalizeOptionalString(item.server);
2072
2063
  const toolName = normalizeOptionalString(item.tool);
2073
2064
  const uiResourceUri = readMcpAppResourceUri(item);
2074
- const connectorId = readMcpAppConnectorId(item);
2065
+ const connectorId = normalizeOptionalString(asOptionalRecord(item.appContext)?.connectorId);
2075
2066
  const toolResult = readMcpToolResult(item);
2076
2067
  if (!serverName || !toolName || !uiResourceUri || !toolResult) return;
2077
2068
  if (serverName === CODEX_APPS_MCP_SERVER && !connectorId) return;
@@ -2134,8 +2125,7 @@ function canonicalizeNativeProgressCardInput(input) {
2134
2125
  var CodexCompactionPlanState = class {
2135
2126
  record(event) {
2136
2127
  if (event.stream !== "plan") return;
2137
- const plan = readBoundedPlan(event.data.explanation, event.data.steps);
2138
- this.latestPlan = plan;
2128
+ this.latestPlan = readBoundedPlan(event.data.explanation, event.data.steps);
2139
2129
  }
2140
2130
  /** Retains markdown that migration-only plan events intentionally omit. */
2141
2131
  recordProgressCardInput(value) {
@@ -2194,7 +2184,7 @@ function truncateUtf8(value, maxBytes) {
2194
2184
  function readPlanSteps(value) {
2195
2185
  if (!Array.isArray(value)) return [];
2196
2186
  return value.flatMap((entry) => {
2197
- if (!entry || typeof entry !== "object" || Array.isArray(entry)) return [];
2187
+ if (!isJsonObject(entry)) return [];
2198
2188
  const { step, status } = entry;
2199
2189
  if (typeof step !== "string" || !isPlanStatus(status)) return [];
2200
2190
  return [{
@@ -2207,6 +2197,48 @@ function isPlanStatus(value) {
2207
2197
  return value === "pending" || value === "in_progress" || value === "completed";
2208
2198
  }
2209
2199
  //#endregion
2200
+ //#region extensions/codex/src/app-server/run-attempt-compaction.ts
2201
+ /** Restore host-owned context after native compaction rebuilds a live thread. */
2202
+ async function restoreCodexAttemptCompactionContext(resources) {
2203
+ const { state, prompt } = resources;
2204
+ const { runtime, attemptTools } = prompt.context;
2205
+ const { connection } = runtime;
2206
+ const { params, runAbortController } = connection;
2207
+ const { computerContextEpoch, compactionPlanState } = attemptTools;
2208
+ const { client, thread } = state;
2209
+ const assertCurrent = () => {
2210
+ params.hostCapabilities.assertActive();
2211
+ connection.assertCurrent();
2212
+ thread.liveThreadOwnership?.assertCurrent();
2213
+ if (state.thread !== thread || state.client !== client) throw new Error("Codex compaction thread ownership changed");
2214
+ };
2215
+ computerContextEpoch.value += 1;
2216
+ delete computerContextEpoch.frameToolCallId;
2217
+ delete computerContextEpoch.frameImageIdentity;
2218
+ try {
2219
+ await compactionPlanState.restore({
2220
+ client,
2221
+ threadId: thread.threadId,
2222
+ timeoutMs: connection.appServer.requestTimeoutMs,
2223
+ signal: runAbortController.signal
2224
+ });
2225
+ } catch (error) {
2226
+ embeddedAgentLog.warn("failed to restore Codex plan state after compaction", {
2227
+ runId: params.runId,
2228
+ threadId: thread.threadId,
2229
+ error: formatErrorMessage(error)
2230
+ });
2231
+ }
2232
+ thread.liveThreadEphemeralPolicy = await restoreCodexThreadSkillsCatalogAfterCompaction({
2233
+ client,
2234
+ threadId: thread.threadId,
2235
+ ephemeralPolicy: thread.liveThreadEphemeralPolicy,
2236
+ timeoutMs: connection.appServer.requestTimeoutMs,
2237
+ signal: runAbortController.signal,
2238
+ assertCurrent
2239
+ });
2240
+ }
2241
+ //#endregion
2210
2242
  //#region extensions/codex/src/app-server/user-input-bridge.ts
2211
2243
  /** Owns per-turn Codex request_user_input and ordinary MCP elicitation lifecycles. */
2212
2244
  const DEFAULT_USER_INPUT_TIMEOUT_MS = 9e5;
@@ -2262,10 +2294,13 @@ function createCodexUserInputBridge(params) {
2262
2294
  async handleRequest(request, requestSignal) {
2263
2295
  const requestParams = readUserInputParams(request.params);
2264
2296
  if (!requestParams || requestParams.threadId !== params.threadId || requestParams.turnId !== params.turnId) return;
2265
- if (requestParams.questions.length === 0) return emptyUserInputResponse();
2297
+ if (requestParams.questions.length === 0) return emptyAgentHarnessUserInputAnswers();
2266
2298
  const timeoutMs = requestParams.isBlocking ? params.paramsForRun.timeoutMs ?? DEFAULT_USER_INPUT_TIMEOUT_MS : NONBLOCKING_USER_INPUT_TIMEOUT_MS;
2267
- const input = compileUserInputQuestions(requestParams.questions);
2268
- const cancelValue = emptyUserInputResponse();
2299
+ const input = agentHarnessStructuredInput.compileQuestions({
2300
+ questions: requestParams.questions,
2301
+ intro: "Codex needs input:"
2302
+ });
2303
+ const cancelValue = emptyAgentHarnessUserInputAnswers();
2269
2304
  return await enqueue({
2270
2305
  cancelValue,
2271
2306
  failureValue: cancelValue,
@@ -2318,12 +2353,6 @@ function createCodexUserInputBridge(params) {
2318
2353
  }
2319
2354
  };
2320
2355
  }
2321
- function compileUserInputQuestions(questions) {
2322
- return agentHarnessStructuredInput.compileQuestions({
2323
- questions,
2324
- intro: "Codex needs input:"
2325
- });
2326
- }
2327
2356
  function readUserInputParams(value) {
2328
2357
  const snapshot = agentHarnessStructuredInput.snapshot(value);
2329
2358
  if (!agentHarnessStructuredInput.isRecord(snapshot)) return;
@@ -2399,9 +2428,6 @@ function readOwnDataString(value, key) {
2399
2428
  function gatewayAnswersToCodexResponse(answers) {
2400
2429
  return { answers: Object.fromEntries(Object.entries(answers).map(([questionId, values]) => [questionId, { answers: values }])) };
2401
2430
  }
2402
- function emptyUserInputResponse() {
2403
- return { ...emptyAgentHarnessUserInputAnswers() };
2404
- }
2405
2431
  function declineElicitation(message) {
2406
2432
  return createCodexElicitationResponse("decline", null, message ? { message } : null);
2407
2433
  }
@@ -2412,8 +2438,8 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2412
2438
  const { context, turnState } = prompt;
2413
2439
  const { runtime, attemptTools, hookContext } = context;
2414
2440
  const { connection } = runtime;
2415
- const { params, runAbortController, terminalState, abortExplicitly, abortFromUpstream, sessionAgentId, contextSessionKey, effectiveCwd } = connection;
2416
- const { dynamicToolParams, compactionPlanState, computerContextEpoch, toolBridge } = attemptTools;
2441
+ const { params, runAbortController, terminalState, abortExplicitly, cancellation, sessionAgentId, contextSessionKey, effectiveCwd } = connection;
2442
+ const { dynamicToolParams, toolBridge } = attemptTools;
2417
2443
  const { state, completion, userInputBridgeRef, steeringQueueRef, deadlines, noteProgress, completeTurn, interruptTurn } = turnRuntime;
2418
2444
  const { emitExecutionPhaseOnce, emitLifecycleStart, maybeAnnounceFastModeAutoOff } = lifecycle;
2419
2445
  const { enqueueNotification } = notifications;
@@ -2532,25 +2558,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2532
2558
  } } : {},
2533
2559
  ...prepareNativeMcpAppResultDetails ? { prepareNativeMcpAppResultDetails } : {},
2534
2560
  upstreamUserText,
2535
- onContextCompacted: async () => {
2536
- computerContextEpoch.value += 1;
2537
- delete computerContextEpoch.frameToolCallId;
2538
- delete computerContextEpoch.frameImageIdentity;
2539
- try {
2540
- await compactionPlanState.restore({
2541
- client: resourceState.client,
2542
- threadId: resourceState.thread.threadId,
2543
- timeoutMs: connection.appServer.requestTimeoutMs,
2544
- signal: runAbortController.signal
2545
- });
2546
- } catch (error) {
2547
- embeddedAgentLog.warn("failed to restore Codex plan state after compaction", {
2548
- runId: params.runId,
2549
- threadId: resourceState.thread.threadId,
2550
- error: formatErrorMessage(error)
2551
- });
2552
- }
2553
- }
2561
+ onContextCompacted: () => restoreCodexAttemptCompactionContext(resources)
2554
2562
  });
2555
2563
  const activeProjector = projectorRef.current;
2556
2564
  let activationFailed = false;
@@ -2558,7 +2566,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2558
2566
  state.abortCleanup = interruptTurn(activeTurnId).then(async (confirmed) => {
2559
2567
  if (!activationFailed && !terminalState.explicitCancellationObserved && !state.permissionChangeRestart && !state.timeout) return;
2560
2568
  if (!confirmed) throw new Error(state.permissionChangeRestart ? "Permission change could not confirm the previous Codex turn stopped." : "Codex cancellation could not confirm the turn stopped; background terminals may still be running.");
2561
- if (resources.nativeProcessAuthority) await resources.nativeProcessAuthority.cancelTurn(resourceState.client, resourceState.thread.threadId, activeTurnId);
2569
+ if (resources.nativeProcessAuthority?.requiresProcessAdmission) await resources.nativeProcessAuthority.cancelTurn(resourceState.client, resourceState.thread.threadId, activeTurnId);
2562
2570
  else await terminateCodexBackgroundTerminals(resourceState.client, resourceState.thread.threadId);
2563
2571
  if (state.permissionChangeRestart) state.permissionChangeRestart = "confirmed";
2564
2572
  });
@@ -2626,16 +2634,14 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2626
2634
  signal: runAbortController.signal,
2627
2635
  assertActive: assertSteeringActive,
2628
2636
  prepareMessage: async (text, options, assertMessageCurrent) => {
2629
- const attachmentNote = await prepareAgentWorkspaceAttachments({
2630
- workspaceDir: params.workspaceDir,
2637
+ const attachmentNote = await connection.prepareInputAttachments({
2638
+ maxChars: Math.max(0, CODEX_TURN_START_TEXT_INPUT_MAX_CHARS - text.length - 2),
2631
2639
  turn: {
2632
- config: params.config,
2633
2640
  media: options.media,
2634
- timeoutMs: params.timeoutMs,
2635
- abortSignal: runAbortController.signal,
2636
2641
  userTurnTranscriptRecorder: options.userTurnTranscriptRecorder
2637
2642
  },
2638
- assertCurrent: assertMessageCurrent
2643
+ assertCurrent: assertMessageCurrent,
2644
+ signal: runAbortController.signal
2639
2645
  });
2640
2646
  const result = await detectAndLoadAgentHarnessPromptImages({
2641
2647
  ...imageContext,
@@ -2796,11 +2802,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2796
2802
  cancel: () => abortExplicitly("cancelled"),
2797
2803
  abort: () => abortExplicitly("aborted")
2798
2804
  };
2799
- const freezeRunTerminalOutcome = () => {
2800
- if (terminalState.terminalOutcomeFrozen) return;
2801
- terminalState.terminalOutcomeFrozen = true;
2802
- params.abortSignal?.removeEventListener("abort", abortFromUpstream);
2803
- };
2805
+ const freezeRunTerminalOutcome = cancellation.freezeTerminalOutcome;
2804
2806
  const projectionReady = Promise.resolve().then(async () => {
2805
2807
  runAbortController.signal.addEventListener("abort", abortListener, { once: true });
2806
2808
  if (runAbortController.signal.aborted) abortListener();
@@ -2931,15 +2933,9 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2931
2933
  kind: "clear",
2932
2934
  threadId: resourceState.thread.threadId
2933
2935
  }) : true;
2934
- if (!retainLiveThread) {
2935
- if (bindingReleased) {
2936
- if (!await releaseThreadSubscription()) {
2937
- if (params.oneShotCliRun) await runCleanupStep("codex-one-shot-unsubscribe", async () => {
2938
- throw new Error("Codex one-shot thread unsubscribe was not confirmed");
2939
- });
2940
- }
2941
- }
2942
- }
2936
+ if (!retainLiveThread && bindingReleased && !await releaseThreadSubscription() && params.oneShotCliRun) await runCleanupStep("codex-one-shot-unsubscribe", async () => {
2937
+ throw new Error("Codex one-shot thread unsubscribe was not confirmed");
2938
+ });
2943
2939
  }
2944
2940
  } finally {
2945
2941
  if (resourceState.thread.liveThreadOwnership) await runCleanupStep("codex-unsettled-subscription", async () => {
@@ -2977,6 +2973,13 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2977
2973
  }
2978
2974
  //#endregion
2979
2975
  //#region extensions/codex/src/app-server/session-binding-scope.ts
2976
+ /** Both read and write projections must leave retained assignment facts unchanged. */
2977
+ function projectAssignmentOwner(assignment, owner) {
2978
+ return {
2979
+ ...assignment,
2980
+ owner
2981
+ };
2982
+ }
2980
2983
  /** Carries one prepared run identity through callers that rederive it from public params. */
2981
2984
  function scopeCodexRunBindingStore(params) {
2982
2985
  const mapSessionIdentity = (identity) => identity.agentId === params.logicalIdentity.agentId && identity.sessionId === params.logicalIdentity.sessionId && identity.sessionKey?.trim() === params.logicalIdentity.sessionKey?.trim() ? params.physicalIdentity : identity;
@@ -2993,9 +2996,17 @@ function scopeCodexRunBindingStore(params) {
2993
2996
  ...params.bindingStore,
2994
2997
  read: (identity) => params.bindingStore.read(mapIdentity(identity)),
2995
2998
  ...readMany ? { readMany: (identities) => readMany(identities.map(mapIdentity)) } : {},
2999
+ readNativeSubagentAssignments: (identity, owner) => (params.bindingStore.readNativeSubagentAssignments?.(mapIdentity(identity), mapHistoryOwner(identity, owner)) ?? []).map((assignment) => projectAssignmentOwner(assignment, {
3000
+ ...assignment.owner,
3001
+ sessionId: owner.sessionId
3002
+ })),
2996
3003
  readNativeSubagentSubmissions: (identity, owner) => params.bindingStore.readNativeSubagentSubmissions(mapIdentity(identity), mapHistoryOwner(identity, owner)),
2997
3004
  hasOtherThreadOwner: (threadId, identity) => params.bindingStore.hasOtherThreadOwner(threadId, identity ? mapIdentity(identity) : void 0),
2998
- mutate: (identity, mutation, assertCurrent) => params.bindingStore.mutate(mapIdentity(identity), mutation.kind === "record-native-subagent-submission" || mutation.kind === "consume-native-subagent-submission" ? {
3005
+ mutate: (identity, mutation, assertCurrent) => params.bindingStore.mutate(mapIdentity(identity), mutation.kind === "record-native-subagent-assignment" || mutation.kind === "consume-native-subagent-assignment" ? {
3006
+ ...mutation,
3007
+ owner: mapHistoryOwner(identity, mutation.owner),
3008
+ assignment: projectAssignmentOwner(mutation.assignment, mapHistoryOwner(identity, mutation.assignment.owner))
3009
+ } : mutation.kind === "record-native-subagent-submission" || mutation.kind === "consume-native-subagent-submission" ? {
2999
3010
  ...mutation,
3000
3011
  owner: mapHistoryOwner(identity, mutation.owner)
3001
3012
  } : mutation, assertCurrent),
@@ -3257,7 +3268,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3257
3268
  offAnnounced: false,
3258
3269
  resetAnnounced: false
3259
3270
  };
3260
- const preDynamicStartupStages = createCodexDynamicToolBuildStageTracker();
3271
+ const preDynamicStartupStages = createStageTimingTracker();
3261
3272
  const runtimeArtifactRequest = params.captureRuntimeArtifact || params.expectedRuntimeArtifact ? params.expectedRuntimeArtifact ? { expected: params.expectedRuntimeArtifact } : {} : void 0;
3262
3273
  const pluginConfig = readCodexPluginConfig(options.pluginConfig);
3263
3274
  const requirementsToml = readCodexRequirementsToml({});
@@ -3301,10 +3312,19 @@ async function prepareCodexAttemptConnection({ params, options }) {
3301
3312
  ...sandbox?.enabled || remoteExec ? void 0 : preparedEnvironment.localIdentityEnv,
3302
3313
  ...preparedEnvironment.localProcessEnv
3303
3314
  } : void 0;
3304
- const shellEnvironment = preparedShellEnvironment && Object.keys(preparedShellEnvironment).length > 0 ? preparedShellEnvironment : void 0;
3315
+ const baseShellEnvironment = preparedShellEnvironment && Object.keys(preparedShellEnvironment).length > 0 ? preparedShellEnvironment : void 0;
3305
3316
  const disableLoginShell = remoteExec || preparedEnvironment?.localProcessEnv !== void 0 || preparedEnvironment?.managedLocalIdentity === true || preparedEnvironment !== void 0 && Object.keys(preparedEnvironment.credentialScrubEnv).length > 0;
3317
+ let shellEnvironment = baseShellEnvironment;
3318
+ let shellPathPrepend;
3306
3319
  const withPreparedProcessEnv = (appServer) => {
3307
3320
  assertLocalTargetSupported(appServer.start.transport !== "stdio" || Boolean(appServer.remoteWorkspaceRoot));
3321
+ const localToolEnv = !sandbox?.enabled && !remoteExec && appServer.start.transport === "stdio" && !isCodexAppServerProxyLaunch(appServer.start.args) && !appServer.remoteWorkspaceRoot ? preparedEnvironment?.localToolEnv : void 0;
3322
+ const hasLocalToolEnv = localToolEnv && Object.keys(localToolEnv).length > 0;
3323
+ shellPathPrepend = hasLocalToolEnv ? preparedEnvironment?.localToolPathPrepend : void 0;
3324
+ shellEnvironment = hasLocalToolEnv ? {
3325
+ ...baseShellEnvironment,
3326
+ ...localToolEnv
3327
+ } : baseShellEnvironment;
3308
3328
  return shellEnvironment ? {
3309
3329
  ...appServer,
3310
3330
  start: {
@@ -3348,7 +3368,9 @@ async function prepareCodexAttemptConnection({ params, options }) {
3348
3368
  bindingIdentity = physicalIdentity;
3349
3369
  }
3350
3370
  }
3351
- const { binding: admittedBinding, assertCurrent } = await resolveCodexSessionBinding({
3371
+ let modelExecution;
3372
+ const assertModelExecutionCurrent = () => modelExecution?.assertCurrent();
3373
+ const { binding: admittedBinding, assertCurrent: assertBindingCurrent } = await resolveCodexSessionBinding({
3352
3374
  reclaimStale: true,
3353
3375
  bindingStore,
3354
3376
  identity: bindingIdentity,
@@ -3358,9 +3380,14 @@ async function prepareCodexAttemptConnection({ params, options }) {
3358
3380
  signal: params.abortSignal,
3359
3381
  assertBinding: params.expectedSessionRuntimeOwnership ? (binding) => assertCodexSessionRuntimeOwnership(binding, params.expectedSessionRuntimeOwnership) : void 0
3360
3382
  });
3383
+ const assertCurrent = () => {
3384
+ assertBindingCurrent();
3385
+ assertModelExecutionCurrent();
3386
+ };
3361
3387
  let startupBinding = admittedBinding;
3362
3388
  preDynamicStartupStages.mark("read-binding");
3363
3389
  const usesSupervisionConnection = startupBinding?.connectionScope === "supervision";
3390
+ if (usesSupervisionConnection && isCodexResponsesOAuthRun(params)) throw new Error("ChatGPT subscription sharing requires an OpenClaw-owned Codex session; detach from native supervision first.");
3364
3391
  if (usesSupervisionConnection) activeContextEngine = void 0;
3365
3392
  if (usesSupervisionConnection && pluginConfig.supervision?.enabled !== true) throw new Error("Codex supervision is disabled; refusing to open a native user-home supervised session");
3366
3393
  const resolveRuntimeOptionsForBinding = async (binding, selection) => (await resolveCodexBindingAppServerConnection({
@@ -3472,13 +3499,9 @@ async function prepareCodexAttemptConnection({ params, options }) {
3472
3499
  },
3473
3500
  agentDir
3474
3501
  });
3475
- return {
3476
- session,
3477
- appServer: withPreparedProcessEnv(trusted)
3478
- };
3502
+ return withPreparedProcessEnv(trusted);
3479
3503
  };
3480
- let resolvedAppServer = resolveFinalAppServer(configuredAppServer, reviewerPolicyContext);
3481
- let appServer = resolvedAppServer.appServer;
3504
+ let appServer = resolveFinalAppServer(configuredAppServer, reviewerPolicyContext);
3482
3505
  preDynamicStartupStages.mark("app-server-policy");
3483
3506
  preDynamicStartupStages.mark("native-hook-relay");
3484
3507
  const terminalState = {
@@ -3488,28 +3511,32 @@ async function prepareCodexAttemptConnection({ params, options }) {
3488
3511
  terminalOutcomeFrozen: false,
3489
3512
  sharedAbortAllowedAfterTerminalOutcome: false
3490
3513
  };
3491
- const runAbortController = new AbortController();
3492
- let attemptAbortNotified = false;
3493
- const notifyAttemptAbort = () => {
3494
- if (attemptAbortNotified) return;
3495
- attemptAbortNotified = true;
3496
- params.onAttemptAbort?.();
3497
- };
3498
- const abortExplicitly = (reason) => {
3499
- if (terminalState.terminalOutcomeFrozen) {
3500
- if (terminalState.sharedAbortAllowedAfterTerminalOutcome) notifyAttemptAbort();
3501
- return;
3502
- }
3503
- notifyAttemptAbort();
3504
- terminalState.explicitCancellationObserved = true;
3505
- terminalState.explicitCancellationReason ??= reason;
3506
- runAbortController.abort(reason);
3507
- };
3508
- const abortFromUpstream = () => {
3509
- abortExplicitly(params.abortSignal?.reason ?? "upstream_abort");
3514
+ const cancellation = createAgentHarnessAttemptCancellation({
3515
+ upstreamSignal: params.abortSignal,
3516
+ onAttemptAbort: () => params.onAttemptAbort?.(),
3517
+ state: terminalState
3518
+ });
3519
+ const { controller: runAbortController, abortExplicitly } = cancellation;
3520
+ let detachModelAbort;
3521
+ const releaseModelExecution = () => {
3522
+ detachModelAbort?.();
3523
+ detachModelAbort = void 0;
3524
+ modelExecution?.release();
3525
+ };
3526
+ const bindModelExecution = (model) => {
3527
+ assertCurrent();
3528
+ const bind = params.hostCapabilities.bindModelExecution;
3529
+ if (!bind) throw new Error("Codex inference requires host model execution authority.");
3530
+ const execution = bind(model);
3531
+ releaseModelExecution();
3532
+ modelExecution = execution;
3533
+ if (!execution) return;
3534
+ const abortModelExecution = () => abortExplicitly(execution.signal.reason);
3535
+ execution.signal.addEventListener("abort", abortModelExecution, { once: true });
3536
+ detachModelAbort = () => execution.signal.removeEventListener("abort", abortModelExecution);
3537
+ if (execution.signal.aborted) abortModelExecution();
3538
+ execution.assertCurrent();
3510
3539
  };
3511
- if (params.abortSignal?.aborted) abortFromUpstream();
3512
- else params.abortSignal?.addEventListener("abort", abortFromUpstream, { once: true });
3513
3540
  try {
3514
3541
  const startupBindingBeforeRotation = startupBinding;
3515
3542
  const startupBindingResolution = await rotateOversizedCodexAppServerStartupBinding({
@@ -3532,8 +3559,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3532
3559
  modelProvider: reviewerPolicyContext.modelProvider,
3533
3560
  model: reviewerPolicyContext.model
3534
3561
  });
3535
- resolvedAppServer = resolveFinalAppServer(configuredAppServer, reviewerPolicyContext);
3536
- appServer = resolvedAppServer.appServer;
3562
+ appServer = resolveFinalAppServer(configuredAppServer, reviewerPolicyContext);
3537
3563
  }
3538
3564
  const sessionPermissionPolicy = resolveCodexEffectiveSessionPermissionPolicy({
3539
3565
  appServer,
@@ -3556,11 +3582,44 @@ async function prepareCodexAttemptConnection({ params, options }) {
3556
3582
  pluginAppServer: appServer,
3557
3583
  continuityCalibration: startupBindingBeforeRotation?.continuityCalibration
3558
3584
  };
3559
- const resolveRuntimeOptionsForCurrentBinding = async (selection) => resolveFinalAppServer(await resolveRuntimeOptionsForBinding(mutable.startupBinding, selection), selection).appServer;
3585
+ const resolveRuntimeOptionsForCurrentBinding = async (selection) => resolveFinalAppServer(await resolveRuntimeOptionsForBinding(mutable.startupBinding, selection), selection);
3560
3586
  assertCurrent();
3561
3587
  return {
3562
3588
  params,
3589
+ prepareInputAttachments: async (request) => {
3590
+ const assertPreparationCurrent = () => {
3591
+ assertCurrent();
3592
+ request.signal?.throwIfAborted();
3593
+ request.assertCurrent();
3594
+ };
3595
+ assertPreparationCurrent();
3596
+ if (request.turn) {
3597
+ const remoteNote = await prepareAgentWorkspaceAttachments({
3598
+ workspaceDir: params.workspaceDir,
3599
+ turn: {
3600
+ ...request.turn,
3601
+ config: params.config,
3602
+ timeoutMs: params.timeoutMs,
3603
+ abortSignal: request.signal
3604
+ },
3605
+ assertCurrent: assertPreparationCurrent
3606
+ });
3607
+ assertPreparationCurrent();
3608
+ if (remoteNote) return remoteNote;
3609
+ }
3610
+ if (sandbox?.enabled || params.disableTools || params.toolsAllow?.length === 0 || params.toolExecutionAllow?.length === 0 || remoteExec || appServer.start.transport !== "stdio" || appServer.remoteWorkspaceRoot || params.permissionMode && params.permissionMode !== "full") return;
3611
+ const note = await params.hostCapabilities.prepareInputAttachments?.({
3612
+ ...request,
3613
+ placement: "local-host",
3614
+ assertCurrent: assertPreparationCurrent
3615
+ });
3616
+ assertPreparationCurrent();
3617
+ return note;
3618
+ },
3563
3619
  assertCurrent,
3620
+ assertModelExecutionCurrent,
3621
+ bindModelExecution,
3622
+ releaseModelExecution,
3564
3623
  options,
3565
3624
  attemptStartedAt,
3566
3625
  profilerEnabled,
@@ -3582,6 +3641,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3582
3641
  sandbox,
3583
3642
  agentDir,
3584
3643
  shellEnvironment,
3644
+ shellPathPrepend,
3585
3645
  disableLoginShell,
3586
3646
  bindingIdentity,
3587
3647
  bindingStore,
@@ -3600,7 +3660,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3600
3660
  runAbortController,
3601
3661
  terminalState,
3602
3662
  abortExplicitly,
3603
- abortFromUpstream,
3663
+ cancellation,
3604
3664
  resolveReviewerPolicyContext,
3605
3665
  resolveRuntimeOptionsForCurrentBinding,
3606
3666
  mutable,
@@ -3608,24 +3668,19 @@ async function prepareCodexAttemptConnection({ params, options }) {
3608
3668
  initialInactiveThreadBootstrapBindingForcedFreshStart
3609
3669
  };
3610
3670
  } catch (error) {
3611
- params.abortSignal?.removeEventListener("abort", abortFromUpstream);
3671
+ cancellation.dispose();
3672
+ releaseModelExecution();
3612
3673
  throw error;
3613
3674
  }
3614
3675
  }
3615
3676
  //#endregion
3616
3677
  //#region extensions/codex/src/app-server/attempt-context.ts
3617
- /**
3618
- * Builds Codex app-server prompt context,
3619
- * system-prompt reports, and context-engine projection decisions.
3620
- */
3621
- /** Reads mirrored Codex session history for harness hooks. */
3622
3678
  async function readMirroredSessionHistoryMessages(params) {
3623
3679
  const { admission, signal, contextTokenBudget, ...target } = params;
3624
3680
  const messages = await readCodexMirroredSessionHistoryMessages(target, admission, signal, contextTokenBudget);
3625
3681
  if (!messages) embeddedAgentLog.warn("failed to read mirrored session history for codex harness hooks", { sessionFile: params.sessionFile });
3626
3682
  return messages;
3627
3683
  }
3628
- /** Reads a valid thread-bootstrap projection request from context-engine output. */
3629
3684
  function readContextEngineThreadBootstrapProjection(projection) {
3630
3685
  if (projection?.mode !== "thread_bootstrap") return;
3631
3686
  const epoch = projection.epoch?.trim();
@@ -3640,10 +3695,6 @@ function readContextEngineThreadBootstrapProjection(projection) {
3640
3695
  ...fingerprint ? { fingerprint } : {}
3641
3696
  };
3642
3697
  }
3643
- /**
3644
- * Decides whether an existing Codex thread can reuse its context-engine
3645
- * bootstrap projection or must be reprojected.
3646
- */
3647
3698
  function resolveContextEngineBootstrapProjectionDecision(params) {
3648
3699
  const bindingProjection = params.startupBinding?.contextEngine?.projection;
3649
3700
  if (!params.startupBinding?.threadId || !bindingProjection) return {
@@ -3670,10 +3721,6 @@ function resolveContextEngineBootstrapProjectionDecision(params) {
3670
3721
  reason: "matching-thread-bootstrap-binding"
3671
3722
  };
3672
3723
  }
3673
- /**
3674
- * Builds the prompt-size, bootstrap-file, skill, and tool-schema accounting
3675
- * report for a Codex run.
3676
- */
3677
3724
  function buildCodexSystemPromptReport(params) {
3678
3725
  const toolEntries = flattenCodexDynamicToolFunctions(params.tools).map(buildCodexToolReportEntry);
3679
3726
  const schemaChars = toolEntries.reduce((sum, tool) => sum + tool.schemaChars, 0);
@@ -3718,26 +3765,22 @@ function buildCodexSystemPromptReport(params) {
3718
3765
  }
3719
3766
  function buildCodexSkillReportEntries(skillsPrompt) {
3720
3767
  if (!skillsPrompt) return [];
3721
- return Array.from(skillsPrompt.matchAll(/<skill>[\s\S]*?<\/skill>/gi)).map((match) => match[0] ?? "").map((block) => ({
3768
+ return Array.from(skillsPrompt.matchAll(/<skill>[\s\S]*?<\/skill>/gi), ([block]) => ({
3722
3769
  name: block.match(/<name>\s*([^<]+?)\s*<\/name>/i)?.[1]?.trim() || "(unknown)",
3723
3770
  blockChars: block.length
3724
- })).filter((entry) => entry.blockChars > 0);
3771
+ }));
3725
3772
  }
3726
3773
  function buildCodexToolReportEntry(tool) {
3727
3774
  const summary = tool.description.trim();
3728
- if (tool.deferLoading === true) return {
3729
- name: tool.name,
3730
- summaryChars: summary.length,
3731
- summaryHash: sha256Text(summary),
3732
- schemaChars: 0,
3733
- schemaHash: stableJsonHash(null),
3734
- propertiesCount: null
3735
- };
3736
3775
  return {
3737
3776
  name: tool.name,
3738
3777
  summaryChars: summary.length,
3739
3778
  summaryHash: sha256Text(summary),
3740
- ...buildCodexToolSchemaStats(tool.inputSchema)
3779
+ ...tool.deferLoading === true ? {
3780
+ schemaChars: 0,
3781
+ schemaHash: stableJsonHash(null),
3782
+ propertiesCount: null
3783
+ } : buildCodexToolSchemaStats(tool.inputSchema)
3741
3784
  };
3742
3785
  }
3743
3786
  function buildCodexToolSchemaStats(schema) {
@@ -3758,21 +3801,13 @@ function buildCodexToolSchemaStats(schema) {
3758
3801
  function sha256Text(value) {
3759
3802
  return createHash("sha256").update(value).digest("hex");
3760
3803
  }
3761
- function normalizeForStableHash(value) {
3762
- if (Array.isArray(value)) return value.map((entry) => normalizeForStableHash(entry));
3763
- if (value && typeof value === "object") {
3764
- const record = value;
3765
- return Object.fromEntries(Object.keys(record).toSorted((left, right) => left.localeCompare(right)).map((key) => [key, normalizeForStableHash(record[key])]));
3766
- }
3767
- return value;
3768
- }
3769
3804
  function stableJsonHash(value) {
3770
- return sha256Text(JSON.stringify(normalizeForStableHash(value)) ?? "null");
3805
+ return sha256Text(JSON.stringify(stabilizeJsonValue(value)) ?? "null");
3771
3806
  }
3772
3807
  function buildCodexBootstrapInjectionStats(params) {
3773
3808
  const injectedIndex = indexCodexContextFileContent(params.injectedFiles);
3774
3809
  const developerInstructionIndex = indexCodexContextFileContent(params.developerInstructionFiles ?? []);
3775
- const memoryToolRoutedPaths = new Set((params.memoryToolRoutedBootstrapFiles ?? []).map((file) => readNonBlankString(file.path)).filter(isNonEmptyString$1).map(normalizeCodexContextFilePath));
3810
+ const memoryToolRoutedPaths = new Set((params.memoryToolRoutedBootstrapFiles ?? []).map((file) => readNonBlankString(file.path)).filter(isNonEmptyString).map(normalizeCodexContextFilePath));
3776
3811
  return params.bootstrapFiles.map((file) => {
3777
3812
  const fileName = readNonBlankString(file.name);
3778
3813
  const pathValue = readNonBlankString(file.path) ?? fileName ?? "";
@@ -3819,28 +3854,19 @@ function indexCodexContextFileContent(files) {
3819
3854
  };
3820
3855
  }
3821
3856
  function readCodexIndexedContextFileContent(index, pathValue, fileName) {
3822
- const pathContent = index.byPath.get(pathValue);
3823
- if (pathContent !== void 0) return pathContent;
3824
- if (fileName) {
3825
- const nameContent = index.byPath.get(fileName);
3826
- if (nameContent !== void 0) return nameContent;
3827
- }
3828
3857
  const baseName = getCodexContextFileBasename(fileName ?? pathValue);
3829
- return baseName ? index.byBaseName.get(baseName) : void 0;
3858
+ return index.byPath.get(pathValue) ?? (fileName ? index.byPath.get(fileName) : void 0) ?? (baseName ? index.byBaseName.get(baseName) : void 0);
3830
3859
  }
3831
3860
  function readPositiveNumber(value) {
3832
3861
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : void 0;
3833
3862
  }
3834
- /**
3835
- * Builds OpenClaw-provided workspace prompt context for the current Codex turn.
3836
- */
3837
3863
  function buildCodexOpenClawPromptContext(params) {
3838
- if (!shouldInjectCodexOpenClawPromptContext(params.params)) return;
3864
+ if (!shouldIncludeAgentHarnessRuntimeContext(params.params)) return;
3839
3865
  const sections = [params.workspacePromptContext?.trim() ? [
3840
3866
  "## OpenClaw Workspace Context",
3841
3867
  "",
3842
3868
  params.workspacePromptContext.trim()
3843
- ].join("\n") : void 0, params.watchedSessionsContext?.trim() || void 0].filter(isNonEmptyString$1);
3869
+ ].join("\n") : void 0, params.watchedSessionsContext?.trim() || void 0].filter(isNonEmptyString);
3844
3870
  if (sections.length === 0) return;
3845
3871
  return [
3846
3872
  "OpenClaw runtime context for this turn:",
@@ -3856,7 +3882,7 @@ function buildCodexOpenClawPromptContext(params) {
3856
3882
  * keep refusing cross-session questions (openclaw#114797).
3857
3883
  */
3858
3884
  function buildCodexWatchedSessionsContext(params) {
3859
- if (!shouldInjectCodexOpenClawPromptContext(params.attempt)) return;
3885
+ if (!shouldIncludeAgentHarnessRuntimeContext(params.attempt)) return;
3860
3886
  return buildWatchedSessionsHarnessContext({
3861
3887
  config: params.attempt.config,
3862
3888
  sessionKey: params.sessionKey,
@@ -3864,9 +3890,8 @@ function buildCodexWatchedSessionsContext(params) {
3864
3890
  toolNames: flattenCodexDynamicToolFunctions(params.dynamicTools).map((tool) => normalizeCodexDynamicToolName(tool.name))
3865
3891
  });
3866
3892
  }
3867
- /** Renders loaded OpenClaw skill prompts as Codex collaboration instructions. */
3868
- function renderCodexSkillsCollaborationInstructions(params) {
3869
- if (!shouldInjectCodexOpenClawPromptContext(params.attempt)) return;
3893
+ function renderCodexSkillsInstructions(params) {
3894
+ if (!shouldIncludeAgentHarnessRuntimeContext(params.attempt)) return;
3870
3895
  return params.skillsPrompt?.trim() ? [
3871
3896
  "## OpenClaw Skills",
3872
3897
  "",
@@ -3921,59 +3946,15 @@ function splitLeadingCodexDeliveryHint(prompt) {
3921
3946
  };
3922
3947
  }
3923
3948
  //#endregion
3924
- //#region extensions/codex/src/app-server/run-attempt-state.ts
3925
- async function clearCodexBindingAfterInvalidImagePayload(bindingStore, identity, fields, expected) {
3926
- const currentBinding = bindingStore.read(identity);
3927
- const expectedThreadId = fields.threadId ?? currentBinding?.threadId;
3928
- if (!expectedThreadId) return;
3929
- if (currentBinding && currentBinding.threadId !== expectedThreadId) {
3930
- embeddedAgentLog.warn("codex app-server image payload error detected for unbound thread; preserving thread binding", {
3931
- ...fields,
3932
- boundThreadId: currentBinding.threadId
3933
- });
3934
- return;
3935
- }
3936
- if (expected || currentBinding?.connectionScope === "supervision") {
3937
- embeddedAgentLog.warn("codex app-server image payload error detected for native-owned thread; preserving binding", fields);
3938
- return;
3939
- }
3940
- embeddedAgentLog.warn("codex app-server image payload error detected; clearing thread binding", fields);
3941
- await bindingStore.mutate(identity, {
3942
- kind: "clear",
3943
- threadId: expectedThreadId
3944
- });
3945
- }
3946
- function isNonEmptyString(value) {
3947
- return typeof value === "string" && value.length > 0;
3948
- }
3949
- function shouldUseFreshCodexThreadAfterContextEngineOverflow(params) {
3950
- if (!params.contextEngineActive || params.thread.lifecycle.action !== "resumed") return false;
3951
- const message = formatErrorMessage(params.error);
3952
- return /ran out of room in the model'?s context window/iu.test(message) || /context window/iu.test(message) || /context length/iu.test(message) || /maximum context/iu.test(message) || /too many tokens/iu.test(message);
3953
- }
3954
- function isCodexActiveCompactTurnError(error) {
3955
- if (!(error instanceof CodexAppServerRpcError)) return false;
3956
- const data = isJsonObject(error.data) ? error.data : void 0;
3957
- const codexErrorInfo = isJsonObject(data?.codexErrorInfo) ? data.codexErrorInfo : void 0;
3958
- return (isJsonObject(codexErrorInfo?.activeTurnNotSteerable) ? codexErrorInfo.activeTurnNotSteerable : void 0)?.turnKind === "compact";
3959
- }
3960
- function joinPresentSections(...sections) {
3961
- return sections.filter((section) => Boolean(section?.trim())).join("\n\n");
3962
- }
3963
- function prependCurrentInboundContext(prompt, context) {
3964
- const text = context?.text.trim();
3965
- return text ? [neutralizeCodexExplicitMentionSigils(text), prompt].filter(Boolean).join("\n\n") : prompt;
3966
- }
3967
- //#endregion
3968
3949
  //#region extensions/codex/src/app-server/run-attempt-context.ts
3969
3950
  async function prepareCodexAttemptContext(runtime, attemptTools) {
3970
- const { connection, runtimeParams, activeSessionId, activeSessionFile, buildActiveRunAttemptParams, effectiveContextWindowInfo, effectiveContextTokenBudget, effectiveRuntimeProviderId, effectiveRuntimeModelId, hookChannelId } = runtime;
3951
+ const { connection, runtimeParams, effectiveContextWindowInfo, effectiveContextTokenBudget, effectiveRuntimeProviderId, effectiveRuntimeModelId, hookChannelId } = runtime;
3971
3952
  const { params, sessionAgentId, contextSessionKey, activeContextEngine, initialStartupBindingHadInactiveThreadBootstrap, effectiveWorkspace, effectiveCwd, agentDir, usesSupervisionConnection, resolvedWorkspace, initialInactiveThreadBootstrapBindingForcedFreshStart, sandbox } = connection;
3972
3953
  const { toolBridge } = attemptTools;
3973
3954
  const activeTranscriptTarget = {
3974
3955
  agentId: sessionAgentId,
3975
- sessionFile: activeSessionFile,
3976
- sessionId: activeSessionId,
3956
+ sessionFile: runtimeParams.sessionFile,
3957
+ sessionId: runtimeParams.sessionId,
3977
3958
  sessionKey: contextSessionKey,
3978
3959
  sessionTarget: params.sessionTarget
3979
3960
  };
@@ -4022,7 +4003,7 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
4022
4003
  };
4023
4004
  const hookRunner = getAgentHarnessHookRunner();
4024
4005
  const buildActiveContextEngineRuntimeContext = () => buildHarnessContextEngineRuntimeContext({
4025
- attempt: buildActiveRunAttemptParams(),
4006
+ attempt: { ...runtimeParams },
4026
4007
  workspaceDir: effectiveWorkspace,
4027
4008
  cwd: effectiveCwd,
4028
4009
  agentDir,
@@ -4034,9 +4015,9 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
4034
4015
  await bootstrapHarnessContextEngine({
4035
4016
  hadSessionFile: hadSessionTranscriptState,
4036
4017
  contextEngine: activeContextEngine,
4037
- sessionId: activeSessionId,
4018
+ sessionId: runtimeParams.sessionId,
4038
4019
  sessionKey: contextSessionKey,
4039
- sessionFile: activeSessionFile,
4020
+ sessionFile: runtimeParams.sessionFile,
4040
4021
  sessionTarget: params.sessionTarget,
4041
4022
  runtimeContext: buildActiveContextEngineRuntimeContext(),
4042
4023
  transcriptReadFence: params.userTurnTranscriptRecorder?.getAdmissionReceipt(),
@@ -4053,7 +4034,6 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
4053
4034
  historyState.messages = await readFencedHistory() ?? historyState.messages;
4054
4035
  }
4055
4036
  historyState.messages.push(...params.pluginRuntimeRefreshMessages ?? []);
4056
- const memoryToolNames = getCodexWorkspaceMemoryToolNames(toolBridge.availableSpecs);
4057
4037
  const workspaceBootstrapContext = await buildCodexWorkspaceBootstrapContext({
4058
4038
  params: runtimeParams,
4059
4039
  agentWorkspaceDeveloperInstructions: connection.mutable.startupBinding?.agentWorkspaceDeveloperInstructions,
@@ -4062,11 +4042,15 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
4062
4042
  effectiveWorkspace,
4063
4043
  sessionKey: contextSessionKey,
4064
4044
  sessionAgentId,
4065
- memoryToolNames,
4045
+ tools: toolBridge.availableSpecs,
4066
4046
  ringZeroActive: isHostScopedAgentToolActive("openclaw") && isSystemAgentOnlyCodexDynamicToolAllowlist(runtimeParams.toolsAllow),
4067
4047
  sandboxed: sandbox?.enabled === true
4068
4048
  });
4069
4049
  const agentWorkspaceDeveloperInstructions = workspaceBootstrapContext.threadDeveloperInstructions;
4050
+ const skillsInstructions = renderCodexSkillsInstructions({
4051
+ attempt: runtimeParams,
4052
+ skillsPrompt: params.skillsSnapshot?.prompt
4053
+ });
4070
4054
  const baseDeveloperInstructions = joinPresentSections(buildDeveloperInstructions(runtimeParams, { dynamicTools: toolBridge.availableSpecs }), agentWorkspaceDeveloperInstructions);
4071
4055
  const watchedSessionsContext = buildCodexWatchedSessionsContext({
4072
4056
  attempt: runtimeParams,
@@ -4092,25 +4076,18 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
4092
4076
  agentWorkspaceDeveloperInstructions,
4093
4077
  baseDeveloperInstructions,
4094
4078
  buildOpenClawPromptContext,
4095
- skillsCollaborationInstructions: renderCodexSkillsCollaborationInstructions({
4096
- attempt: runtimeParams,
4097
- skillsPrompt: params.skillsSnapshot?.prompt
4098
- }),
4079
+ skillsInstructions,
4099
4080
  promptState: {
4100
4081
  promptText: params.prompt,
4101
4082
  promptContextRange: void 0,
4102
4083
  developerInstructions: baseDeveloperInstructions,
4103
- prePromptMessageCount: historyState.messages.length,
4104
4084
  contextEngineProjection: void 0,
4105
4085
  precomputedStaleBindingContinuityProjectionApplied: false,
4106
4086
  staleBindingContinuityForcedFreshStart: false,
4107
4087
  noEngineContinuityProjectionApplied: false,
4108
4088
  inactiveThreadBootstrapBindingForcedFreshStart: initialInactiveThreadBootstrapBindingForcedFreshStart
4109
4089
  },
4110
- codexContextProjectionMaxChars: resolveCodexContextEngineProjectionMaxChars({
4111
- contextTokenBudget: effectiveContextTokenBudget,
4112
- reserveTokens: resolveCodexContextEngineProjectionReserveTokens()
4113
- }),
4090
+ codexContextProjectionMaxChars: resolveCodexContextEngineProjectionMaxChars({ contextTokenBudget: effectiveContextTokenBudget }),
4114
4091
  codexContinuityProjectionMaxChars: resolveCodexContinuityProjectionMaxChars({
4115
4092
  contextTokenBudget: effectiveContextTokenBudget,
4116
4093
  calibration: connection.mutable.continuityCalibration
@@ -4119,23 +4096,6 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
4119
4096
  }
4120
4097
  //#endregion
4121
4098
  //#region extensions/codex/src/app-server/attempt-diagnostics.ts
4122
- /**
4123
- * Diagnostic helpers for Codex app-server model calls and plugin-thread config
4124
- * eligibility.
4125
- */
4126
- /** Reads a tool schema field in either app-server or OpenClaw naming. */
4127
- function readCodexDiagnosticToolParameters(tool) {
4128
- return tool.inputSchema ?? tool.parameters;
4129
- }
4130
- /** Builds compact diagnostic tool definitions for trusted private telemetry. */
4131
- function buildCodexDiagnosticToolDefinitions(tools) {
4132
- return tools.map((tool) => ({
4133
- name: tool.name,
4134
- description: tool.description,
4135
- parameters: readCodexDiagnosticToolParameters(tool)
4136
- }));
4137
- }
4138
- /** Returns the serialized UTF-8 byte length for a JSON-compatible value. */
4139
4099
  function utf8JsonByteLength(value) {
4140
4100
  try {
4141
4101
  return Buffer.byteLength(JSON.stringify(value), "utf8");
@@ -4143,7 +4103,6 @@ function utf8JsonByteLength(value) {
4143
4103
  return;
4144
4104
  }
4145
4105
  }
4146
- /** Builds a short namespaced fingerprint for sensitive log values. */
4147
4106
  function fingerprintCodexLogValue(namespace, value) {
4148
4107
  const hash = createHash("sha256");
4149
4108
  hash.update(namespace);
@@ -4151,10 +4110,6 @@ function fingerprintCodexLogValue(namespace, value) {
4151
4110
  hash.update(value);
4152
4111
  return `sha256:${hash.digest("hex").slice(0, 16)}`;
4153
4112
  }
4154
- /**
4155
- * Builds redacted diagnostics explaining whether plugin thread config was
4156
- * eligible for a Codex app-server attempt.
4157
- */
4158
4113
  function buildCodexPluginThreadConfigEligibilityLogData(params) {
4159
4114
  return {
4160
4115
  sessionId: params.sessionId,
@@ -4171,27 +4126,38 @@ function buildCodexPluginThreadConfigEligibilityLogData(params) {
4171
4126
  appServerCommandSource: params.appServer.start.commandSource
4172
4127
  };
4173
4128
  }
4174
- /**
4175
- * Creates lifecycle emitters for trusted model-call diagnostics with optional
4176
- * private payload capture.
4177
- */
4178
4129
  function createCodexModelCallDiagnosticEmitter(params) {
4179
4130
  const now = params.now ?? (() => Date.now());
4180
- const toolDefinitions = params.capture.toolDefinitions ? buildCodexDiagnosticToolDefinitions(params.tools) : void 0;
4131
+ const toolDefinitions = params.capture.toolDefinitions ? params.tools.map((tool) => ({
4132
+ name: tool.name,
4133
+ description: tool.description,
4134
+ parameters: tool.inputSchema ?? tool.parameters
4135
+ })) : void 0;
4181
4136
  let startedAt = now();
4182
4137
  let started = false;
4183
4138
  let terminalEmitted = false;
4184
4139
  let requestPayloadBytes;
4185
4140
  const privateData = (modelContent) => modelContent && Object.keys(modelContent).length > 0 ? { modelContent } : void 0;
4186
- const buildContent = () => {
4187
- const modelContent = {
4188
- ...params.capture.inputMessages ? { inputMessages: params.buildInputMessages() } : {},
4189
- ...params.capture.systemPrompt ? { systemPrompt: params.buildSystemPrompt() } : {},
4190
- ...toolDefinitions ? { toolDefinitions } : {}
4191
- };
4192
- return Object.keys(modelContent).length > 0 ? modelContent : void 0;
4141
+ const buildContent = () => ({
4142
+ ...params.capture.inputMessages ? { inputMessages: params.buildInputMessages() } : {},
4143
+ ...params.capture.systemPrompt ? { systemPrompt: params.buildSystemPrompt() } : {},
4144
+ ...toolDefinitions ? { toolDefinitions } : {}
4145
+ });
4146
+ const emitTerminal = (type, outputMessages, fields = {}) => {
4147
+ if (!started || terminalEmitted) return false;
4148
+ terminalEmitted = true;
4149
+ emitTrustedDiagnosticEventWithPrivateData({
4150
+ type,
4151
+ ...params.baseFields,
4152
+ durationMs: Math.max(0, now() - startedAt),
4153
+ ...fields,
4154
+ ...requestPayloadBytes !== void 0 ? { requestPayloadBytes } : {}
4155
+ }, privateData({
4156
+ ...buildContent(),
4157
+ ...params.capture.outputMessages ? { outputMessages } : {}
4158
+ }));
4159
+ return true;
4193
4160
  };
4194
- const requestPayloadBytesField = () => requestPayloadBytes !== void 0 ? { requestPayloadBytes } : {};
4195
4161
  return {
4196
4162
  setRequestPayloadBytes(bytes) {
4197
4163
  requestPayloadBytes = bytes;
@@ -4205,37 +4171,16 @@ function createCodexModelCallDiagnosticEmitter(params) {
4205
4171
  }, privateData(buildContent()));
4206
4172
  },
4207
4173
  emitCompleted(result) {
4208
- if (!started || terminalEmitted) return;
4209
- terminalEmitted = true;
4210
- emitTrustedDiagnosticEventWithPrivateData({
4211
- type: "model.call.completed",
4212
- ...params.baseFields,
4213
- durationMs: Math.max(0, now() - startedAt),
4214
- ...requestPayloadBytesField()
4215
- }, privateData({
4216
- ...buildContent(),
4217
- ...params.capture.outputMessages ? { outputMessages: result.lastAssistant ? [result.lastAssistant] : result.assistantTexts } : {}
4218
- }));
4174
+ emitTerminal("model.call.completed", result.lastAssistant ? [result.lastAssistant] : result.assistantTexts);
4219
4175
  },
4220
4176
  emitError(error, fields = {}) {
4221
- if (!started || terminalEmitted) return;
4222
- terminalEmitted = true;
4223
- emitTrustedDiagnosticEventWithPrivateData({
4224
- type: "model.call.error",
4225
- ...params.baseFields,
4226
- durationMs: Math.max(0, now() - startedAt),
4177
+ if (emitTerminal("model.call.error", [], {
4227
4178
  errorCategory: fields.failureKind ?? "error",
4228
- ...fields.failureKind ? { failureKind: fields.failureKind } : {},
4229
- ...requestPayloadBytesField()
4230
- }, privateData({
4231
- ...buildContent(),
4232
- ...params.capture.outputMessages ? { outputMessages: [] } : {}
4233
- }));
4234
- params.onErrorDiagnostic?.(error);
4179
+ ...fields.failureKind ? { failureKind: fields.failureKind } : {}
4180
+ })) params.onErrorDiagnostic?.(error);
4235
4181
  }
4236
4182
  };
4237
4183
  }
4238
- /** Classifies model-call failures into timeout/abort buckets for diagnostics. */
4239
4184
  function classifyCodexModelCallFailureKind(params) {
4240
4185
  if (params.timedOut) return "timeout";
4241
4186
  const errorMessage = params.error ? params.formatError(params.error).toLowerCase() : "";
@@ -4245,7 +4190,6 @@ function classifyCodexModelCallFailureKind(params) {
4245
4190
  }
4246
4191
  //#endregion
4247
4192
  //#region extensions/codex/src/app-server/attempt-results.ts
4248
- /** Joins terminal assistant text blocks into the final attempt answer. */
4249
4193
  function collectTerminalAssistantText(result) {
4250
4194
  return result.assistantTexts.join("\n\n").trim();
4251
4195
  }
@@ -4258,14 +4202,12 @@ function buildCodexAppServerPromptTimeoutOutcome(timeout) {
4258
4202
  livenessState: "abandoned"
4259
4203
  };
4260
4204
  }
4261
- /** Explains why an incomplete app-server turn cannot be safely replayed. */
4262
4205
  function resolveCodexAppServerReplayBlockedReason(result) {
4263
4206
  if (result.replayMetadata.hadPotentialSideEffects) return "potential_side_effect";
4264
4207
  if (result.assistantTexts.some((text) => text.trim().length > 0)) return "assistant_output";
4265
4208
  if (result.toolMetas.length > 0 || result.clientToolCalls || result.lastToolError || result.didSendDeterministicApprovalPrompt) return "tool_activity";
4266
4209
  if (result.itemLifecycle.startedCount > 0 || result.itemLifecycle.activeCount > 0) return "active_item";
4267
4210
  }
4268
- /** Builds an attempt result for failures before the app-server turn starts. */
4269
4211
  function buildCodexTurnStartFailureResult(params) {
4270
4212
  return {
4271
4213
  terminal: attemptTerminal.normalize({
@@ -4296,7 +4238,6 @@ function buildCodexTurnStartFailureResult(params) {
4296
4238
  systemPromptReport: params.systemPromptReport
4297
4239
  };
4298
4240
  }
4299
- /** Detects app-server errors caused by invalid image payload data. */
4300
4241
  function isInvalidCodexImagePayloadError(message) {
4301
4242
  if (typeof message !== "string" || !message.trim()) return false;
4302
4243
  const normalizedMessage = message.replace(/[_-]+/gu, " ");
@@ -4325,37 +4266,150 @@ async function settleReplyMedia(activeTurn, result, { state, settlementExpired }
4325
4266
  if (signal.aborted) await state.abortCleanup;
4326
4267
  }
4327
4268
  //#endregion
4328
- //#region extensions/codex/src/app-server/trajectory.ts
4329
- /** Creates a trajectory recorder when the host exposes its capture capability. */
4330
- function createCodexTrajectoryRecorder(params) {
4331
- if (!params.trajectory) return null;
4332
- const trajectory = params.trajectory;
4333
- return {
4334
- recordEvent: (type, data) => {
4335
- try {
4336
- trajectory.recordEvent(type, data);
4337
- } catch {}
4338
- },
4339
- flush: trajectory.flush
4269
+ //#region extensions/codex/src/app-server/run-attempt-settlement.ts
4270
+ async function beginCodexAttemptSettlement(resources, turnRuntime, notifications, activeTurn) {
4271
+ const { state: resourceState } = resources;
4272
+ const { connection } = resources.prompt.context.runtime;
4273
+ const { params, runAbortController, appServer } = connection;
4274
+ const { state, deadlines, settlementExpired } = turnRuntime;
4275
+ const { drainNotificationQueue } = notifications;
4276
+ const { activeProjector, activeTurnId } = activeTurn;
4277
+ const drainGraceElapsed = createDeferred();
4278
+ let settlementPhase = "active";
4279
+ let drainGraceTimer;
4280
+ const beginDrainGrace = () => {
4281
+ if (settlementPhase !== "active" || drainGraceTimer) return;
4282
+ drainGraceTimer = setTimeout(() => {
4283
+ settlementPhase = "expired";
4284
+ drainGraceElapsed.resolve();
4285
+ }, TURN_FINALIZE_DRAIN_ABORT_GRACE_MS);
4286
+ drainGraceTimer.unref?.();
4340
4287
  };
4341
- }
4342
- /** Records compiled prompt/tool context at the start of a Codex runtime attempt. */
4343
- function recordCodexTrajectoryContext(recorder, params) {
4344
- if (!recorder) return;
4345
- recorder.recordEvent("context.compiled", {
4346
- systemPrompt: params.developerInstructions,
4347
- prompt: params.prompt ?? params.attempt.prompt,
4348
- imagesCount: params.attempt.images?.length ?? 0,
4349
- tools: toTrajectoryToolDefinitions(params.tools)
4288
+ const abortListener = addAbortListener(runAbortController.signal, () => {
4289
+ state.abortCleanup.then(beginDrainGrace, beginDrainGrace);
4350
4290
  });
4291
+ const closeProjection = () => {
4292
+ state.projectionClosed = true;
4293
+ return activeProjector.closeProjection();
4294
+ };
4295
+ const closeSettlement = () => {
4296
+ if (settlementPhase === "closed") return;
4297
+ settlementPhase = "closed";
4298
+ abortListener[Symbol.dispose]();
4299
+ clearTimeout(drainGraceTimer);
4300
+ deadlines.dispose();
4301
+ };
4302
+ if (state.pluginRuntimeRefreshStop) await state.pluginRuntimeRefreshStop.catch(() => void 0);
4303
+ let readRetainedNativeCommands;
4304
+ return {
4305
+ settlement: drainNotificationQueue().then(async () => {
4306
+ const commands = activeProjector.getPendingNativeCommands();
4307
+ if (commands.size > 0 && !params.oneShotCliRun && !state.pluginRuntimeRefreshStop) {
4308
+ try {
4309
+ const readCurrent = await readCodexRetainedBackgroundCommands({
4310
+ client: resourceState.client,
4311
+ threadId: resourceState.thread.threadId,
4312
+ turnId: activeTurnId,
4313
+ commands,
4314
+ authority: resources.nativeProcessAuthority,
4315
+ assertCurrent: connection.assertCurrent,
4316
+ signal: runAbortController.signal,
4317
+ timeoutMs: appServer.requestTimeoutMs
4318
+ });
4319
+ readRetainedNativeCommands = () => {
4320
+ try {
4321
+ return readCurrent();
4322
+ } catch {
4323
+ return /* @__PURE__ */ new Map();
4324
+ }
4325
+ };
4326
+ } catch (error) {
4327
+ embeddedAgentLog.debug("could not confirm retained native commands", {
4328
+ threadId: resourceState.thread.threadId,
4329
+ error: formatErrorMessage(error)
4330
+ });
4331
+ }
4332
+ await drainNotificationQueue();
4333
+ }
4334
+ await closeProjection();
4335
+ await activeProjector.settlement.drain();
4336
+ }),
4337
+ degradedSettlement: settlementExpired.then(() => {
4338
+ beginDrainGrace();
4339
+ }),
4340
+ drainGraceElapsed,
4341
+ closeProjection,
4342
+ closeSettlement,
4343
+ isActive: () => settlementPhase === "active",
4344
+ readRetainedNativeCommands: () => readRetainedNativeCommands?.() ?? /* @__PURE__ */ new Map()
4345
+ };
4351
4346
  }
4352
- /** Records final Codex model completion metadata and assistant snapshots. */
4353
- function recordCodexTrajectoryCompletion(recorder, params) {
4354
- if (!recorder) return;
4355
- const terminal = attemptTerminal.project(params.result.terminal);
4356
- recorder.recordEvent("model.completed", {
4357
- threadId: params.threadId,
4358
- turnId: params.turnId,
4347
+ //#endregion
4348
+ //#region extensions/codex/src/app-server/run-attempt-state.ts
4349
+ async function clearCodexBindingAfterInvalidImagePayload(bindingStore, identity, fields, expected) {
4350
+ const currentBinding = bindingStore.read(identity);
4351
+ const expectedThreadId = fields.threadId ?? currentBinding?.threadId;
4352
+ if (!expectedThreadId) return;
4353
+ if (currentBinding && currentBinding.threadId !== expectedThreadId) {
4354
+ embeddedAgentLog.warn("codex app-server image payload error detected for unbound thread; preserving thread binding", {
4355
+ ...fields,
4356
+ boundThreadId: currentBinding.threadId
4357
+ });
4358
+ return;
4359
+ }
4360
+ if (expected || currentBinding?.connectionScope === "supervision") {
4361
+ embeddedAgentLog.warn("codex app-server image payload error detected for native-owned thread; preserving binding", fields);
4362
+ return;
4363
+ }
4364
+ embeddedAgentLog.warn("codex app-server image payload error detected; clearing thread binding", fields);
4365
+ await bindingStore.mutate(identity, {
4366
+ kind: "clear",
4367
+ threadId: expectedThreadId
4368
+ });
4369
+ }
4370
+ function shouldUseFreshCodexThreadAfterContextEngineOverflow(params) {
4371
+ if (!params.contextEngineActive || params.thread.lifecycle.action !== "resumed") return false;
4372
+ return /context (?:window|length)|maximum context|too many tokens/iu.test(formatErrorMessage(params.error));
4373
+ }
4374
+ function isCodexActiveCompactTurnError(error) {
4375
+ if (!(error instanceof CodexAppServerRpcError)) return false;
4376
+ const data = isJsonObject(error.data) ? error.data : void 0;
4377
+ const codexErrorInfo = isJsonObject(data?.codexErrorInfo) ? data.codexErrorInfo : void 0;
4378
+ return (isJsonObject(codexErrorInfo?.activeTurnNotSteerable) ? codexErrorInfo.activeTurnNotSteerable : void 0)?.turnKind === "compact";
4379
+ }
4380
+ function prependCurrentInboundContext(prompt, context) {
4381
+ const text = context?.text.trim();
4382
+ return text ? [neutralizeCodexExplicitMentionSigils(text), prompt].filter(Boolean).join("\n\n") : prompt;
4383
+ }
4384
+ //#endregion
4385
+ //#region extensions/codex/src/app-server/trajectory.ts
4386
+ function createCodexTrajectoryRecorder(params) {
4387
+ if (!params.trajectory) return null;
4388
+ const trajectory = params.trajectory;
4389
+ return {
4390
+ recordEvent: (type, data) => {
4391
+ try {
4392
+ trajectory.recordEvent(type, data);
4393
+ } catch {}
4394
+ },
4395
+ flush: trajectory.flush
4396
+ };
4397
+ }
4398
+ function recordCodexTrajectoryContext(recorder, params) {
4399
+ if (!recorder) return;
4400
+ recorder.recordEvent("context.compiled", {
4401
+ systemPrompt: params.developerInstructions,
4402
+ prompt: params.prompt ?? params.attempt.prompt,
4403
+ imagesCount: params.attempt.images?.length ?? 0,
4404
+ tools: toTrajectoryToolDefinitions(params.tools)
4405
+ });
4406
+ }
4407
+ function recordCodexTrajectoryCompletion(recorder, params) {
4408
+ if (!recorder) return;
4409
+ const terminal = attemptTerminal.project(params.result.terminal);
4410
+ recorder.recordEvent("model.completed", {
4411
+ threadId: params.threadId,
4412
+ turnId: params.turnId,
4359
4413
  timedOut: params.timedOut,
4360
4414
  yieldDetected: params.yieldDetected ?? false,
4361
4415
  aborted: terminal.aborted,
@@ -4378,7 +4432,6 @@ function toTrajectoryToolDefinitions(tools) {
4378
4432
  }];
4379
4433
  }).toSorted((left, right) => left.name.localeCompare(right.name));
4380
4434
  }
4381
- /** Converts arbitrary prompt errors into trajectory-safe text. */
4382
4435
  function normalizeCodexTrajectoryError(value) {
4383
4436
  if (!value) return null;
4384
4437
  if (value instanceof Error) return value.message;
@@ -4395,7 +4448,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4395
4448
  const { prompt, state: resourceState, trajectoryRecorder, markTrajectoryEndRecorded } = resources;
4396
4449
  const { context, systemPromptReport } = prompt;
4397
4450
  const { runtime, attemptTools, activeTranscriptTarget, hookContext } = context;
4398
- const { hookContextWindowFields, hookRunner } = context;
4451
+ const { hookRunner } = context;
4399
4452
  const { connection, preparedAuthBinding } = runtime;
4400
4453
  const { effectiveRuntimeProviderId, effectiveRuntimeModelId } = runtime;
4401
4454
  const { params, terminalState, runAbortController, activeContextEngine, bindingStore, bindingIdentity, appServer, usesSupervisionConnection, sessionAgentId, contextSessionKey, effectiveCwd, agentDir, attemptStartedAt, startupAuthProfileId } = connection;
@@ -4411,45 +4464,12 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4411
4464
  assertCodexBindingMayBeReplaced(resourceState.thread, operation);
4412
4465
  return true;
4413
4466
  };
4414
- const { state, completion, deadlines, settlementExpired } = turnRuntime;
4467
+ const { state, completion } = turnRuntime;
4415
4468
  const { emitLifecycleTerminal, buildLifecycleTerminalMeta } = lifecycle;
4416
- const { drainNotificationQueue } = notifications;
4417
- const { codexModelCallDiagnostics } = requestRuntime;
4469
+ const { codexModelCallDiagnostics, buildLlmOutputEvent } = requestRuntime;
4418
4470
  const { activeTurnId, activeProjector, runtimeModelSelection, streamState, freezeRunTerminalOutcome, notifyUserMessagePersisted } = activeTurn;
4419
4471
  await completion;
4420
- const drainGraceElapsed = createDeferred();
4421
- let settlementPhase = "active";
4422
- let drainGraceTimer;
4423
- const beginDrainGrace = () => {
4424
- if (settlementPhase !== "active" || drainGraceTimer) return;
4425
- drainGraceTimer = setTimeout(() => {
4426
- settlementPhase = "expired";
4427
- drainGraceElapsed.resolve();
4428
- }, TURN_FINALIZE_DRAIN_ABORT_GRACE_MS);
4429
- drainGraceTimer.unref?.();
4430
- };
4431
- const abortListener = addAbortListener(runAbortController.signal, () => {
4432
- state.abortCleanup.then(beginDrainGrace, beginDrainGrace);
4433
- });
4434
- const closeProjection = () => {
4435
- state.projectionClosed = true;
4436
- return activeProjector.closeProjection();
4437
- };
4438
- const closeSettlement = () => {
4439
- if (settlementPhase === "closed") return;
4440
- settlementPhase = "closed";
4441
- abortListener[Symbol.dispose]();
4442
- clearTimeout(drainGraceTimer);
4443
- deadlines.dispose();
4444
- };
4445
- if (state.pluginRuntimeRefreshStop) await state.pluginRuntimeRefreshStop.catch(() => void 0);
4446
- const settlement = drainNotificationQueue().then(async () => {
4447
- await closeProjection();
4448
- await activeProjector.settlement.drain();
4449
- });
4450
- const degradedSettlement = settlementExpired.then(() => {
4451
- beginDrainGrace();
4452
- });
4472
+ const { settlement, degradedSettlement, drainGraceElapsed, closeProjection, closeSettlement, isActive: isSettlementActive, readRetainedNativeCommands } = await beginCodexAttemptSettlement(resources, turnRuntime, notifications, activeTurn);
4453
4473
  let projectionDrained = false;
4454
4474
  try {
4455
4475
  try {
@@ -4464,6 +4484,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4464
4484
  }
4465
4485
  const result = activeProjector.buildResult(toolBridge.telemetry, {
4466
4486
  yieldDetected: toolState.yieldDetected,
4487
+ readRetainedNativeCommands,
4467
4488
  steeringMessages: params.pluginRuntimeRefreshPending?.() ? turnRuntime.steeringQueueRef.current?.getAcceptedMessages() : void 0
4468
4489
  });
4469
4490
  const projectedTerminal = attemptTerminal.project(result.terminal);
@@ -4578,7 +4599,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4578
4599
  state.pendingSettlementStage = "transcript/mirror";
4579
4600
  return codexTranscriptMirrorRuntime.mirrorBestEffort({
4580
4601
  assertWriteCurrent: () => {
4581
- if (settlementPhase !== "active" || state.settlementWarning !== warning) throw new Error("Codex transcript settlement is no longer active");
4602
+ if (!isSettlementActive() || state.settlementWarning !== warning) throw new Error("Codex transcript settlement is no longer active");
4582
4603
  const current = projectTerminalOutcome();
4583
4604
  if (current.finalAborted !== mirrorTerminal.finalAborted || current.effectiveTimedOut !== mirrorTerminal.effectiveTimedOut || current.finalPromptError !== mirrorTerminal.finalPromptError) throw new Error("Codex transcript terminal outcome changed before write");
4584
4605
  },
@@ -4594,7 +4615,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4594
4615
  });
4595
4616
  };
4596
4617
  try {
4597
- if (projectionDrained && settlementPhase === "active" && !state.settlementWarning) mirrorOutcome = await Promise.race([
4618
+ if (projectionDrained && isSettlementActive() && !state.settlementWarning) mirrorOutcome = await Promise.race([
4598
4619
  mirrorFinal(),
4599
4620
  drainGraceElapsed.promise.then(() => unavailableMirror),
4600
4621
  degradedSettlement.then(() => unavailableMirror)
@@ -4619,7 +4640,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4619
4640
  message: toolState.yieldMessage,
4620
4641
  assertCurrent: () => {
4621
4642
  connection.assertCurrent();
4622
- if (settlementPhase !== "active" || !projectTerminalOutcome().turnSucceeded) throw new Error("Codex yield settlement is no longer active");
4643
+ if (!isSettlementActive() || !projectTerminalOutcome().turnSucceeded) throw new Error("Codex yield settlement is no longer active");
4623
4644
  }
4624
4645
  }),
4625
4646
  drainGraceElapsed.promise,
@@ -4670,13 +4691,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4670
4691
  });
4671
4692
  runAgentHarnessLlmOutputHook({
4672
4693
  event: {
4673
- runId: params.runId,
4674
- sessionId: params.sessionId,
4675
- provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
4676
- model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId,
4677
- ...hookContextWindowFields,
4678
- resolvedRef: usesSupervisionConnection ? `${resourceState.thread.modelProvider ?? effectiveRuntimeProviderId}/${resourceState.thread.model ?? effectiveRuntimeModelId}` : params.runtimePlan?.observability.resolvedRef ?? `${params.provider}/${params.modelId}`,
4679
- ...!usesSupervisionConnection && params.runtimePlan?.observability.harnessId ? { harnessId: params.runtimePlan.observability.harnessId } : {},
4694
+ ...buildLlmOutputEvent(),
4680
4695
  assistantTexts: result.assistantTexts,
4681
4696
  ...result.lastAssistant ? { lastAssistant: result.lastAssistant } : {},
4682
4697
  ...result.attemptUsage ? { usage: result.attemptUsage } : {}
@@ -4812,7 +4827,7 @@ function reportCodexExecutionNotification(params) {
4812
4827
  }
4813
4828
  if (notification.method !== "item/started") return;
4814
4829
  const item = readCodexNotificationItem(notification.params);
4815
- const tool = item ? codexExecutionToolName(item) : void 0;
4830
+ const tool = item ? itemName(item) : void 0;
4816
4831
  if (!item || !tool) return;
4817
4832
  params.emitExecutionPhaseOnce(`tool:${item.id}`, {
4818
4833
  phase: "tool_execution_started",
@@ -4820,10 +4835,6 @@ function reportCodexExecutionNotification(params) {
4820
4835
  itemId: item.id
4821
4836
  });
4822
4837
  }
4823
- /** Returns true when a notification ends the current app-server turn. */
4824
- function isTerminalCodexTurnNotificationForTurn(params) {
4825
- return params.notification.method === "turn/completed" && isCodexNotificationForTurn(params.notification.params, params.threadId, params.turnId) && readCodexTurnCompletedNotification(params.notification.params) !== void 0;
4826
- }
4827
4838
  //#endregion
4828
4839
  //#region extensions/codex/src/app-server/run-attempt-lifecycle-terminal.ts
4829
4840
  function buildCodexLifecycleTerminalMeta(input) {
@@ -4905,36 +4916,14 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
4905
4916
  state.pendingTerminalDynamicToolRelease = value;
4906
4917
  scheduleTerminalDynamicToolReleaseCheck();
4907
4918
  };
4908
- const emitLifecycleStart = (model) => {
4909
- emitCodexAppServerEvent(params, {
4910
- stream: "lifecycle",
4911
- data: {
4912
- phase: "start",
4913
- startedAt: attemptStartedAt
4914
- }
4915
- });
4916
- emitCodexAppServerEvent(params, {
4917
- stream: "lifecycle",
4918
- data: {
4919
- phase: "model",
4920
- ...model
4921
- }
4922
- });
4923
- state.lifecycleStarted = true;
4924
- };
4925
- const emitLifecycleTerminal = (data) => {
4926
- if (!state.lifecycleStarted || state.lifecycleTerminalEmitted || state.permissionChangeRestart || params.pluginRuntimeRefreshPending?.()) return;
4927
- emitCodexAppServerEvent(params, {
4928
- stream: "lifecycle",
4929
- data: {
4930
- startedAt: attemptStartedAt,
4931
- endedAt: Date.now(),
4932
- ...data,
4933
- ...params.deferTerminalLifecycle ? { phase: "finishing" } : {}
4934
- }
4935
- });
4936
- state.lifecycleTerminalEmitted = true;
4937
- };
4919
+ const { emitLifecycleStart, emitLifecycleTerminal, emitExecutionPhaseOnce } = createAgentHarnessAttemptLifecycle({
4920
+ attempt: params,
4921
+ backend: "codex-app-server",
4922
+ startedAtMs: attemptStartedAt,
4923
+ state,
4924
+ emitEvent: (event) => emitCodexAppServerEvent(params, event),
4925
+ shouldSuppressTerminal: () => Boolean(state.permissionChangeRestart || params.pluginRuntimeRefreshPending?.())
4926
+ });
4938
4927
  const buildLifecycleTerminalMeta = (input) => {
4939
4928
  const abortFields = input.aborted ? resolveAgentRunAbortLifecycleFields(runAbortController.signal) : void 0;
4940
4929
  return buildCodexLifecycleTerminalMeta({
@@ -4942,17 +4931,6 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
4942
4931
  abortStopReason: abortFields?.stopReason
4943
4932
  });
4944
4933
  };
4945
- const executionPhaseKeys = /* @__PURE__ */ new Set();
4946
- const emitExecutionPhaseOnce = (key, info) => {
4947
- if (executionPhaseKeys.has(key)) return;
4948
- executionPhaseKeys.add(key);
4949
- params.onExecutionPhase?.({
4950
- provider: params.provider,
4951
- model: params.modelId,
4952
- backend: "codex-app-server",
4953
- ...info
4954
- });
4955
- };
4956
4934
  const reportExecutionNotification = (notification) => {
4957
4935
  reportCodexExecutionNotification({
4958
4936
  notification,
@@ -4990,18 +4968,15 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
4990
4968
  fastModeAutoProgressState.offAnnounced = true;
4991
4969
  await emitFastModeAutoProgress(next);
4992
4970
  };
4993
- const maybeEmitFastModeAutoReset = async () => {
4994
- if (params.fastModeAuto !== true || !fastModeAutoProgressState.offAnnounced || fastModeAutoProgressState.resetAnnounced) return;
4995
- fastModeAutoProgressState.resetAnnounced = true;
4996
- await emitFastModeAutoProgress({
4997
- enabled: true,
4998
- elapsedSeconds: 0,
4999
- fastAutoOnSeconds: params.fastModeAutoOnSeconds
5000
- });
5001
- };
5002
4971
  const maybeEmitFastModeAutoResetBestEffort = async () => {
5003
4972
  try {
5004
- await maybeEmitFastModeAutoReset();
4973
+ if (params.fastModeAuto !== true || !fastModeAutoProgressState.offAnnounced || fastModeAutoProgressState.resetAnnounced) return;
4974
+ fastModeAutoProgressState.resetAnnounced = true;
4975
+ await emitFastModeAutoProgress({
4976
+ enabled: true,
4977
+ elapsedSeconds: 0,
4978
+ fastAutoOnSeconds: params.fastModeAutoOnSeconds
4979
+ });
5005
4980
  } catch (error) {
5006
4981
  embeddedAgentLog.warn(`codex app-server fast mode auto reset progress failed: ${formatErrorMessage(error)}`);
5007
4982
  }
@@ -5044,11 +5019,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
5044
5019
  nativeItemObservers.delete(observe);
5045
5020
  }
5046
5021
  };
5047
- const isTerminalTurnNotificationForTurn = (notification, notificationTurnId) => isTerminalCodexTurnNotificationForTurn({
5048
- notification,
5049
- threadId: resourceState.thread.threadId,
5050
- turnId: notificationTurnId
5051
- });
5022
+ const readTerminalTurn = (notification, notificationTurnId) => notification.method === "turn/completed" && isCodexNotificationForTurn(notification.params, resourceState.thread.threadId, notificationTurnId) ? readCodexTurnCompletedNotification(notification.params)?.turn : void 0;
5052
5023
  const handleNotification = async (notification) => {
5053
5024
  if (state.projectionClosed) return;
5054
5025
  const projector = projectorRef.current;
@@ -5058,8 +5029,8 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
5058
5029
  return;
5059
5030
  }
5060
5031
  const isCurrentTurn = isCodexNotificationForTurn(notification.params, resourceState.thread.threadId, turnId);
5061
- const isTerminal = isTerminalTurnNotificationForTurn(notification, turnId);
5062
- if ((state.timeout || state.localCompletionRequested) && isTerminal && readCodexTurnCompletedNotification(notification.params)?.turn.status === "interrupted") {
5032
+ const completedTurn = readTerminalTurn(notification, turnId);
5033
+ if ((state.timeout || state.localCompletionRequested) && completedTurn?.status === "interrupted") {
5063
5034
  completeTurn();
5064
5035
  return;
5065
5036
  }
@@ -5076,7 +5047,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
5076
5047
  if (notification.method === "item/completed") {
5077
5048
  if (activeTurnItemIds.size === 0) scheduleTerminalDynamicToolReleaseCheck();
5078
5049
  const item = readCodexNotificationItem(notification.params);
5079
- if (item?.type === "dynamicToolCall" && typeof item.id === "string") {
5050
+ if (item?.type === "dynamicToolCall") {
5080
5051
  const response = await openClawDynamicToolExecutions.get({
5081
5052
  threadId: resourceState.thread.threadId,
5082
5053
  turnId,
@@ -5099,11 +5070,11 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
5099
5070
  state.activeLocalProjections -= 1;
5100
5071
  if (isCurrentTurn && notification.method === "item/completed") {
5101
5072
  const item = readCodexNotificationItem(notification.params);
5102
- if (item?.type === "commandExecution" && typeof item.id === "string") pendingNativeCommandItems.delete(item.id);
5073
+ if (item?.type === "commandExecution") pendingNativeCommandItems.delete(item.id);
5103
5074
  }
5104
5075
  for (const observe of nativeItemObservers) observe();
5105
- if (isTerminal) {
5106
- if ((readCodexTurnCompletedNotification(notification.params)?.turn)?.status === "interrupted" && state.sawCodexInterruptMarker) projector.markAborted();
5076
+ if (completedTurn) {
5077
+ if (completedTurn.status === "interrupted" && state.sawCodexInterruptMarker) projector.markAborted();
5107
5078
  completeTurn();
5108
5079
  }
5109
5080
  }
@@ -5129,9 +5100,9 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
5129
5100
  const turnId = turnIdRef.current;
5130
5101
  if (!projector || !turnId || state.projectionClosed) return;
5131
5102
  projector.recordMcpToolCallReceipt(notification);
5132
- if (isTerminalTurnNotificationForTurn(notification, turnId)) {
5133
- const completed = readCodexTurnCompletedNotification(notification.params);
5134
- if (completed) projector.settlement.terminalReceipt = completed.turn;
5103
+ const completedTurn = readTerminalTurn(notification, turnId);
5104
+ if (completedTurn) {
5105
+ projector.settlement.terminalReceipt = completedTurn;
5135
5106
  state.terminalTurnNotificationQueued = true;
5136
5107
  steeringQueueRef.current?.sealAdmission();
5137
5108
  deadlines.beginSettlement(receivedAtMs);
@@ -5140,7 +5111,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
5140
5111
  const modelToolCallId = readRawResponseToolCallId(notification);
5141
5112
  if (modelToolCallId) allocateCodexToolOutcomeOrdinal?.(modelToolCallId);
5142
5113
  const nativeItem = readCodexNotificationItem(notification.params);
5143
- if (notification.method === "item/started" && nativeItem?.type === "commandExecution" && typeof nativeItem.id === "string") pendingNativeCommandItems.add(nativeItem.id);
5114
+ if (notification.method === "item/started" && nativeItem?.type === "commandExecution") pendingNativeCommandItems.add(nativeItem.id);
5144
5115
  if (nativeItem?.type === "webSearch") {
5145
5116
  projector.settlement.turnTainted ||= notification.method === "item/completed";
5146
5117
  projector.recordNativeToolOutcome(nativeItem);
@@ -5167,12 +5138,9 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
5167
5138
  }
5168
5139
  //#endregion
5169
5140
  //#region extensions/codex/src/app-server/run-attempt-prompt.ts
5170
- function isRestrictivePromptToolsAllow(toolsAllow) {
5171
- return toolsAllow !== void 0 && !toolsAllow.some((name) => name.trim() === "*");
5172
- }
5173
5141
  async function prepareCodexAttemptPrompt(context) {
5174
- const { runtime, attemptTools, historyState, hookContext, workspaceBootstrapContext, buildActiveContextEngineRuntimeContext, baseDeveloperInstructions, buildOpenClawPromptContext, skillsCollaborationInstructions, promptState, codexContextProjectionMaxChars, codexContinuityProjectionMaxChars } = context;
5175
- const { connection, buildActiveRunAttemptParams, effectiveContextTokenBudget, effectiveRuntimeModelId, effectiveRuntimeProviderId } = runtime;
5142
+ const { runtime, attemptTools, historyState, hookContext, workspaceBootstrapContext, buildActiveContextEngineRuntimeContext, baseDeveloperInstructions, buildOpenClawPromptContext, skillsInstructions, promptState, codexContextProjectionMaxChars, codexContinuityProjectionMaxChars } = context;
5143
+ const { connection, runtimeParams, effectiveContextTokenBudget, effectiveRuntimeModelId, effectiveRuntimeProviderId } = runtime;
5176
5144
  const { params, activeContextEngine, usesSupervisionConnection, mutable, isInactiveThreadBootstrapBinding, bindingStore, bindingIdentity, agentDir, appServer, contextSessionKey, effectiveWorkspace, sandbox } = connection;
5177
5145
  const { toolBridge } = attemptTools;
5178
5146
  const nativeHistoryProvenancePrefix = params.trigger === "user" ? buildCodexHistoryProvenancePrefix(params) : void 0;
@@ -5190,6 +5158,12 @@ async function prepareCodexAttemptPrompt(context) {
5190
5158
  connection.assertCurrent();
5191
5159
  connection.runAbortController.signal.throwIfAborted();
5192
5160
  };
5161
+ const inputAttachmentNote = await connection.prepareInputAttachments({
5162
+ maxChars: Math.max(0, CODEX_TURN_START_TEXT_INPUT_MAX_CHARS - (nativeHistoryProvenancePrefix?.length ?? 0) - params.prompt.length - 2),
5163
+ assertCurrent: assertProjectionCurrent,
5164
+ signal: connection.runAbortController.signal
5165
+ });
5166
+ assertProjectionCurrent();
5193
5167
  const admittedMessage = params.userTurnTranscriptRecorder?.message ?? await params.userTurnTranscriptRecorder?.resolveMessage();
5194
5168
  assertProjectionCurrent();
5195
5169
  const currentUserTurnIdempotencyKey = params.pluginRuntimeRefreshMessages ? void 0 : admittedMessage?.idempotencyKey;
@@ -5215,7 +5189,6 @@ async function prepareCodexAttemptPrompt(context) {
5215
5189
  const applyContinuityProjection = async (messages) => {
5216
5190
  const projection = await projectContextEngineAssemblyForCodex({
5217
5191
  assembledMessages: messages,
5218
- originalHistoryMessages: historyState.messages,
5219
5192
  prompt: params.prompt,
5220
5193
  maxRenderedContextChars: codexContinuityProjectionMaxChars,
5221
5194
  toolPayloadMode: params.pluginRuntimeRefreshMessages || preserveForkedToolResults ? "preserve" : "elide",
@@ -5226,107 +5199,97 @@ async function prepareCodexAttemptPrompt(context) {
5226
5199
  contextImageGroups = projection.imageGroups ?? [];
5227
5200
  promptState.promptText = projection.promptText;
5228
5201
  promptState.promptContextRange = projection.promptContextRange;
5229
- promptState.prePromptMessageCount = projection.prePromptMessageCount;
5230
5202
  promptState.noEngineContinuityProjectionApplied = true;
5231
5203
  };
5232
5204
  const applyActiveContextEngineProjection = async (decisionStartupBinding) => {
5233
5205
  if (!activeContextEngine) return;
5234
- const assembled = await assembleHarnessContextEngine({
5235
- contextEngine: activeContextEngine,
5236
- sessionId: runtime.activeSessionId,
5237
- sessionKey: contextSessionKey,
5238
- messages: historyState.messages,
5239
- tokenBudget: effectiveContextTokenBudget,
5240
- availableTools: new Set(flattenCodexDynamicToolFunctions(toolBridge.availableSpecs).map((tool) => tool.name).filter(isNonEmptyString)),
5241
- citationsMode: params.config?.memory?.citations,
5242
- sandboxed: sandbox?.enabled === true,
5243
- modelId: effectiveRuntimeModelId,
5244
- contextEngineHostSupport: CODEX_APP_SERVER_CONTEXT_ENGINE_HOST,
5245
- providerId: effectiveRuntimeProviderId,
5246
- requestedModelId: usesSupervisionConnection ? void 0 : params.requestedModelId,
5247
- fallbackReason: usesSupervisionConnection ? void 0 : params.fallbackReason,
5248
- degradedReason: usesSupervisionConnection ? void 0 : params.degradedReason,
5249
- runtimeContext: buildActiveContextEngineRuntimeContext(),
5250
- transcriptReadFence: params.userTurnTranscriptRecorder?.getAdmissionReceipt(),
5251
- prompt: params.prompt
5252
- });
5253
- if (!assembled) throw new Error("context engine assemble returned no result");
5254
- const contextEngineProjection = readContextEngineThreadBootstrapProjection(assembled.contextProjection);
5255
- const projectionDecision = contextEngineProjection ? resolveContextEngineBootstrapProjectionDecision({
5256
- startupBinding: decisionStartupBinding,
5257
- expectedBinding: buildContextEngineBinding(buildActiveRunAttemptParams(), contextEngineProjection),
5258
- projection: contextEngineProjection,
5259
- dynamicToolsFingerprint: codexDynamicToolsFingerprint(toolBridge.specs),
5260
- legacyDynamicToolsFingerprint: codexLegacyDynamicToolsFingerprint(toolBridge.specs)
5261
- }) : {
5262
- project: true,
5263
- reason: "per-turn-projection"
5264
- };
5265
- const projection = await projectContextEngineAssemblyForCodex({
5266
- assembledMessages: assembled.messages,
5267
- originalHistoryMessages: historyState.messages,
5268
- prompt: params.prompt,
5269
- systemPromptAddition: assembled.systemPromptAddition,
5270
- maxRenderedContextChars: codexContextProjectionMaxChars,
5271
- toolPayloadMode: contextEngineProjection || params.pluginRuntimeRefreshMessages || preserveForkedToolResults ? "preserve" : "elide",
5272
- ...projectionDecision.project ? { prepareFileContext } : {},
5273
- currentUserTurnIdempotencyKey
5274
- });
5275
- assertProjectionCurrent();
5276
- contextImageGroups = projectionDecision.project ? projection.imageGroups ?? [] : [];
5277
- const decisionBinding = decisionStartupBinding;
5278
- embeddedAgentLog.info("codex app-server context-engine projection decision", {
5279
- sessionId: params.sessionId,
5280
- sessionKey: contextSessionKey,
5281
- engineId: activeContextEngine.info.id,
5282
- mode: contextEngineProjection?.mode ?? assembled.contextProjection?.mode ?? "per_turn",
5283
- epoch: contextEngineProjection?.epoch,
5284
- fingerprint: contextEngineProjection?.fingerprint,
5285
- previousThreadId: decisionBinding?.threadId,
5286
- previousEpoch: decisionBinding?.contextEngine?.projection?.epoch,
5287
- previousFingerprint: decisionBinding?.contextEngine?.projection?.fingerprint,
5288
- projected: projectionDecision.project,
5289
- reason: projectionDecision.reason,
5290
- assembledMessages: assembled.messages.length,
5291
- originalHistoryMessages: historyState.messages.length,
5292
- projectedPromptChars: projection.promptText.length,
5293
- developerInstructionAdditionChars: projection.developerInstructionAddition?.length ?? 0
5294
- });
5295
- promptState.contextEngineProjection = contextEngineProjection;
5296
- promptState.promptText = projectionDecision.project ? projection.promptText : params.prompt;
5297
- promptState.promptContextRange = projectionDecision.project ? projection.promptContextRange : void 0;
5298
- promptState.developerInstructions = joinPresentSections(baseDeveloperInstructions, projection.developerInstructionAddition);
5299
- promptState.prePromptMessageCount = projection.prePromptMessageCount;
5300
- };
5301
- if (activeContextEngine) try {
5302
- await applyActiveContextEngineProjection(runtime.nativeToolSurfaceEnabled ? mutable.startupBinding : void 0);
5303
- } catch (assembleErr) {
5304
- if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
5305
- assertProjectionCurrent();
5306
- embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
5307
- }
5308
- const codexModelInputHistoryMessages = [];
5309
- const admittedContent = admittedMessage?.content;
5310
- const currentUserMessage = admittedMessage ? typeof admittedContent === "string" ? admittedContent : (admittedContent ?? []).flatMap((part) => part.type === "text" ? [part.text] : []).join("\n") : params.pluginRuntimeRefreshMessages ? "" : params.prompt;
5311
- const buildPromptFromCurrentInputs = async () => {
5312
- return await resolveAgentHarnessBeforePromptBuildResult({
5313
- currentUserMessage,
5314
- currentUserMessageId: admittedMessage?.idempotencyKey,
5315
- prompt: prependCurrentInboundContext(promptState.promptText, params.currentInboundContext),
5316
- developerInstructions: { build: ({ toolsAllow }) => {
5317
- 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.");
5318
- return promptState.developerInstructions;
5319
- } },
5320
- messages: historyState.messages,
5321
- ctx: hookContext,
5322
- bootstrapContextRunKind: params.bootstrapContextRunKind,
5323
- toolAuthority: {
5324
- fingerprint: params.toolAuthorityFingerprint,
5325
- activeToolNames: () => flattenCodexDynamicToolFunctions(toolBridge.availableSpecs).map((tool) => tool.name).filter(isNonEmptyString),
5326
- assertActive: connection.assertCurrent
5327
- }
5328
- });
5206
+ try {
5207
+ const assembled = await assembleHarnessContextEngine({
5208
+ contextEngine: activeContextEngine,
5209
+ sessionId: runtimeParams.sessionId,
5210
+ sessionKey: contextSessionKey,
5211
+ messages: historyState.messages,
5212
+ tokenBudget: effectiveContextTokenBudget,
5213
+ availableTools: new Set(flattenCodexDynamicToolFunctions(toolBridge.availableSpecs).map((tool) => tool.name).filter(isNonEmptyString)),
5214
+ citationsMode: params.config?.memory?.citations,
5215
+ sandboxed: sandbox?.enabled === true,
5216
+ modelId: effectiveRuntimeModelId,
5217
+ contextEngineHostSupport: CODEX_APP_SERVER_CONTEXT_ENGINE_HOST,
5218
+ providerId: effectiveRuntimeProviderId,
5219
+ requestedModelId: usesSupervisionConnection ? void 0 : params.requestedModelId,
5220
+ fallbackReason: usesSupervisionConnection ? void 0 : params.fallbackReason,
5221
+ degradedReason: usesSupervisionConnection ? void 0 : params.degradedReason,
5222
+ runtimeContext: buildActiveContextEngineRuntimeContext(),
5223
+ transcriptReadFence: params.userTurnTranscriptRecorder?.getAdmissionReceipt(),
5224
+ prompt: params.prompt
5225
+ });
5226
+ if (!assembled) throw new Error("context engine assemble returned no result");
5227
+ const contextEngineProjection = readContextEngineThreadBootstrapProjection(assembled.contextProjection);
5228
+ const projectionDecision = contextEngineProjection ? resolveContextEngineBootstrapProjectionDecision({
5229
+ startupBinding: decisionStartupBinding,
5230
+ expectedBinding: buildContextEngineBinding({ ...runtimeParams }, contextEngineProjection),
5231
+ projection: contextEngineProjection,
5232
+ dynamicToolsFingerprint: codexDynamicToolsFingerprint(toolBridge.specs),
5233
+ legacyDynamicToolsFingerprint: codexLegacyDynamicToolsFingerprint(toolBridge.specs)
5234
+ }) : {
5235
+ project: true,
5236
+ reason: "per-turn-projection"
5237
+ };
5238
+ const projection = await projectContextEngineAssemblyForCodex({
5239
+ assembledMessages: assembled.messages,
5240
+ prompt: params.prompt,
5241
+ systemPromptAddition: assembled.systemPromptAddition,
5242
+ maxRenderedContextChars: codexContextProjectionMaxChars,
5243
+ toolPayloadMode: contextEngineProjection || params.pluginRuntimeRefreshMessages || preserveForkedToolResults ? "preserve" : "elide",
5244
+ ...projectionDecision.project ? { prepareFileContext } : {},
5245
+ currentUserTurnIdempotencyKey
5246
+ });
5247
+ assertProjectionCurrent();
5248
+ contextImageGroups = projectionDecision.project ? projection.imageGroups ?? [] : [];
5249
+ embeddedAgentLog.info("codex app-server context-engine projection decision", {
5250
+ sessionId: params.sessionId,
5251
+ sessionKey: contextSessionKey,
5252
+ engineId: activeContextEngine.info.id,
5253
+ mode: contextEngineProjection?.mode ?? assembled.contextProjection?.mode ?? "per_turn",
5254
+ epoch: contextEngineProjection?.epoch,
5255
+ fingerprint: contextEngineProjection?.fingerprint,
5256
+ previousThreadId: decisionStartupBinding?.threadId,
5257
+ previousEpoch: decisionStartupBinding?.contextEngine?.projection?.epoch,
5258
+ previousFingerprint: decisionStartupBinding?.contextEngine?.projection?.fingerprint,
5259
+ projected: projectionDecision.project,
5260
+ reason: projectionDecision.reason,
5261
+ assembledMessages: assembled.messages.length,
5262
+ originalHistoryMessages: historyState.messages.length,
5263
+ projectedPromptChars: projection.promptText.length,
5264
+ developerInstructionAdditionChars: projection.developerInstructionAddition?.length ?? 0
5265
+ });
5266
+ promptState.contextEngineProjection = contextEngineProjection;
5267
+ promptState.promptText = projectionDecision.project ? projection.promptText : params.prompt;
5268
+ promptState.promptContextRange = projectionDecision.project ? projection.promptContextRange : void 0;
5269
+ promptState.developerInstructions = joinPresentSections(baseDeveloperInstructions, projection.developerInstructionAddition);
5270
+ } catch (assembleErr) {
5271
+ if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
5272
+ assertProjectionCurrent();
5273
+ embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
5274
+ }
5329
5275
  };
5276
+ if (activeContextEngine) await applyActiveContextEngineProjection(runtime.nativeToolSurfaceEnabled ? mutable.startupBinding : void 0);
5277
+ const buildPromptFromCurrentInputs = () => resolveAgentHarnessBeforePromptBuildResult({
5278
+ currentUserMessage: admittedMessage ?? (params.pluginRuntimeRefreshMessages ? "" : params.prompt),
5279
+ prompt: prependCurrentInboundContext(promptState.promptText, params.currentInboundContext),
5280
+ developerInstructions: { build: ({ hasToolRestrictions }) => {
5281
+ if (hasToolRestrictions) throw new Error("Codex app-server cannot enforce before_prompt_build toolsAllow; use the embedded or Copilot runtime for turn-scoped tool policy.");
5282
+ return promptState.developerInstructions;
5283
+ } },
5284
+ messages: historyState.messages,
5285
+ ctx: hookContext,
5286
+ bootstrapContextRunKind: params.bootstrapContextRunKind,
5287
+ toolAuthority: {
5288
+ fingerprint: params.toolAuthorityFingerprint,
5289
+ activeToolNames: () => flattenCodexDynamicToolFunctions(toolBridge.availableSpecs).map((tool) => tool.name).filter(isNonEmptyString),
5290
+ assertActive: connection.assertCurrent
5291
+ }
5292
+ });
5330
5293
  const resolveShiftedPromptInputRange = (prompt, promptInputRange, turnPromptText) => {
5331
5294
  if (!promptInputRange || promptInputRange.start < 0 || promptInputRange.end < promptInputRange.start || promptInputRange.end > prompt.length || !turnPromptText.endsWith(prompt)) return;
5332
5295
  const turnPromptOffset = turnPromptText.length - prompt.length;
@@ -5362,9 +5325,12 @@ async function prepareCodexAttemptPrompt(context) {
5362
5325
  decoratedPrompt: turnPromptText
5363
5326
  });
5364
5327
  const imageOffset = projectedRanges && promptState.promptContextRange ? projectedRanges.contextRange.start - promptState.promptContextRange.start : void 0;
5328
+ const inputLimit = CODEX_TURN_START_TEXT_INPUT_MAX_CHARS - (nativeHistoryProvenancePrefix?.length ?? 0);
5329
+ const requiredInputChars = turnPromptText.length - (projectedRanges ? projectedRanges.contextRange.end - projectedRanges.contextRange.start : 0);
5330
+ const attachmentNote = inputAttachmentNote && requiredInputChars + inputAttachmentNote.length + 2 <= inputLimit ? inputAttachmentNote : void 0;
5365
5331
  const fitted = fitCodexProjectedContextForTurnStart({
5366
5332
  promptText: turnPromptText,
5367
- maxChars: CODEX_TURN_START_TEXT_INPUT_MAX_CHARS - (nativeHistoryProvenancePrefix?.length ?? 0),
5333
+ maxChars: inputLimit - (attachmentNote ? attachmentNote.length + 2 : 0),
5368
5334
  contextRange: projectedRanges?.contextRange,
5369
5335
  requestRange: projectedRanges?.requestRange,
5370
5336
  preservedRange,
@@ -5375,7 +5341,7 @@ async function prepareCodexAttemptPrompt(context) {
5375
5341
  }))
5376
5342
  });
5377
5343
  turnContextImageGroups = fitted.imageGroups ?? [];
5378
- return fitted.promptText;
5344
+ return attachmentNote ? `${fitted.promptText}\n\n${attachmentNote}` : fitted.promptText;
5379
5345
  };
5380
5346
  const firstPromptBuild = await buildPromptFromCurrentInputs();
5381
5347
  const turnState = {
@@ -5385,10 +5351,12 @@ async function prepareCodexAttemptPrompt(context) {
5385
5351
  let parentLocalEgress = false;
5386
5352
  const parentLocalContext = {
5387
5353
  turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
5388
- skillsCollaborationInstructions,
5389
5354
  memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions
5390
5355
  };
5391
- const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(turnState.promptBuild.developerInstructions, (parentLocalEgress ? buildCodexParentLocalInstructions(params, parentLocalContext) : buildTurnCollaborationMode(params, parentLocalContext).settings.developer_instructions) ?? void 0);
5356
+ const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(turnState.promptBuild.developerInstructions, parentLocalEgress ? void 0 : skillsInstructions, (parentLocalEgress ? buildCodexParentLocalInstructions(params, {
5357
+ ...parentLocalContext,
5358
+ skillsInstructions
5359
+ }) : buildTurnCollaborationMode(params, parentLocalContext).settings.developer_instructions) ?? void 0);
5392
5360
  const rebuildCodexPromptBuildFromCurrentProjection = async () => {
5393
5361
  turnState.promptBuild = await buildPromptFromCurrentInputs();
5394
5362
  turnState.codexTurnPromptText = decorateCodexTurnPromptText(turnState.promptBuild);
@@ -5472,13 +5440,7 @@ async function prepareCodexAttemptPrompt(context) {
5472
5440
  if (promptState.staleBindingContinuityForcedFreshStart) await applyContinuityProjection(historyState.messages);
5473
5441
  if (activeContextEngine) {
5474
5442
  promptState.contextEngineProjection = void 0;
5475
- try {
5476
- await applyActiveContextEngineProjection(void 0);
5477
- } catch (assembleErr) {
5478
- if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
5479
- assertProjectionCurrent();
5480
- embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
5481
- }
5443
+ await applyActiveContextEngineProjection(void 0);
5482
5444
  }
5483
5445
  await rebuildCodexPromptBuildFromCurrentProjection();
5484
5446
  embeddedAgentLog.info("codex app-server rebuilt turn prompt after native thread rotation", {
@@ -5497,7 +5459,7 @@ async function prepareCodexAttemptPrompt(context) {
5497
5459
  developerInstructions: buildRenderedCodexDeveloperInstructions(),
5498
5460
  workspaceBootstrapContext,
5499
5461
  omitWorkspaceReferences,
5500
- skillsPrompt: skillsCollaborationInstructions ? params.skillsSnapshot?.prompt ?? "" : "",
5462
+ skillsPrompt: skillsInstructions ? params.skillsSnapshot?.prompt ?? "" : "",
5501
5463
  tools: toolBridge.availableSpecs
5502
5464
  });
5503
5465
  const systemPromptReport = buildSystemPromptReport();
@@ -5507,7 +5469,6 @@ async function prepareCodexAttemptPrompt(context) {
5507
5469
  get contextImageGroups() {
5508
5470
  return turnContextImageGroups;
5509
5471
  },
5510
- codexModelInputHistoryMessages,
5511
5472
  nativeHistoryProvenancePrefix,
5512
5473
  turnState,
5513
5474
  refreshWorkspaceReferences: (include) => {
@@ -5542,6 +5503,39 @@ function buildCodexHookRequester(params) {
5542
5503
  return Object.keys(requester).length > 0 ? requester : void 0;
5543
5504
  }
5544
5505
  //#endregion
5506
+ //#region extensions/codex/src/app-server/native-subagent-assignment-store.ts
5507
+ function createNativeSubagentAssignmentStore(params) {
5508
+ const { bindingStore, identity, owner } = params;
5509
+ const assertCurrent = () => {
5510
+ params.assertLifecycleCurrent?.();
5511
+ const binding = bindingStore.read(identity);
5512
+ if (!binding || !matchesCodexNativeSubagentSubmissionBinding(binding, owner)) throw new Error("Native assignment binding is no longer current.");
5513
+ };
5514
+ return {
5515
+ assertCurrent,
5516
+ read: () => {
5517
+ assertCurrent();
5518
+ return bindingStore.readNativeSubagentAssignments?.(identity, owner) ?? [];
5519
+ },
5520
+ record: (assignment, assertSourceCurrent) => bindingStore.mutate(identity, {
5521
+ kind: "record-native-subagent-assignment",
5522
+ owner,
5523
+ assignment
5524
+ }, () => {
5525
+ assertCurrent();
5526
+ assertSourceCurrent();
5527
+ }),
5528
+ consume: (assignment, assertSourceCurrent) => bindingStore.mutate(identity, {
5529
+ kind: "consume-native-subagent-assignment",
5530
+ owner,
5531
+ assignment
5532
+ }, () => {
5533
+ assertCurrent();
5534
+ assertSourceCurrent();
5535
+ })
5536
+ };
5537
+ }
5538
+ //#endregion
5545
5539
  //#region extensions/codex/src/app-server/run-attempt-resources.ts
5546
5540
  function prepareCodexAttemptResources(prompt) {
5547
5541
  const { context, turnState, buildRenderedCodexDeveloperInstructions } = prompt;
@@ -5549,6 +5543,13 @@ function prepareCodexAttemptResources(prompt) {
5549
5543
  const { connection, hookChannelId } = runtime;
5550
5544
  const { appServer, params, effectiveCwd, sessionAgentId, contextSessionKey, runAbortController, sandbox, options, nativeHookRelayEvents } = connection;
5551
5545
  const { toolBridge } = attemptTools;
5546
+ const modelAdmissionSource = runtime.nativeToolSurfaceEnabled ? params.hostCapabilities.retainSourceAuthority?.() : void 0;
5547
+ let nativeModelAdmission;
5548
+ try {
5549
+ nativeModelAdmission = modelAdmissionSource ? modelAdmissionSource.modelPolicyRequired !== false ? "required" : options.nativeHookRelay?.enabled === false ? "disabled" : "optional" : void 0;
5550
+ } finally {
5551
+ modelAdmissionSource?.release();
5552
+ }
5552
5553
  let nativeProcessAuthorityReleased = false;
5553
5554
  const releaseNativeProcessAuthority = () => {
5554
5555
  if (!nativeProcessAuthorityReleased) {
@@ -5576,8 +5577,6 @@ function prepareCodexAttemptResources(prompt) {
5576
5577
  nativeHookRelay: void 0,
5577
5578
  nativeSubagentMonitor: void 0,
5578
5579
  runtimeContinuationStarted: false,
5579
- nativePreToolUseFailureFallbackActive: false,
5580
- nativePreToolUseFailureFallbackTerminalReason: void 0,
5581
5580
  releaseSharedClientLease: void 0,
5582
5581
  startupClientUnsafe: false,
5583
5582
  turnStartAttempted: false,
@@ -5590,29 +5589,14 @@ function prepareCodexAttemptResources(prompt) {
5590
5589
  codexSandboxPolicy: void 0,
5591
5590
  restartContextEngineCodexThread: void 0
5592
5591
  };
5593
- const pendingNativePreToolUseFailures = [];
5594
5592
  const projectorRef = {};
5595
- const emitNativePreToolUseFailure = (failure) => {
5596
- emitCodexNativePreToolUseFailureDiagnostic({
5597
- agentId: sessionAgentId,
5598
- sessionId: params.sessionId,
5599
- sessionKey: contextSessionKey,
5600
- runId: params.runId,
5601
- signal: runAbortController.signal,
5602
- failure,
5603
- ...state.nativePreToolUseFailureFallbackActive ? { terminalReason: state.nativePreToolUseFailureFallbackTerminalReason ?? failure.disposition } : {}
5604
- });
5605
- };
5606
- const flushPendingNativePreToolUseFailures = () => {
5607
- for (const failure of pendingNativePreToolUseFailures.splice(0)) emitNativePreToolUseFailure(failure);
5608
- };
5609
- const activateNativePreToolUseFailureFallback = () => {
5610
- if (!state.nativePreToolUseFailureFallbackActive) {
5611
- state.nativePreToolUseFailureFallbackTerminalReason = runAbortController.signal.aborted ? resolveCodexToolAbortTerminalReason(runAbortController.signal) : void 0;
5612
- state.nativePreToolUseFailureFallbackActive = true;
5613
- }
5614
- flushPendingNativePreToolUseFailures();
5615
- };
5593
+ const nativePreToolUseFailures = createCodexNativePreToolUseFailureBuffer({
5594
+ agentId: sessionAgentId,
5595
+ sessionId: params.sessionId,
5596
+ sessionKey: contextSessionKey,
5597
+ runId: params.runId,
5598
+ signal: runAbortController.signal
5599
+ });
5616
5600
  const releaseSharedClientLeaseOnce = () => {
5617
5601
  const release = state.releaseSharedClientLease;
5618
5602
  if (!release) return;
@@ -5672,15 +5656,19 @@ function prepareCodexAttemptResources(prompt) {
5672
5656
  }
5673
5657
  });
5674
5658
  let nativeSubagentMonitorSettlement;
5659
+ let nativeSubagentMonitorGeneration = 0;
5675
5660
  const unregisterNativeSubagentMonitor = async () => {
5661
+ nativeSubagentMonitorGeneration += 1;
5676
5662
  const registration = state.nativeSubagentMonitor;
5677
5663
  state.nativeSubagentMonitor = void 0;
5678
5664
  if (registration) nativeSubagentMonitorSettlement = registration.unregister();
5679
5665
  await nativeSubagentMonitorSettlement;
5680
5666
  };
5681
5667
  const registerNativeSubagentMonitor = async (parentThreadId) => {
5668
+ const { client, thread, nativeHookRelay, turnRoute } = state;
5682
5669
  await unregisterNativeSubagentMonitor();
5683
5670
  connection.assertCurrent();
5671
+ const generation = ++nativeSubagentMonitorGeneration;
5684
5672
  const sessionKey = params.sessionKey;
5685
5673
  const storePath = params.sessionTarget?.storePath;
5686
5674
  const parentSession = sessionKey && storePath ? getSessionEntry({
@@ -5694,22 +5682,25 @@ function prepareCodexAttemptResources(prompt) {
5694
5682
  parentThreadId,
5695
5683
  sessionId: params.sessionId,
5696
5684
  ...parentSession?.sessionId === params.sessionId ? { lifecycleRevision: parentSession.lifecycleRevision } : {},
5697
- binding: state.thread
5685
+ binding: thread
5698
5686
  });
5699
5687
  const { bindingStore, bindingIdentity } = connection;
5700
- const submissionStore = historyOwner ? {
5688
+ const assertParentSessionCurrent = () => {
5689
+ if (historyOwner?.lifecycleRevision && sessionKey && storePath) {
5690
+ if (getSessionEntry({
5691
+ agentId: sessionAgentId,
5692
+ sessionKey,
5693
+ storePath,
5694
+ readConsistency: "latest",
5695
+ hydrateSkillPromptRefs: false
5696
+ })?.lifecycleRevision !== historyOwner.lifecycleRevision) throw new Error("Native submission session lifecycle is no longer current.");
5697
+ }
5698
+ };
5699
+ const submissionStore = historyOwner && thread.lifecycle.preserveExistingBinding !== true ? {
5701
5700
  assertCurrent: () => {
5702
5701
  const current = bindingStore.read(bindingIdentity);
5703
5702
  if (!current || !matchesCodexNativeSubagentSubmissionBinding(current, historyOwner)) throw new Error("Native submission binding is no longer current.");
5704
- if (historyOwner.lifecycleRevision && sessionKey && storePath) {
5705
- if (getSessionEntry({
5706
- agentId: sessionAgentId,
5707
- sessionKey,
5708
- storePath,
5709
- readConsistency: "latest",
5710
- hydrateSkillPromptRefs: false
5711
- })?.lifecycleRevision !== historyOwner.lifecycleRevision) throw new Error("Native submission session lifecycle is no longer current.");
5712
- }
5703
+ assertParentSessionCurrent();
5713
5704
  },
5714
5705
  read: () => bindingStore.readNativeSubagentSubmissions(bindingIdentity, historyOwner),
5715
5706
  record: (receipt, assertCurrent) => bindingStore.mutate(bindingIdentity, {
@@ -5723,22 +5714,60 @@ function prepareCodexAttemptResources(prompt) {
5723
5714
  receipt
5724
5715
  }, assertCurrent)
5725
5716
  } : void 0;
5726
- state.nativeSubagentMonitor = codexNativeSubagentMonitorRuntime.register({
5727
- client: state.client,
5728
- parentThreadId,
5729
- requesterSessionKey: params.sessionKey,
5730
- taskRuntimeScope: params.agentHarnessTaskRuntimeScope,
5731
- historyOwner,
5732
- submissionStore,
5733
- agentId: sessionAgentId,
5734
- retainClient: () => retainSharedCodexAppServerClientIfCurrent(state.client),
5735
- retainParentThread: (protectedThreadId) => protectCodexAppServerLiveThread(state.client, protectedThreadId),
5736
- claimDirectChild: (childThreadId) => state.nativeHookRelay?.claimDirectChild(childThreadId),
5737
- rejectPendingDirectChild: (childThreadId, reason) => state.nativeHookRelay?.rejectPendingDirectChild(childThreadId, reason),
5738
- ...params.sessionKey && params.agentHarnessTaskRuntimeScope ? { onDirectChildAccepted: () => {
5739
- state.runtimeContinuationStarted = true;
5740
- } } : {}
5741
- });
5717
+ const assignmentStore = historyOwner && submissionStore ? createNativeSubagentAssignmentStore({
5718
+ bindingStore,
5719
+ identity: bindingIdentity,
5720
+ owner: historyOwner,
5721
+ assertLifecycleCurrent: () => submissionStore.assertCurrent()
5722
+ }) : void 0;
5723
+ const assertRegistrationCurrent = () => {
5724
+ runAbortController.signal.throwIfAborted();
5725
+ params.hostCapabilities.assertActive();
5726
+ connection.assertCurrent();
5727
+ if (submissionStore) submissionStore.assertCurrent();
5728
+ else assertParentSessionCurrent();
5729
+ thread.liveThreadOwnership?.assertCurrent();
5730
+ if (generation !== nativeSubagentMonitorGeneration || state.client !== client || state.thread !== thread || state.nativeHookRelay !== nativeHookRelay || state.turnRoute !== turnRoute) throw new Error("Codex native subagent registration was superseded during setup");
5731
+ };
5732
+ const retainModelSource = params.hostCapabilities.retainSourceAuthority;
5733
+ const modelSource = retainModelSource?.();
5734
+ try {
5735
+ const configurationQualification = getCodexInferenceThreadQualification(client, parentThreadId);
5736
+ const registration = await codexNativeSubagentMonitorRuntime.register({
5737
+ client,
5738
+ parentThreadId,
5739
+ ...retainModelSource ? { modelSource } : {},
5740
+ configurationQualification,
5741
+ unqualifiedModelExecution: modelSource && !configurationQualification ? true : void 0,
5742
+ onUnqualifiedModelCancelled: connection.abortExplicitly,
5743
+ requesterSessionKey: params.sessionKey,
5744
+ completionScope: params.agentHarnessCompletionScope,
5745
+ historyOwner,
5746
+ submissionStore,
5747
+ assignmentStore,
5748
+ agentId: sessionAgentId,
5749
+ assertCurrent: assertRegistrationCurrent,
5750
+ isTurnYielded: () => attemptTools.toolState.yieldDetected,
5751
+ retainClient: () => retainSharedCodexAppServerClientIfCurrent(client),
5752
+ retainParentThread: (protectedThreadId) => protectCodexAppServerLiveThread(client, protectedThreadId),
5753
+ claimDirectChild: (childThreadId) => nativeHookRelay?.claimDirectChild(childThreadId),
5754
+ rejectPendingDirectChild: (childThreadId, reason) => nativeHookRelay?.rejectPendingDirectChild(childThreadId, reason),
5755
+ ...params.sessionKey && params.agentHarnessCompletionScope ? { onDirectChildAccepted: () => {
5756
+ state.runtimeContinuationStarted = true;
5757
+ } } : {}
5758
+ });
5759
+ try {
5760
+ await registration.ready;
5761
+ assertRegistrationCurrent();
5762
+ state.nativeSubagentMonitor = registration;
5763
+ } catch (error) {
5764
+ await registration.unregister();
5765
+ throw error;
5766
+ }
5767
+ } catch (error) {
5768
+ modelSource?.release();
5769
+ throw error;
5770
+ }
5742
5771
  };
5743
5772
  const releaseCurrentRoute = async () => {
5744
5773
  state.releaseInferenceContext?.();
@@ -5804,7 +5833,7 @@ function prepareCodexAttemptResources(prompt) {
5804
5833
  return released;
5805
5834
  };
5806
5835
  const cleanupBeforeActiveTurn = async () => {
5807
- await runCleanupStep("codex-pre-turn-hook-fallback", activateNativePreToolUseFailureFallback);
5836
+ await runCleanupStep("codex-pre-turn-hook-fallback", () => nativePreToolUseFailures.activateFallback(runAbortController.signal.aborted));
5808
5837
  await runCleanupStep("codex-pre-turn-subscription", async () => {
5809
5838
  const { thread } = state;
5810
5839
  if (!thread || subscriptionSettlement?.thread === thread || state.startupClientUnsafe) return;
@@ -5843,8 +5872,10 @@ function prepareCodexAttemptResources(prompt) {
5843
5872
  previousRelay?.unregister();
5844
5873
  await previousRelay?.drain();
5845
5874
  connection.assertCurrent();
5846
- const requiresProcessAdmission = nativeProcessAuthority && runtime.nativeToolSurfaceEnabled;
5847
- const relayEvents = requiresProcessAdmission && !nativeHookRelayEvents.includes("pre_tool_use") ? [...nativeHookRelayEvents, "pre_tool_use"] : nativeHookRelayEvents;
5875
+ const requiresProcessAdmission = nativeProcessAuthority?.requiresProcessAdmission && runtime.nativeToolSurfaceEnabled;
5876
+ const requiresModelAdmission = nativeModelAdmission !== void 0 && decision.nativeModelInputTools !== void 0;
5877
+ const requiresExecutionAdmission = requiresProcessAdmission || requiresModelAdmission;
5878
+ const relayEvents = requiresExecutionAdmission && !nativeHookRelayEvents.includes("pre_tool_use") ? [...nativeHookRelayEvents, "pre_tool_use"] : nativeHookRelayEvents;
5848
5879
  if (params.pluginHarnessToolPolicyRestricted === true) {
5849
5880
  state.nativeHookRelay = void 0;
5850
5881
  return {
@@ -5853,7 +5884,7 @@ function prepareCodexAttemptResources(prompt) {
5853
5884
  };
5854
5885
  }
5855
5886
  state.nativeHookRelay = createCodexNativeHookRelay({
5856
- options: requiresProcessAdmission ? {
5887
+ options: requiresExecutionAdmission ? {
5857
5888
  ...options.nativeHookRelay,
5858
5889
  enabled: true
5859
5890
  } : options.nativeHookRelay,
@@ -5887,12 +5918,17 @@ function prepareCodexAttemptResources(prompt) {
5887
5918
  owner: nativeProcessAuthority,
5888
5919
  client: () => state.client
5889
5920
  } : void 0,
5921
+ nativeModelAdmission: requiresModelAdmission ? {
5922
+ client: () => state.client,
5923
+ threadId: () => state.thread?.threadId,
5924
+ tools: decision.nativeModelInputTools,
5925
+ readQualification: (threadId) => getCodexInferenceThreadQualification(state.client, threadId)
5926
+ } : void 0,
5890
5927
  assertCurrent: connection.assertCurrent,
5891
5928
  onPreToolUseFailure: (failure) => {
5892
5929
  const projector = projectorRef.current;
5893
5930
  if (projector) projector.recordNativeToolPreToolUseFailure(failure);
5894
- else if (state.nativePreToolUseFailureFallbackActive) emitNativePreToolUseFailure(failure);
5895
- else pendingNativePreToolUseFailures.push(failure);
5931
+ else nativePreToolUseFailures.record(failure);
5896
5932
  }
5897
5933
  });
5898
5934
  await state.nativeHookRelay?.prepareInvocation();
@@ -5906,7 +5942,7 @@ function prepareCodexAttemptResources(prompt) {
5906
5942
  nativeHookRelayGeneration: state.nativeHookRelay?.generation
5907
5943
  };
5908
5944
  };
5909
- const nativeProcessAuthority = sandbox?.enabled && sandbox.backend && params.hostCapabilities.retainSourceAuthority ? new CodexNativeProcessAuthority(params.hostCapabilities, (error) => {
5945
+ const nativeProcessAuthority = params.hostCapabilities.retainSourceAuthority ? new CodexNativeProcessAuthority(params.hostCapabilities, (error) => {
5910
5946
  const message = formatErrorMessage(error);
5911
5947
  embeddedAgentLog.warn("codex native background work remains unsettled", {
5912
5948
  runId: params.runId,
@@ -5920,20 +5956,19 @@ function prepareCodexAttemptResources(prompt) {
5920
5956
  error: message
5921
5957
  }
5922
5958
  });
5923
- }) : void 0;
5959
+ }, Boolean(sandbox?.enabled && sandbox.backend)) : void 0;
5924
5960
  return {
5925
5961
  prompt,
5926
5962
  trajectoryRecorder,
5927
5963
  state,
5928
5964
  projectorRef,
5929
- pendingNativePreToolUseFailures,
5965
+ pendingNativePreToolUseFailures: nativePreToolUseFailures.pending,
5966
+ nativeModelAdmission,
5930
5967
  nativeProcessAuthority,
5931
5968
  releaseNativeProcessAuthority,
5932
5969
  markTrajectoryEndRecorded: () => {
5933
5970
  state.trajectoryEndRecorded = true;
5934
5971
  },
5935
- activateNativePreToolUseFailureFallback,
5936
- releaseSharedClientLeaseOnce,
5937
5972
  releaseSharedClientLeaseAndRetireOneShotClient,
5938
5973
  releaseSandboxExecEnvironment,
5939
5974
  runCleanupStep,
@@ -5985,7 +6020,6 @@ async function prepareCodexAttemptRoute(resources, turnRuntime, notifications, h
5985
6020
  await releaseCurrentRoute();
5986
6021
  resourceState.turnRoute = resourceState.turnRouter.reserveThread({ threadId: resourceState.thread.threadId });
5987
6022
  }
5988
- if (!resourceState.turnRoute) throw new Error("codex app-server turn route was not reserved");
5989
6023
  if (!resourceState.routeActivated) {
5990
6024
  if (!resourceState.nativeSubagentMonitor) await registerNativeSubagentMonitor(resourceState.thread.threadId);
5991
6025
  resourceState.detachRouteAbort = attachRouteAbort(resourceState.turnRoute);
@@ -6088,13 +6122,6 @@ async function prepareCodexAttemptRuntime(connection) {
6088
6122
  ...legacyScheduledAppRecoveryPrompt ? { extraSystemPrompt: [params.extraSystemPrompt, legacyScheduledAppRecoveryPrompt].filter((value) => Boolean(value?.trim())).join("\n\n") } : {},
6089
6123
  ...startupAuthProfileId ? { authProfileId: startupAuthProfileId } : {}
6090
6124
  };
6091
- const activeSessionId = params.sessionId;
6092
- const activeSessionFile = params.sessionFile;
6093
- const buildActiveRunAttemptParams = () => ({
6094
- ...runtimeParams,
6095
- sessionId: activeSessionId,
6096
- sessionFile: activeSessionFile
6097
- });
6098
6125
  const startupAuthAccountCacheKey = usesSupervisionConnection ? void 0 : startupPreparedAuth?.kind === "api-key" ? resolveCodexAppServerPreparedApiKeyCacheKey(startupPreparedAuth.apiKey) : startupPreparedAuth?.kind === "profile" ? startupPreparedAuth.snapshot?.secretFreeCacheKey : await resolveCodexAppServerAuthAccountCacheKey({
6099
6126
  authProfileId: startupAuthProfileId,
6100
6127
  authProfileStore: attemptAuthProfileStore,
@@ -6188,7 +6215,8 @@ async function prepareCodexAttemptRuntime(connection) {
6188
6215
  });
6189
6216
  const supervisedSearchFingerprint = usesSupervisionConnection && !mutable.startupBinding?.pendingSupervisionBranch ? mutable.startupBinding?.webSearchThreadConfigFingerprint : void 0;
6190
6217
  let nativeProviderWebSearchSupport;
6191
- if (webSearchPlan.kind !== "native-hosted" || supervisedSearchFingerprint === fingerprintJsonObject(resolveCodexWebSearchPlan({ disableTools: true }).threadConfig)) nativeProviderWebSearchSupport = "unsupported";
6218
+ if (isCodexResponsesOAuth(startupPreparedAuth)) nativeProviderWebSearchSupport = "supported";
6219
+ else if (webSearchPlan.kind !== "native-hosted" || supervisedSearchFingerprint === fingerprintJsonObject(resolveCodexWebSearchPlan({ disableTools: true }).threadConfig)) nativeProviderWebSearchSupport = "unsupported";
6192
6220
  else if (supervisedSearchFingerprint === fingerprintJsonObject(webSearchPlan.threadConfig)) nativeProviderWebSearchSupport = "supported";
6193
6221
  else nativeProviderWebSearchSupport = await resolveCodexProviderWebSearchSupport({
6194
6222
  clientFactory: attemptClientFactory,
@@ -6199,6 +6227,7 @@ async function prepareCodexAttemptRuntime(connection) {
6199
6227
  config: params.config,
6200
6228
  expectedNativeModelProvider: usesSupervisionConnection ? mutable.startupBinding?.modelProvider : void 0,
6201
6229
  modelProviderOverride: usesSupervisionConnection ? void 0 : resolveCodexAppServerThreadModelSelection({
6230
+ homeScope: appServer.start.homeScope,
6202
6231
  provider: params.provider,
6203
6232
  model: params.modelId,
6204
6233
  binding: mutable.startupBinding,
@@ -6222,10 +6251,6 @@ async function prepareCodexAttemptRuntime(connection) {
6222
6251
  connection,
6223
6252
  preparedAuthBinding,
6224
6253
  runtimeParams,
6225
- activeSessionId,
6226
- activeSessionFile,
6227
- buildActiveRunAttemptParams,
6228
- attemptAuthProfileStore,
6229
6254
  effectiveContextWindowInfo,
6230
6255
  effectiveContextTokenBudget,
6231
6256
  effectiveRuntimeProviderId,
@@ -6263,7 +6288,7 @@ function recordCodexDynamicToolResult(projector, call, response, protocolRespons
6263
6288
  //#endregion
6264
6289
  //#region extensions/codex/src/app-server/run-attempt-tools.ts
6265
6290
  function toTranscriptToolResult(response) {
6266
- const sanitized = sanitizeCodexToolResponse(response);
6291
+ const sanitized = sanitizeCodexAgentEventRecord({ ...response });
6267
6292
  const contentItems = Array.isArray(sanitized.contentItems) ? sanitized.contentItems : [];
6268
6293
  const result = {
6269
6294
  ...sanitized,
@@ -6299,32 +6324,6 @@ function formatUnsupportedCodexDynamicToolOutput(type) {
6299
6324
  const rawType = typeof type === "string" ? type.replace(/\s+/g, " ").trim() : "";
6300
6325
  return `[Unsupported Codex dynamic tool output: ${rawType ? truncateUtf16Safe(rawType, 80) : "unknown"}${rawType.length > 80 ? "..." : ""}]`;
6301
6326
  }
6302
- function createCodexDynamicToolExecutionRegistry() {
6303
- const executions = /* @__PURE__ */ new Map();
6304
- const keyFor = (call) => JSON.stringify([
6305
- call.threadId,
6306
- call.turnId,
6307
- call.callId
6308
- ]);
6309
- return {
6310
- get(call) {
6311
- return executions.get(keyFor(call));
6312
- },
6313
- claim(call, start) {
6314
- const existing = executions.get(keyFor(call));
6315
- if (existing) return {
6316
- execution: existing,
6317
- replayed: true
6318
- };
6319
- const execution = start();
6320
- executions.set(keyFor(call), execution);
6321
- return {
6322
- execution,
6323
- replayed: false
6324
- };
6325
- }
6326
- };
6327
- }
6328
6327
  function resolveCodexDynamicToolDirectNames(params, registeredTools, hostSystemAgentActive = false) {
6329
6328
  const names = [];
6330
6329
  if (hostSystemAgentActive && isSystemAgentOnlyCodexDynamicToolAllowlist(params.toolsAllow)) names.push("openclaw");
@@ -6444,7 +6443,7 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6444
6443
  tool: call.tool,
6445
6444
  toolCallId: call.callId
6446
6445
  });
6447
- const toolMeta = inferCodexDynamicToolMeta(call, resolveCodexToolProgressDetailMode(params.toolProgressDetail));
6446
+ const toolMeta = inferToolMetaFromArgs(call.tool, call.arguments, { detailMode: resolveCodexToolProgressDetailMode(params.toolProgressDetail) });
6448
6447
  const toolArgs = sanitizeCodexToolArguments(call.arguments);
6449
6448
  const commandBearing = isCodexCommandBearingToolCall(call.tool, toolArgs);
6450
6449
  const shouldEmitDynamicToolProgress = shouldEmitTranscriptToolProgress(call.tool);
@@ -6480,26 +6479,24 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6480
6479
  });
6481
6480
  setExecutionTimeoutMs?.(dynamicToolTimeoutMs);
6482
6481
  const toolStartedAt = Date.now();
6482
+ const diagnosticContext = {
6483
+ call,
6484
+ agentId: sessionAgentId,
6485
+ runId: params.runId,
6486
+ sessionId: params.sessionId,
6487
+ sessionKey: params.sessionKey
6488
+ };
6483
6489
  let terminalDiagnosticObserved = false;
6484
6490
  const unsubscribeToolDiagnosticObserver = onInternalDiagnosticEvent((event) => {
6485
6491
  if (isDynamicToolTerminalDiagnosticEvent(event) && isMatchingDynamicToolTerminalDiagnostic({
6486
- event,
6487
- call,
6488
- runId: params.runId,
6489
- sessionId: params.sessionId,
6490
- sessionKey: params.sessionKey
6492
+ ...diagnosticContext,
6493
+ event
6491
6494
  })) terminalDiagnosticObserved = true;
6492
6495
  }, { include: DYNAMIC_TOOL_TERMINAL_DIAGNOSTIC_TYPES });
6493
6496
  try {
6494
6497
  const { execution } = openClawDynamicToolExecutions.claim(call, async () => {
6495
6498
  await projector?.transcriptCheckpoint.flush();
6496
- emitDynamicToolStartedDiagnostic({
6497
- call,
6498
- agentId: sessionAgentId,
6499
- runId: params.runId,
6500
- sessionId: params.sessionId,
6501
- sessionKey: params.sessionKey
6502
- });
6499
+ emitDynamicToolStartedDiagnostic(diagnosticContext);
6503
6500
  const response = await handleDynamicToolCallWithTimeout({
6504
6501
  call,
6505
6502
  toolBridge,
@@ -6581,18 +6578,9 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6581
6578
  data: activity
6582
6579
  });
6583
6580
  }
6584
- if (!terminalDiagnosticObserved && !hasPendingDynamicToolTerminalDiagnostic({
6585
- call,
6586
- runId: params.runId,
6587
- sessionId: params.sessionId,
6588
- sessionKey: params.sessionKey
6589
- })) emitDynamicToolTerminalDiagnostic({
6581
+ if (!terminalDiagnosticObserved && !hasPendingDynamicToolTerminalDiagnostic(diagnosticContext)) emitDynamicToolTerminalDiagnostic({
6582
+ ...diagnosticContext,
6590
6583
  response,
6591
- call,
6592
- agentId: sessionAgentId,
6593
- runId: params.runId,
6594
- sessionId: params.sessionId,
6595
- sessionKey: params.sessionKey,
6596
6584
  durationMs: toolDurationMs
6597
6585
  });
6598
6586
  pendingOpenClawDynamicToolCompletionIds.delete(call.callId);
@@ -6610,17 +6598,8 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6610
6598
  return protocolResponse;
6611
6599
  } catch (error) {
6612
6600
  pendingOpenClawDynamicToolCompletionIds.delete(call.callId);
6613
- if (!terminalDiagnosticObserved && !hasPendingDynamicToolTerminalDiagnostic({
6614
- call,
6615
- runId: params.runId,
6616
- sessionId: params.sessionId,
6617
- sessionKey: params.sessionKey
6618
- })) emitDynamicToolErrorDiagnostic({
6619
- call,
6620
- agentId: sessionAgentId,
6621
- runId: params.runId,
6622
- sessionId: params.sessionId,
6623
- sessionKey: params.sessionKey,
6601
+ if (!terminalDiagnosticObserved && !hasPendingDynamicToolTerminalDiagnostic(diagnosticContext)) emitDynamicToolErrorDiagnostic({
6602
+ ...diagnosticContext,
6624
6603
  durationMs: Math.max(0, Date.now() - toolStartedAt)
6625
6604
  });
6626
6605
  await settlePluginRuntimeRefresh(turnId);
@@ -6643,11 +6622,11 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
6643
6622
  //#region extensions/codex/src/app-server/attempt-runtime-artifact.ts
6644
6623
  async function verifyStartupArtifact(params) {
6645
6624
  if (!params.request) return;
6646
- const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-CLZ8udh-.mjs");
6625
+ const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-DDQ-HGXf.mjs");
6647
6626
  const runtimeArtifact = readCodexAppServerClientRuntimeArtifact(params.client);
6648
6627
  const expected = params.request.expected;
6649
6628
  const matchesExpected = !expected || runtimeArtifact?.id === expected.id && runtimeArtifact.fingerprint === expected.fingerprint;
6650
- if (!runtimeArtifact || !matchesExpected || !await validateCodexAppServerRuntimeArtifact(runtimeArtifact, params.signal)) {
6629
+ if (!runtimeArtifact || !matchesExpected || !await validateCodexAppServerRuntimeArtifact(runtimeArtifact, params.signal, params.startOptions)) {
6651
6630
  retireSharedCodexAppServerClientIfCurrent(params.client);
6652
6631
  throw new Error(expected ? "Codex app-server runtime artifact does not match verified inference" : "Codex app-server runtime artifact is unavailable or stale");
6653
6632
  }
@@ -6676,7 +6655,6 @@ function startCodexComputerUseHealthMonitor(params) {
6676
6655
  if (existing) clearComputerUseHealthMonitor(params.client, existing);
6677
6656
  const monitor = {
6678
6657
  fingerprint,
6679
- intervalMs,
6680
6658
  timer: setInterval(() => {
6681
6659
  runCodexComputerUseHealthProbe(params.client, params.config, monitor, params.tools);
6682
6660
  }, intervalMs),
@@ -6712,9 +6690,9 @@ async function runCodexComputerUseHealthProbe(client, config, monitor, tools) {
6712
6690
  client,
6713
6691
  config,
6714
6692
  tools,
6715
- request: async (method, requestParams, requestOptions) => await client.request(method, requestParams, {
6716
- timeoutMs: requestOptions?.timeoutMs ?? config.liveTestTimeoutMs,
6717
- ...requestOptions?.signal ? { signal: requestOptions.signal } : {}
6693
+ request: createComputerUseRequest({
6694
+ client,
6695
+ timeoutMs: config.liveTestTimeoutMs
6718
6696
  })
6719
6697
  });
6720
6698
  if (!liveTest.ok) {
@@ -6756,8 +6734,8 @@ var CodexPluginThreadConfigDeadlineError = class extends Error {
6756
6734
  };
6757
6735
  /** Resolves the plugin policy state reused throughout app-server startup. */
6758
6736
  function resolveCodexPluginThreadConfigStartupPolicy(params) {
6759
- const pluginThreadConfigRequired = Boolean(params.scheduledRuntimeAuthority) || !params.nativeToolSurfaceEnabled || shouldBuildCodexPluginThreadConfig(params.pluginConfig);
6760
- const pluginThreadConfigPluginConfig = params.nativeToolSurfaceEnabled || params.scheduledRuntimeAuthority ? params.pluginConfig : disableCodexPluginThreadConfig(params.pluginConfig);
6737
+ const pluginThreadConfigRequired = params.hostedAppsSupported === false || Boolean(params.scheduledRuntimeAuthority) || !params.nativeToolSurfaceEnabled || shouldBuildCodexPluginThreadConfig(params.pluginConfig);
6738
+ const pluginThreadConfigPluginConfig = params.hostedAppsSupported !== false && (params.nativeToolSurfaceEnabled || params.scheduledRuntimeAuthority) ? params.pluginConfig : disableCodexPluginThreadConfig(params.pluginConfig);
6761
6739
  const resolvedPluginPolicy = pluginThreadConfigRequired ? resolveCodexPluginsPolicy(pluginThreadConfigPluginConfig) : void 0;
6762
6740
  return {
6763
6741
  pluginThreadConfigRequired,
@@ -6771,10 +6749,10 @@ async function buildCodexPluginThreadConfigWithinDeadline(params) {
6771
6749
  const { requestTimeoutMs, signal, request, failClosedOnTimeout, transform, ...buildParams } = params;
6772
6750
  signal.throwIfAborted();
6773
6751
  const timeoutMs = resolveCodexPluginThreadConfigTimeoutMs(requestTimeoutMs);
6774
- const deadlineMs = Date.now() + timeoutMs;
6752
+ const deadlineMs = performance.now() + timeoutMs;
6775
6753
  let requestTimedOut = false;
6776
6754
  const boundedRequest = async (method, requestParams) => {
6777
- const remainingTimeoutMs = deadlineMs - Date.now();
6755
+ const remainingTimeoutMs = deadlineMs - performance.now();
6778
6756
  if (requestTimedOut || remainingTimeoutMs <= 0) throw new CodexPluginThreadConfigDeadlineError();
6779
6757
  try {
6780
6758
  return await request(method, requestParams, {
@@ -6796,14 +6774,14 @@ async function buildCodexPluginThreadConfigWithinDeadline(params) {
6796
6774
  request: boundedRequest
6797
6775
  });
6798
6776
  const result = transform ? await transform(config, boundedRequest) : config;
6799
- if (requestTimedOut || Date.now() >= deadlineMs) throw new CodexPluginThreadConfigDeadlineError();
6777
+ if (requestTimedOut || performance.now() >= deadlineMs) throw new CodexPluginThreadConfigDeadlineError();
6800
6778
  return result;
6801
6779
  })(),
6802
6780
  timeoutMessage: "Codex plugin thread config deadline elapsed",
6803
6781
  createTimeoutError: () => new CodexPluginThreadConfigDeadlineError()
6804
6782
  });
6805
6783
  } catch (error) {
6806
- if (signal.aborted || !requestTimedOut && !isCodexPluginThreadConfigTimeoutError(error) && Date.now() < deadlineMs) throw error;
6784
+ if (signal.aborted || !requestTimedOut && !isCodexPluginThreadConfigTimeoutError(error) && performance.now() < deadlineMs) throw error;
6807
6785
  if (failClosedOnTimeout) throw new AgentHarnessPreflightError(`Codex app policy verification exceeded its ${timeoutMs} ms startup budget. No app tools were executed. Retry after Codex app inventory is responsive.`);
6808
6786
  return buildCodexPluginThreadConfigTimeoutFallback({
6809
6787
  pluginConfig: buildParams.pluginConfig,
@@ -6835,7 +6813,11 @@ function createCodexPluginThreadConfigStartupProvider(params) {
6835
6813
  appCache: appCache ?? defaultCodexAppInventoryCache,
6836
6814
  metadataCache,
6837
6815
  failClosedOnTimeout: Boolean(params.scheduledRuntimeAuthority),
6838
- transform: params.scheduledRuntimeAuthority ? async (builtConfig, request) => intersectCodexPluginThreadConfigWithScheduledAuthority(builtConfig, params.scheduledRuntimeAuthority, await readCurrentCodexScheduledAppPolicy(request, params.configCwd, buildOptions?.threadId)) : void 0,
6816
+ transform: params.scheduledRuntimeAuthority ? async (builtConfig, request) => intersectCodexPluginThreadConfigWithScheduledAuthority(builtConfig, params.scheduledRuntimeAuthority, await readCurrentCodexScheduledAppPolicy({
6817
+ request,
6818
+ configCwd: params.configCwd,
6819
+ threadId: buildOptions?.threadId
6820
+ })) : void 0,
6839
6821
  request: (method, requestParams, options) => client.request(method, requestParams, options)
6840
6822
  });
6841
6823
  return params.scheduledRuntimeAuthority && params.inputFingerprint ? {
@@ -6845,13 +6827,6 @@ function createCodexPluginThreadConfigStartupProvider(params) {
6845
6827
  }
6846
6828
  };
6847
6829
  }
6848
- async function readCurrentCodexScheduledAppPolicy(request, cwd, threadId) {
6849
- return await readCurrentCodexScheduledAppPolicy$1({
6850
- request,
6851
- configCwd: cwd,
6852
- threadId
6853
- });
6854
- }
6855
6830
  function resolveCodexPluginThreadConfigTimeoutMs(requestTimeoutMs) {
6856
6831
  return Math.min(CODEX_PLUGIN_THREAD_CONFIG_MAX_TIMEOUT_MS, Math.max(CODEX_PLUGIN_THREAD_CONFIG_MIN_TIMEOUT_MS, Math.floor((Number.isFinite(requestTimeoutMs) && requestTimeoutMs > 0 ? requestTimeoutMs : CODEX_PLUGIN_THREAD_CONFIG_MAX_TIMEOUT_MS * CODEX_PLUGIN_THREAD_CONFIG_TIMEOUT_DIVISOR) / CODEX_PLUGIN_THREAD_CONFIG_TIMEOUT_DIVISOR)));
6857
6832
  }
@@ -6860,20 +6835,7 @@ function isCodexPluginThreadConfigTimeoutError(error) {
6860
6835
  }
6861
6836
  //#endregion
6862
6837
  //#region extensions/codex/src/app-server/attempt-startup.ts
6863
- /**
6864
- * Startup orchestration for Codex app-server attempts, including shared-client
6865
- * leasing, plugin thread config, sandbox environment, and thread lifecycle binding.
6866
- */
6867
6838
  const CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS = 3;
6868
- const CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED = "CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED";
6869
- /** True when a pre-write context restart must replay on the newly selected owner. */
6870
- function isCodexContextRestartSelectionChangedError(error) {
6871
- return error instanceof Error && "code" in error && error.code === CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED;
6872
- }
6873
- /**
6874
- * Starts or resumes the Codex app-server thread and returns the resources the
6875
- * run loop must later release.
6876
- */
6877
6839
  async function startCodexAttemptThread(params) {
6878
6840
  let pluginAppServer = params.appServer;
6879
6841
  const startupRuntimeAuthProfileId = params.startupPreparedAuth?.kind === "profile" ? params.startupPreparedAuth.profileId : params.startupAuthProfileId ?? void 0;
@@ -6902,6 +6864,7 @@ async function startCodexAttemptThread(params) {
6902
6864
  const { pluginThreadConfigRequired, pluginThreadConfigPluginConfig, resolvedPluginPolicy, enabledPluginConfigKeys } = resolveCodexPluginThreadConfigStartupPolicy({
6903
6865
  pluginConfig: params.pluginConfig,
6904
6866
  nativeToolSurfaceEnabled: params.nativeToolSurfaceEnabled,
6867
+ hostedAppsSupported: !isCodexResponsesOAuth(params.startupPreparedAuth),
6905
6868
  scheduledRuntimeAuthority: params.buildAttemptParams().scheduledRuntimeAuthority
6906
6869
  });
6907
6870
  pluginAppServer = resolvedPluginPolicy?.enabled === true || params.computerUseConfig.enabled || params.nativeToolSurfaceEnabled && params.configuredMcpOwnershipVersion !== 1 && hasCodexMcpToolApprovalOverrides(params.config?.mcp?.servers, params.bundleMcpThreadConfig.userStaticServerNames, params.bundleMcpThreadConfig.configPatch?.mcp_servers) ? {
@@ -6954,6 +6917,7 @@ async function startCodexAttemptThread(params) {
6954
6917
  if (startupAbandonController.signal.aborted) throw new CodexAppServerStartupError("aborted");
6955
6918
  const runtimeArtifact = await verifyStartupArtifact({
6956
6919
  client: activeStartupClient,
6920
+ startOptions: params.appServer.start,
6957
6921
  request: params.runtimeArtifactRequest,
6958
6922
  signal: startupAbandonController.signal
6959
6923
  });
@@ -6961,21 +6925,28 @@ async function startCodexAttemptThread(params) {
6961
6925
  ensureCodexAppServerClientRuntime(activeStartupClient, {
6962
6926
  agentDir: params.agentDir,
6963
6927
  authProfileId: startupRuntimeAuthProfileId,
6964
- authMode: params.startupPreparedAuth?.kind === "api-key" ? "prepared-api-key" : "profile",
6928
+ authMode: params.startupPreparedAuth?.kind === "api-key" || isCodexResponsesOAuth(params.startupPreparedAuth) ? "prepared-api-key" : "profile",
6965
6929
  authProfileStore: startupRuntimeAuthProfileStore ?? attemptParams.authProfileStore,
6966
6930
  config: params.config
6967
6931
  });
6968
6932
  const turnRouter = getCodexAppServerTurnRouter(activeStartupClient);
6969
6933
  let computerUseTools = [];
6934
+ let computerUseConfig = params.computerUseConfig;
6970
6935
  try {
6971
- computerUseTools = (await ensureCodexComputerUse({
6936
+ const computerUseStatus = await ensureCodexComputerUse({
6972
6937
  client: activeStartupClient,
6973
6938
  pluginConfig: params.pluginConfig,
6974
6939
  config: params.config,
6975
6940
  agentDir: params.agentDir,
6976
6941
  timeoutMs: params.appServer.requestTimeoutMs,
6977
6942
  signal: startupAbandonController.signal
6978
- })).tools;
6943
+ });
6944
+ computerUseTools = computerUseStatus.tools;
6945
+ computerUseConfig = {
6946
+ ...computerUseConfig,
6947
+ pluginName: computerUseStatus.pluginName,
6948
+ mcpServerName: computerUseStatus.mcpServerName
6949
+ };
6979
6950
  } catch (error) {
6980
6951
  if (startupAbandonController.signal.aborted || isCodexAppServerStartSelectionChangedError(error)) throw error;
6981
6952
  throw new AgentHarnessPreflightError(`Codex Computer Use readiness failed: ${formatErrorMessage(error)}`, {
@@ -7089,14 +7060,17 @@ async function startCodexAttemptThread(params) {
7089
7060
  webSearchAllowed: params.webSearchAllowed,
7090
7061
  appServer: pluginAppServer,
7091
7062
  developerInstructions: params.developerInstructions,
7063
+ skillsInstructions: params.skillsInstructions,
7092
7064
  agentWorkspaceDeveloperInstructions: params.agentWorkspaceDeveloperInstructions,
7093
7065
  config: threadConfig,
7094
7066
  shellEnvironment: params.shellEnvironment,
7067
+ shellPathPrepend: params.shellPathPrepend,
7095
7068
  disableLoginShell: params.disableLoginShell,
7096
7069
  finalConfigPatch: params.finalConfigPatch,
7097
7070
  buildFinalConfigPatch: params.buildFinalConfigPatch,
7098
7071
  nativeHookRelayGeneration: params.nativeHookRelayGeneration,
7099
7072
  nativeHookRelayRequired: params.nativeHookRelayRequired,
7073
+ nativeModelAdmission: params.nativeModelAdmission,
7100
7074
  nativeCodeModeEnabled: params.nativeToolSurfaceEnabled,
7101
7075
  nativeProviderWebSearchSupport: params.nativeProviderWebSearchSupport,
7102
7076
  nativeCodeModeOnlyEnabled: params.appServer.codeModeOnly,
@@ -7138,7 +7112,7 @@ async function startCodexAttemptThread(params) {
7138
7112
  startupSandboxEnvironmentAcquired = false;
7139
7113
  startCodexComputerUseHealthMonitor({
7140
7114
  client: activeStartupClient,
7141
- config: params.computerUseConfig,
7115
+ config: computerUseConfig,
7142
7116
  tools: computerUseTools
7143
7117
  });
7144
7118
  startupAttemptSucceeded = true;
@@ -7154,7 +7128,10 @@ async function startCodexAttemptThread(params) {
7154
7128
  ...runtimeArtifact ? { runtimeArtifact } : {},
7155
7129
  restartContextEngineCodexThread: async () => {
7156
7130
  try {
7157
- return await startOrResumeThread(buildThreadLifecycleParams(params.signal));
7131
+ return await startOrResumeThread({
7132
+ ...buildThreadLifecycleParams(params.signal),
7133
+ contextEngineProjection: void 0
7134
+ });
7158
7135
  } catch (error) {
7159
7136
  if (!isCodexAppServerStartSelectionChangedError(error)) throw error;
7160
7137
  retireSharedCodexAppServerClientIfCurrent(activeStartupClient);
@@ -7195,7 +7172,7 @@ async function startCodexAttemptThread(params) {
7195
7172
  } catch (error) {
7196
7173
  const selectionChanged = isCodexAppServerStartSelectionChangedError(error);
7197
7174
  const clientRetired = error instanceof CodexThreadClientReplacementError;
7198
- if (startupAbandonController.signal.aborted || clientRetired && replacedSettledFailureClient || !clientRetired && !selectionChanged && !isCodexAppServerConnectionClosedError(error)) throw error;
7175
+ if (startupAbandonController.signal.aborted || isCodexWebSocketOpenFailure(error) || clientRetired && replacedSettledFailureClient || !clientRetired && !selectionChanged && !isCodexAppServerConnectionClosedError(error)) throw error;
7199
7176
  replacedSettledFailureClient ||= clientRetired;
7200
7177
  const refreshedSharedClient = clientRetired ? void 0 : selectionChanged ? retireSharedCodexAppServerClientIfCurrent(attemptedClient) : clearSharedCodexAppServerClientIfCurrent(attemptedClient);
7201
7178
  if (startupClientForAbandonedRequestCleanup === attemptedClient) startupClientForAbandonedRequestCleanup = void 0;
@@ -7246,7 +7223,7 @@ async function startCodexAttemptRuntime(resources) {
7246
7223
  const { prompt, state, trajectoryRecorder, startupTimeoutMs, buildNativeHookRelayFinalConfigPatch } = resources;
7247
7224
  const { context, turnState, rebuildCodexTurnPromptTextFromCurrentProjection, applyNoContextEngineContinuityProjection } = prompt;
7248
7225
  const { runtime, attemptTools, promptState } = context;
7249
- const { connection, runtimeParams, preparedAuthBinding, buildActiveRunAttemptParams, startupAuthAccountCacheKey, startupEnvApiKeyCacheKey, bundleMcpThreadConfig, nativeToolSurfaceEnabled, nativeProviderWebSearchSupport, effectiveRuntimeModelId, sandboxExecServerEnabled } = runtime;
7226
+ const { connection, runtimeParams, preparedAuthBinding, startupAuthAccountCacheKey, startupEnvApiKeyCacheKey, bundleMcpThreadConfig, nativeToolSurfaceEnabled, nativeProviderWebSearchSupport, effectiveRuntimeModelId, sandboxExecServerEnabled } = runtime;
7250
7227
  const { toolBridge, toolState } = attemptTools;
7251
7228
  const developerInstructions = joinPresentSections(turnState.promptBuild.developerInstructions, attemptTools.configuredMcp?.diagnosticNotice);
7252
7229
  const { params, attemptClientFactory, bindingStore, appServer, pluginConfig, computerUseConfig, startupClientAuthProfileId, runtimeArtifactRequest, startupPreparedAuth, agentDir, sessionAgentId, effectiveWorkspace, effectiveCwd, sandbox, runAbortController, usesSupervisionConnection, resolveReviewerPolicyContext, resolveRuntimeOptionsForCurrentBinding, startupAuthProfileId, startupAuthRequirement } = connection;
@@ -7275,8 +7252,9 @@ async function startCodexAttemptRuntime(resources) {
7275
7252
  agentDir,
7276
7253
  config: params.config,
7277
7254
  shellEnvironment: connection.shellEnvironment,
7255
+ shellPathPrepend: connection.shellPathPrepend,
7278
7256
  disableLoginShell: connection.disableLoginShell,
7279
- buildAttemptParams: buildActiveRunAttemptParams,
7257
+ buildAttemptParams: () => ({ ...runtimeParams }),
7280
7258
  ...effectiveRuntimeModelId !== runtimeParams.modelId ? { runtimeModelId: effectiveRuntimeModelId } : {},
7281
7259
  sessionAgentId,
7282
7260
  effectiveWorkspace,
@@ -7285,9 +7263,11 @@ async function startCodexAttemptRuntime(resources) {
7285
7263
  persistentWebSearchAllowed: toolState.persistentWebSearchAllowed,
7286
7264
  webSearchAllowed: toolState.webSearchAllowed,
7287
7265
  developerInstructions,
7266
+ skillsInstructions: context.skillsInstructions,
7288
7267
  agentWorkspaceDeveloperInstructions: context.agentWorkspaceDeveloperInstructions,
7289
7268
  buildFinalConfigPatch: buildNativeHookRelayFinalConfigPatch,
7290
- nativeHookRelayRequired: Boolean(resources.nativeProcessAuthority && nativeToolSurfaceEnabled) || connection.options.nativeHookRelay?.enabled !== false && params.pluginHarnessToolPolicyRestricted !== true && connection.nativeHookRelayEvents.includes("pre_tool_use") && (hasBeforeToolCallPolicy() || appServer.loopDetectionPreToolUseRelay && Boolean(connection.sandboxSessionKey) && loopDetectionEnabled),
7269
+ nativeModelAdmission: resources.nativeModelAdmission,
7270
+ nativeHookRelayRequired: nativeToolSurfaceEnabled && params.pluginHarnessToolPolicyRestricted !== true && (resources.nativeProcessAuthority?.requiresProcessAdmission || resources.nativeModelAdmission === "required") || connection.options.nativeHookRelay?.enabled !== false && params.pluginHarnessToolPolicyRestricted !== true && connection.nativeHookRelayEvents.includes("pre_tool_use") && (hasBeforeToolCallPolicy() || appServer.loopDetectionPreToolUseRelay && Boolean(connection.sandboxSessionKey) && loopDetectionEnabled),
7291
7271
  bundleMcpThreadConfig,
7292
7272
  configuredMcpDynamicSurface: attemptTools.configuredMcp !== void 0,
7293
7273
  configuredMcpOwnershipVersion: attemptTools.configuredMcpOwnershipVersion,
@@ -7378,6 +7358,53 @@ async function startCodexAttemptRuntime(resources) {
7378
7358
  }
7379
7359
  }
7380
7360
  //#endregion
7361
+ //#region extensions/codex/src/app-server/heartbeat-tool-fallback.ts
7362
+ const InactiveHeartbeatResponseParameters = Type.Object({}, { additionalProperties: true });
7363
+ function resolveInactiveCodexHeartbeatResponseDescriptor(params) {
7364
+ if (params.registeredSpecs) {
7365
+ const spec = flattenCodexDynamicToolFunctions(params.registeredSpecs).find((tool) => tool.name === HEARTBEAT_RESPONSE_TOOL_NAME);
7366
+ return spec ? {
7367
+ name: spec.name,
7368
+ description: spec.description
7369
+ } : void 0;
7370
+ }
7371
+ const descriptor = params.registeredTools.find((tool) => tool.name === HEARTBEAT_RESPONSE_TOOL_NAME);
7372
+ return descriptor ? {
7373
+ name: descriptor.name,
7374
+ description: descriptor.description
7375
+ } : void 0;
7376
+ }
7377
+ /** Keeps the thread-stable heartbeat endpoint executable on ordinary Codex turns. */
7378
+ function createInactiveCodexHeartbeatResponseTool(descriptor) {
7379
+ if (descriptor.name !== HEARTBEAT_RESPONSE_TOOL_NAME) throw new Error(`Expected ${HEARTBEAT_RESPONSE_TOOL_NAME}, received ${descriptor.name}`);
7380
+ return {
7381
+ name: descriptor.name,
7382
+ label: descriptor.name,
7383
+ description: descriptor.description,
7384
+ parameters: InactiveHeartbeatResponseParameters,
7385
+ execute: async (_toolCallId, args) => {
7386
+ const response = normalizeHeartbeatToolResponse(args);
7387
+ if (!response) throw new Error("Invalid heartbeat response. Provide outcome, notify, and non-empty summary.");
7388
+ if (response.notify) throw new Error("heartbeat_respond cannot send notifications outside a heartbeat turn");
7389
+ return {
7390
+ content: [{
7391
+ type: "text",
7392
+ text: "No heartbeat is active for this turn. Continue the current task and respond normally."
7393
+ }],
7394
+ details: {
7395
+ status: "ignored",
7396
+ reason: "non-heartbeat-turn"
7397
+ }
7398
+ };
7399
+ }
7400
+ };
7401
+ }
7402
+ function selectInactiveCodexHeartbeatResponseTool(params) {
7403
+ if (params.disableTools) return;
7404
+ const allowed = applyEmbeddedAttemptToolsAllow([createInactiveCodexHeartbeatResponseTool(params.descriptor)], params.toolsAllow);
7405
+ return filterCodexDynamicTools(allowed, params.pluginConfig)[0];
7406
+ }
7407
+ //#endregion
7381
7408
  //#region extensions/codex/src/app-server/run-attempt-tool-setup.ts
7382
7409
  function isAuthorityResolutionOperationAbort(error, signal) {
7383
7410
  return signal?.aborted === true && error === signal.reason;
@@ -7386,7 +7413,7 @@ async function prepareCodexAttemptTools(runtime) {
7386
7413
  const { connection, bundleMcpThreadConfig, bundleManifestRegistry, runtimeParams, effectiveRuntimeModelId, nativeToolSurfaceEnabled, nativeProviderWebSearchSupport, hookChannelId, codexMcpToolOverrides, authenticatedScheduledMode, configuredMcpSurface, canResolveScheduledConfiguredMcpCreatorAuthority } = runtime;
7387
7414
  const { params, preDynamicStartupStages, mutable, resolvedWorkspace, effectiveWorkspace, effectiveCwd, sandboxSessionKey, contextSessionKey, sandbox, sessionPermissionPolicy, runAbortController, sessionAgentId, policyAgentId, pluginConfig, profilerEnabled, agentDir } = connection;
7388
7415
  const preDynamicSummary = preDynamicStartupStages.snapshot();
7389
- if (shouldWarnCodexDynamicToolBuildStageSummary(preDynamicSummary, profilerEnabled)) embeddedAgentLog.warn(`codex app-server pre-dynamic startup timings runId=${params.runId} sessionId=${params.sessionId} totalMs=${preDynamicSummary.totalMs} stages=${formatCodexDynamicToolBuildStageSummary(preDynamicSummary)}`, {
7416
+ if (shouldWarnCodexDynamicToolBuildStageSummary(preDynamicSummary, profilerEnabled)) embeddedAgentLog.warn(`codex app-server pre-dynamic startup timings runId=${params.runId} sessionId=${params.sessionId} totalMs=${preDynamicSummary.totalMs} stages=${formatStageTimings(preDynamicSummary.stages)}`, {
7390
7417
  runId: params.runId,
7391
7418
  sessionId: params.sessionId,
7392
7419
  totalMs: preDynamicSummary.totalMs,
@@ -7441,7 +7468,7 @@ async function prepareCodexAttemptTools(runtime) {
7441
7468
  } : void 0;
7442
7469
  const scheduledCodexAppAuth = preparedChatgptAuth ?? configuredAppServerAuth;
7443
7470
  const appPolicy = resolveCodexPluginsPolicy(pluginConfig);
7444
- const codexAppsMayBeVisible = appPolicy.enabled && (appPolicy.allowAllPlugins || appPolicy.pluginPolicies.some((entry) => entry.enabled));
7471
+ const codexAppsMayBeVisible = !isCodexResponsesOAuth(connection.startupPreparedAuth) && appPolicy.enabled && (appPolicy.allowAllPlugins || appPolicy.pluginPolicies.some((entry) => entry.enabled));
7445
7472
  const appCreatorCapture = resolveScheduledCodexAppCreatorCaptureDecision({
7446
7473
  appsMayBeVisible: codexAppsMayBeVisible,
7447
7474
  authenticatedScheduledMode,
@@ -7612,20 +7639,8 @@ async function prepareCodexAttemptTools(runtime) {
7612
7639
  const reservedToolNames = [...tools.map((tool) => tool.name), ...registeredTools.map((tool) => tool.name)];
7613
7640
  const turnSourceChannel = params.messageChannel ?? params.messageProvider;
7614
7641
  const turnSourceTo = params.currentMessagingTarget ?? params.currentChannelId;
7615
- const requester = {
7616
- ...turnSourceChannel ? { channel: turnSourceChannel } : {},
7617
- ...params.agentAccountId ? { accountId: params.agentAccountId } : {},
7618
- ...params.senderId ? { senderId: params.senderId } : {},
7619
- ...params.senderIsOwner !== void 0 ? { senderIsOwner: params.senderIsOwner } : {},
7620
- ...params.memberRoleIds?.length ? { roleIds: [...params.memberRoleIds] } : {}
7621
- };
7622
- const hasRequester = Object.keys(requester).length > 0;
7623
- const requestInteractiveMcpApproval = async (approval) => {
7624
- const allowedDecisions = approval.mode === "prompt" ? ["allow-once", "deny"] : [
7625
- "allow-once",
7626
- "allow-always",
7627
- "deny"
7628
- ];
7642
+ const requester = buildCodexHookRequester(params);
7643
+ const requestInteractiveMcpApproval = async (approval, allowedDecisions) => {
7629
7644
  const outcome = await requestPluginApprovalOutcome({
7630
7645
  hostCapabilities: params.hostCapabilities,
7631
7646
  signal: approval.signal,
@@ -7642,57 +7657,39 @@ async function prepareCodexAttemptTools(runtime) {
7642
7657
  });
7643
7658
  if (outcome !== "approved-once" && outcome !== "approved-session") throw new Error(`${approval.serverName}/${approval.toolName}: interactive Codex approval (${approval.mode}) was not granted: ${outcome}`);
7644
7659
  };
7645
- const requestRequesterMcpApproval = async (approval) => {
7646
- const outcome = await requestPluginApprovalOutcome({
7647
- hostCapabilities: params.hostCapabilities,
7648
- signal: approval.signal,
7649
- title: `Run MCP tool ${approval.serverName}/${approval.toolName}`,
7650
- description: `Codex approval mode "${approval.mode}" requires an operator decision before this MCP tool runs. ${formatMcpCodexApprovalRemedy(approval.serverName)}`,
7651
- allowedDecisions: ["allow-once", "deny"],
7652
- toolName: approval.safeToolName,
7653
- toolCallId: approval.toolCallId,
7654
- mcpTool: {
7655
- server: approval.serverName,
7656
- tool: approval.toolName
7657
- },
7658
- isMcpToolApprovalActive: approval.isActive
7659
- });
7660
- if (outcome !== "approved-once" && outcome !== "approved-session") throw new Error(`${approval.serverName}/${approval.toolName}: interactive Codex approval (${approval.mode}) was not granted: ${outcome}`);
7661
- };
7662
- configuredMcp = configuredMcpSurface ? await materializeStaticMcpToolsForHarnessRun({
7663
- sessionId: params.sessionId,
7664
- sessionKey: params.sessionKey,
7665
- agentId: sessionAgentId,
7660
+ const mcpOptions = {
7666
7661
  workspaceDir: effectiveWorkspace,
7667
7662
  agentDir: policyContext.agentDir,
7668
7663
  cfg: params.config,
7669
7664
  manifestRegistry: bundleManifestRegistry,
7670
- reservedToolNames,
7671
7665
  toolsAllow: params.toolsAllow,
7672
7666
  toolOverrides: codexMcpToolOverrides,
7673
7667
  autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
7674
- projectedMcpServers: bundleMcpThreadConfig.configPatch?.mcp_servers,
7675
- ...configuredMcpSurface === "transient" ? { requestInteractiveCodexApproval: requestInteractiveMcpApproval } : {},
7676
7668
  policyContext,
7677
7669
  warn: (message) => embeddedAgentLog.warn(message)
7670
+ };
7671
+ configuredMcp = configuredMcpSurface ? await materializeStaticMcpToolsForHarnessRun({
7672
+ ...mcpOptions,
7673
+ sessionId: params.sessionId,
7674
+ sessionKey: params.sessionKey,
7675
+ agentId: sessionAgentId,
7676
+ reservedToolNames,
7677
+ projectedMcpServers: bundleMcpThreadConfig.configPatch?.mcp_servers,
7678
+ ...configuredMcpSurface === "transient" ? { requestInteractiveCodexApproval: (approval) => requestInteractiveMcpApproval(approval, approval.mode === "prompt" ? ["allow-once", "deny"] : [
7679
+ "allow-once",
7680
+ "allow-always",
7681
+ "deny"
7682
+ ]) } : {}
7678
7683
  }) : void 0;
7679
7684
  scopedMcpTools = authenticatedScheduledMode ? void 0 : await materializeRequesterScopedMcpToolsForHarnessRun({
7685
+ ...mcpOptions,
7680
7686
  sessionId: params.sessionId,
7681
7687
  sessionKey: params.sessionKey,
7682
- workspaceDir: effectiveWorkspace,
7683
- agentDir: policyContext.agentDir,
7684
- cfg: params.config,
7685
- manifestRegistry: bundleManifestRegistry,
7686
- toolOverrides: codexMcpToolOverrides,
7687
- autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
7688
- requestInteractiveCodexApproval: requestRequesterMcpApproval,
7688
+ requestInteractiveCodexApproval: (approval) => requestInteractiveMcpApproval(approval, ["allow-once", "deny"]),
7689
7689
  requesterSenderId: params.senderId,
7690
7690
  agentAccountId: params.agentAccountId,
7691
7691
  messageChannel: params.messageChannel ?? params.messageProvider,
7692
- reservedToolNames: [...reservedToolNames, ...configuredMcp?.tools.map((tool) => tool.name) ?? []],
7693
- toolsAllow: params.toolsAllow,
7694
- policyContext,
7695
- warn: (message) => embeddedAgentLog.warn(message)
7692
+ reservedToolNames: [...reservedToolNames, ...configuredMcp?.tools.map((tool) => tool.name) ?? []]
7696
7693
  });
7697
7694
  const scopedExecutable = filterCodexDynamicTools([...configuredMcp?.tools ?? [], ...scopedMcpTools?.tools ?? []], pluginConfig);
7698
7695
  const scopedAdvertised = filterCodexDynamicTools([...configuredMcp?.tools ?? [], ...scopedMcpTools?.advertisedTools ?? []], pluginConfig);
@@ -7721,19 +7718,32 @@ async function prepareCodexAttemptTools(runtime) {
7721
7718
  allocateToolOutcomeOrdinal: allocateCodexToolOutcomeOrdinal,
7722
7719
  trigger: params.trigger,
7723
7720
  approvalReviewerDeviceId: params.approvalReviewerDeviceId,
7724
- ...hasRequester ? { requester } : {},
7721
+ ...requester ? { requester } : {},
7725
7722
  ...turnSourceChannel ? { turnSourceChannel } : {},
7726
7723
  ...turnSourceTo ? { turnSourceTo } : {},
7727
7724
  ...params.agentAccountId ? { turnSourceAccountId: params.agentAccountId } : {},
7728
7725
  ...params.currentThreadTs !== void 0 ? { turnSourceThreadId: params.currentThreadTs } : {}
7729
7726
  };
7727
+ const heartbeatFallbackDescriptor = resolveInactiveCodexHeartbeatResponseDescriptor({
7728
+ registeredTools: registeredWithScopedMcp,
7729
+ ...nativeSpecs ? { registeredSpecs: nativeSpecs } : {}
7730
+ });
7731
+ const heartbeatFallbackTool = heartbeatFallbackDescriptor && supportsModelTools(params.model) ? selectInactiveCodexHeartbeatResponseTool({
7732
+ descriptor: heartbeatFallbackDescriptor,
7733
+ disableTools: params.disableTools,
7734
+ toolsAllow: params.toolsAllow,
7735
+ pluginConfig
7736
+ }) : void 0;
7737
+ const registeredFallbackTools = params.trigger === "heartbeat" || params.enableHeartbeatTool === true || params.forceHeartbeatTool === true || !heartbeatFallbackTool ? void 0 : params.hostCapabilities.bindToolSurface([heartbeatFallbackTool], { cwd: effectiveCwd ?? effectiveWorkspace });
7730
7738
  const toolBridge = createCodexDynamicToolBridge({
7731
7739
  tools: toolsWithScopedMcp,
7732
7740
  registeredTools: registeredWithScopedMcp,
7741
+ registeredFallbackTools,
7733
7742
  registeredSpecs: nativeSpecs,
7734
7743
  signal: runAbortController.signal,
7735
7744
  computerContextEpoch,
7736
- loading: resolveCodexDynamicToolsLoadingForRuntime(pluginConfig, effectiveRuntimeModelId, { connectionClass: connection.appServer.connectionClass }),
7745
+ functionToolsOnly: isCodexResponsesOAuth(connection.startupPreparedAuth),
7746
+ loading: isCodexResponsesOAuth(connection.startupPreparedAuth) ? "direct" : resolveCodexDynamicToolsLoadingForRuntime(pluginConfig, effectiveRuntimeModelId, { connectionClass: connection.appServer.connectionClass }),
7737
7747
  directToolNames: resolveCodexDynamicToolDirectNames(params, registeredWithScopedMcp, isHostScopedAgentToolActive("openclaw")),
7738
7748
  hookContext
7739
7749
  });
@@ -7757,19 +7767,11 @@ async function prepareCodexAttemptTools(runtime) {
7757
7767
  try {
7758
7768
  if (canResolveScheduledConfiguredMcpCreatorAuthority) try {
7759
7769
  materialized = await materializeStaticMcpToolsForHarnessRun({
7770
+ ...mcpOptions,
7760
7771
  sessionId: `cron-authority:${params.runId}`,
7761
7772
  agentId: sessionAgentId,
7762
- workspaceDir: effectiveWorkspace,
7763
- agentDir: policyContext.agentDir,
7764
- cfg: params.config,
7765
- manifestRegistry: bundleManifestRegistry,
7766
7773
  reservedToolNames: configuredMcp ? reservedToolNames : toolBridge.availableTools.map((tool) => tool.name),
7767
- toolsAllow: params.toolsAllow,
7768
- toolOverrides: codexMcpToolOverrides,
7769
- autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
7770
7774
  projectedMcpServers: bundleMcpThreadConfig.configPatch?.mcp_servers,
7771
- policyContext,
7772
- warn: (message) => embeddedAgentLog.warn(message),
7773
7775
  retireSessionRuntimeAfterDispose: true
7774
7776
  });
7775
7777
  } catch (error) {
@@ -7798,9 +7800,7 @@ async function prepareCodexAttemptTools(runtime) {
7798
7800
  };
7799
7801
  return {
7800
7802
  tools: toolsWithScopedMcp,
7801
- registeredTools: registeredWithScopedMcp,
7802
7803
  requireExplicitMessageTarget,
7803
- scopedMcpTools,
7804
7804
  configuredMcp,
7805
7805
  disposeTools,
7806
7806
  configuredMcpOwnershipVersion: configuredMcpSurface === "scheduled" ? 1 : void 0,
@@ -7813,7 +7813,6 @@ async function prepareCodexAttemptTools(runtime) {
7813
7813
  toolState,
7814
7814
  toolOutcomeOrdinals,
7815
7815
  suppressedDynamicToolOutcomeOrdinals,
7816
- onCodexToolOutcome,
7817
7816
  allocateCodexToolOutcomeOrdinal,
7818
7817
  runtimeYieldCompletionClaim
7819
7818
  };
@@ -7944,6 +7943,40 @@ async function prepareCodexProviderReviewContinuation(params) {
7944
7943
  }
7945
7944
  }
7946
7945
  //#endregion
7946
+ //#region extensions/codex/src/app-server/service-tier.ts
7947
+ /** Optional speed upgrades follow this turn's native model and authenticated client. */
7948
+ async function resolveCodexUltrafastServiceTier(params) {
7949
+ if (!params.enabled || params.modelProvider !== "openai" && params.modelProvider !== "openclaw_token_sharing" || !params.model) return params.serviceTier;
7950
+ params.signal.throwIfAborted();
7951
+ params.assertCurrent();
7952
+ const deadline = Date.now() + params.timeoutMs;
7953
+ try {
7954
+ const catalog = await listAllCodexAppServerModels({
7955
+ includeHidden: true,
7956
+ request: (request) => {
7957
+ const timeoutMs = deadline - Date.now();
7958
+ if (timeoutMs <= 0) throw new Error("Codex Ultrafast catalog deadline exceeded");
7959
+ return requestCodexAppServerClientJson({
7960
+ ...request,
7961
+ client: params.client,
7962
+ signal: params.signal,
7963
+ assertCurrent: params.assertCurrent,
7964
+ timeoutMs,
7965
+ config: params.config
7966
+ });
7967
+ }
7968
+ });
7969
+ params.signal.throwIfAborted();
7970
+ params.assertCurrent();
7971
+ return catalog.models.find((entry) => entry.model === params.model)?.serviceTiers?.includes("ultrafast") ? "ultrafast" : params.serviceTier;
7972
+ } catch (error) {
7973
+ params.signal.throwIfAborted();
7974
+ params.assertCurrent();
7975
+ if (error instanceof CodexAppServerScopedRequestRejectedError) throw error;
7976
+ return params.serviceTier;
7977
+ }
7978
+ }
7979
+ //#endregion
7947
7980
  //#region extensions/codex/src/app-server/run-attempt-turn-request.ts
7948
7981
  async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurrentThreadRoute, waitForActiveNativeTurnCompletion) {
7949
7982
  const { prompt, state: resourceState, releaseCurrentRoute } = resources;
@@ -7951,7 +7984,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7951
7984
  const { runtime, attemptTools, hookContextWindowFields, workspaceBootstrapContext } = context;
7952
7985
  const { connection, runtimeParams, effectiveRuntimeProviderId, effectiveRuntimeModelId } = runtime;
7953
7986
  const { tools, toolBridge } = attemptTools;
7954
- const { params, usesSupervisionConnection, codexModelCallId, codexModelCallTrace, codexModelContentCapture, appServer, runAbortController } = connection;
7987
+ const { params, sessionAgentId, usesSupervisionConnection, codexModelCallId, codexModelCallTrace, codexModelContentCapture, appServer, runAbortController } = connection;
7955
7988
  const { state } = turnRuntime;
7956
7989
  const explicitSkillInputs = await resolveCodexExplicitSkillInputs({
7957
7990
  client: resourceState.client,
@@ -7959,18 +7992,22 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7959
7992
  selections: runtimeParams.explicitSkillSelections,
7960
7993
  signal: runAbortController.signal
7961
7994
  });
7962
- const buildCodexModelInputMessages = () => [...prompt.codexModelInputHistoryMessages, buildCodexUserPromptMessage({
7995
+ const buildCodexModelInputMessages = () => [buildCodexUserPromptMessage({
7963
7996
  ...runtimeParams,
7964
7997
  prompt: turnState.codexTurnPromptText
7965
7998
  })];
7999
+ const buildModelCallIdentity = () => ({
8000
+ runId: params.runId,
8001
+ sessionId: params.sessionId,
8002
+ provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
8003
+ model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId
8004
+ });
7966
8005
  const codexModelCallDiagnostics = createCodexModelCallDiagnosticEmitter({
7967
8006
  baseFields: {
7968
- runId: params.runId,
8007
+ ...buildModelCallIdentity(),
8008
+ agentId: sessionAgentId,
7969
8009
  callId: codexModelCallId,
7970
8010
  ...params.sessionKey ? { sessionKey: params.sessionKey } : {},
7971
- sessionId: params.sessionId,
7972
- provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
7973
- model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId,
7974
8011
  api: usesSupervisionConnection ? runtimeParams.model.api : params.model.api,
7975
8012
  transport: appServer.start.transport,
7976
8013
  observationUnit: "turn",
@@ -8004,15 +8041,16 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
8004
8041
  const selectedThread = resourceState.thread;
8005
8042
  const { threadId, liveThreadOwnership, model, modelProvider } = selectedThread;
8006
8043
  const turnClient = resourceState.client;
8044
+ const nativeModel = usesSupervisionConnection ? requireCodexSupervisionModelSelection(selectedThread) : void 0;
8007
8045
  const assertTurnCurrent = () => {
8008
8046
  connection.assertCurrent();
8009
8047
  liveThreadOwnership?.assertCurrent();
8010
8048
  if (resourceState.thread !== selectedThread || selectedThread.threadId !== threadId || selectedThread.liveThreadOwnership !== liveThreadOwnership || selectedThread.model !== model || selectedThread.modelProvider !== modelProvider) throw new Error("Codex native model or thread ownership changed during turn start.");
8011
8049
  };
8012
- const turnAppServer = withCodexAppServerFastModeServiceTier(connection.mutable.pluginAppServer, runtimeParams);
8013
- connection.mutable.pluginAppServer = turnAppServer;
8050
+ const fastMode = typeof runtimeParams.fastMode === "function" ? runtimeParams.fastMode() : runtimeParams.fastMode;
8051
+ const turnAppServer = withCodexAppServerFastModeServiceTier(connection.mutable.pluginAppServer, { fastMode }, connection.appServer);
8014
8052
  const references = prepareWorkspaceReferences();
8015
- const inferenceRoute = usesSupervisionConnection ? void 0 : getCodexInferenceThread(resourceState.client, resourceState.thread.threadId);
8053
+ const inferenceRoute = getCodexInferenceThread(resourceState.client, resourceState.thread.threadId);
8016
8054
  const turnStartParams = buildTurnStartParams(runtimeParams, {
8017
8055
  threadId: resourceState.thread.threadId,
8018
8056
  cwd: resourceState.codexExecutionCwd,
@@ -8029,7 +8067,6 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
8029
8067
  modelProvider: resourceState.thread.modelProvider
8030
8068
  },
8031
8069
  turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
8032
- skillsCollaborationInstructions: context.skillsCollaborationInstructions,
8033
8070
  memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions,
8034
8071
  preserveNativeTurnSettings: usesSupervisionConnection,
8035
8072
  parentLocalEgress: inferenceRoute !== void 0,
@@ -8037,15 +8074,51 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
8037
8074
  requireExplicitMessageTarget: attemptTools.requireExplicitMessageTarget,
8038
8075
  sessionStatusAvailable: toolBridge.availableTools.some((tool) => tool.name === "session_status")
8039
8076
  });
8077
+ const serviceTier = await resolveCodexUltrafastServiceTier({
8078
+ enabled: turnAppServer.enableUltrafast === true && fastMode !== false,
8079
+ serviceTier: turnStartParams.serviceTier,
8080
+ model: turnStartParams.model ?? model,
8081
+ modelProvider,
8082
+ client: turnClient,
8083
+ timeoutMs: Math.min(params.timeoutMs, 2500),
8084
+ signal: runAbortController.signal,
8085
+ assertCurrent: assertTurnCurrent,
8086
+ config: params.config
8087
+ });
8088
+ assertTurnCurrent();
8089
+ turnStartParams.serviceTier = serviceTier;
8090
+ connection.mutable.pluginAppServer = {
8091
+ ...turnAppServer,
8092
+ serviceTier
8093
+ };
8094
+ const authorizedModel = nativeModel ? {
8095
+ provider: nativeModel.modelProvider,
8096
+ model: nativeModel.model
8097
+ } : effectiveRuntimeModelId === readCodexRuntimeModelId(params.model, params.modelId) ? {
8098
+ provider: params.provider,
8099
+ model: params.modelId
8100
+ } : turnStartParams.model ? {
8101
+ provider: modelProvider ?? params.provider,
8102
+ model: turnStartParams.model
8103
+ } : void 0;
8104
+ connection.bindModelExecution(authorizedModel);
8105
+ const nativeRequestModel = turnStartParams.model ?? model;
8106
+ const modelMapping = authorizedModel && nativeRequestModel ? {
8107
+ nativeModel: {
8108
+ provider: modelProvider ?? params.provider,
8109
+ model: nativeRequestModel
8110
+ },
8111
+ authorizedModel
8112
+ } : void 0;
8040
8113
  if (inferenceRoute) {
8041
- prompt.setParentLocalEgress();
8114
+ if (!usesSupervisionConnection) prompt.setParentLocalEgress();
8042
8115
  resourceState.releaseInferenceContext?.();
8043
8116
  const inferenceThread = resourceState.thread;
8044
8117
  const registration = inferenceRoute.context.register({
8045
8118
  threadId: resourceState.thread.threadId,
8046
- text: buildCodexParentLocalInstructions(runtimeParams, {
8119
+ text: usesSupervisionConnection ? "" : buildCodexParentLocalInstructions(runtimeParams, {
8047
8120
  turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
8048
- skillsCollaborationInstructions: context.skillsCollaborationInstructions,
8121
+ skillsInstructions: context.skillsInstructions,
8049
8122
  memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions
8050
8123
  }) ?? "",
8051
8124
  signal: runAbortController.signal,
@@ -8122,6 +8195,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
8122
8195
  acceptedTurnId = startedTurn.turn.id;
8123
8196
  resources.nativeProcessAuthority?.bindTurn(turnClient, threadId, acceptedTurnId);
8124
8197
  assertTurnCurrent();
8198
+ resourceState.nativeSubagentMonitor?.bindTurn(acceptedTurnId, modelMapping);
8125
8199
  if (upstreamUserText.includes(workspaceBootstrapContext.promptContext ?? "")) references.accepted();
8126
8200
  throwIfTurnStartAcceptedAfterAbort();
8127
8201
  await continuation?.accept(acceptedTurnId);
@@ -8160,20 +8234,24 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
8160
8234
  }
8161
8235
  prepareWorkspaceReferences();
8162
8236
  const buildLlmInputEvent = () => ({
8163
- runId: params.runId,
8164
- sessionId: params.sessionId,
8165
- provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
8166
- model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId,
8237
+ ...buildModelCallIdentity(),
8167
8238
  systemPrompt: buildRenderedCodexDeveloperInstructions(),
8168
8239
  prompt: turnState.codexTurnPromptText,
8169
- historyMessages: prompt.codexModelInputHistoryMessages,
8240
+ historyMessages: [],
8170
8241
  imagesCount: prompt.contextImageGroups.reduce((count, group) => count + group.images.length, 0) + (params.images?.length ?? 0),
8171
8242
  tools
8172
8243
  });
8244
+ const buildLlmOutputEvent = () => ({
8245
+ ...buildModelCallIdentity(),
8246
+ ...hookContextWindowFields,
8247
+ resolvedRef: usesSupervisionConnection ? `${resourceState.thread.modelProvider ?? effectiveRuntimeProviderId}/${resourceState.thread.model ?? effectiveRuntimeModelId}` : params.runtimePlan?.observability.resolvedRef ?? `${params.provider}/${params.modelId}`,
8248
+ ...!usesSupervisionConnection && params.runtimePlan?.observability.harnessId ? { harnessId: params.runtimePlan.observability.harnessId } : {}
8249
+ });
8173
8250
  return {
8174
8251
  codexModelCallDiagnostics,
8175
8252
  startCodexTurn,
8176
- buildLlmInputEvent
8253
+ buildLlmInputEvent,
8254
+ buildLlmOutputEvent
8177
8255
  };
8178
8256
  }
8179
8257
  //#endregion
@@ -8181,12 +8259,12 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
8181
8259
  async function startCodexAttemptTurn(resources, turnRuntime, notifications, requestRuntime) {
8182
8260
  const { prompt, state: resourceState, trajectoryRecorder, markTrajectoryEndRecorded } = resources;
8183
8261
  const { context, turnState, systemPromptReport } = prompt;
8184
- const { runtime, historyState, hookContext, hookContextWindowFields, hookRunner } = context;
8185
- const { connection, runtimeParams, effectiveRuntimeProviderId, effectiveRuntimeModelId } = runtime;
8186
- const { params, usesSupervisionConnection, runAbortController, activeContextEngine, bindingStore, bindingIdentity, appServer, attemptStartedAt, startupAuthProfileId } = connection;
8262
+ const { runtime, historyState, hookContext, hookRunner } = context;
8263
+ const { connection, runtimeParams } = runtime;
8264
+ const { params, runAbortController, activeContextEngine, bindingStore, bindingIdentity, appServer, attemptStartedAt, startupAuthProfileId } = connection;
8187
8265
  const { state, turnIdRef } = turnRuntime;
8188
8266
  const { waitForActiveNativeTurnCompletion } = notifications;
8189
- const { codexModelCallDiagnostics, startCodexTurn, buildLlmInputEvent } = requestRuntime;
8267
+ const { codexModelCallDiagnostics, startCodexTurn, buildLlmInputEvent, buildLlmOutputEvent } = requestRuntime;
8190
8268
  let started;
8191
8269
  resourceState.turnStartAttempted = true;
8192
8270
  try {
@@ -8229,27 +8307,12 @@ async function startCodexAttemptTurn(resources, turnRuntime, notifications, requ
8229
8307
  if (!await bindingStore.mutate(bindingIdentity, {
8230
8308
  kind: "clear",
8231
8309
  threadId: resourceState.thread.threadId
8232
- })) embeddedAgentLog.warn("codex app-server preserved newer context-engine binding after resume overflow; skipping fresh retry", {
8310
+ }, connection.assertCurrent)) embeddedAgentLog.warn("codex app-server preserved newer context-engine binding after resume overflow; skipping fresh retry", {
8233
8311
  threadId: resourceState.thread.threadId,
8234
8312
  error: formatErrorMessage(turnStartError)
8235
8313
  });
8236
8314
  else {
8237
8315
  resourceState.thread = await resourceState.restartContextEngineCodexThread();
8238
- const retryBinding = bindingStore.read(bindingIdentity);
8239
- if (retryBinding && retryBinding.threadId === resourceState.thread.threadId && retryBinding.contextEngine?.projection) {
8240
- await bindingStore.mutate(bindingIdentity, {
8241
- kind: "patch",
8242
- threadId: retryBinding.threadId,
8243
- patch: { contextEngine: {
8244
- ...retryBinding.contextEngine,
8245
- projection: void 0
8246
- } }
8247
- });
8248
- embeddedAgentLog.info("codex app-server cleared stale context-engine projection after overflow retry", {
8249
- threadId: resourceState.thread.threadId,
8250
- previousEpoch: retryBinding.contextEngine.projection.epoch
8251
- });
8252
- }
8253
8316
  emitCodexAppServerEvent(params, {
8254
8317
  stream: "codex_app_server.lifecycle",
8255
8318
  data: {
@@ -8298,13 +8361,7 @@ async function startCodexAttemptTurn(resources, turnRuntime, notifications, requ
8298
8361
  markTrajectoryEndRecorded();
8299
8362
  runAgentHarnessLlmOutputHook({
8300
8363
  event: {
8301
- runId: params.runId,
8302
- sessionId: params.sessionId,
8303
- provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
8304
- model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId,
8305
- ...hookContextWindowFields,
8306
- resolvedRef: usesSupervisionConnection ? `${resourceState.thread.modelProvider ?? effectiveRuntimeProviderId}/${resourceState.thread.model ?? effectiveRuntimeModelId}` : params.runtimePlan?.observability.resolvedRef ?? `${params.provider}/${params.modelId}`,
8307
- ...!usesSupervisionConnection && params.runtimePlan?.observability.harnessId ? { harnessId: params.runtimePlan.observability.harnessId } : {},
8364
+ ...buildLlmOutputEvent(),
8308
8365
  assistantTexts: []
8309
8366
  },
8310
8367
  ctx: hookContext,
@@ -8373,63 +8430,9 @@ async function startCodexAttemptTurn(resources, turnRuntime, notifications, requ
8373
8430
  configCwd: connection.effectiveCwd
8374
8431
  };
8375
8432
  turnIdRef.current = started.turn.turn.id;
8376
- resourceState.nativeSubagentMonitor?.bindTurn(started.turn.turn.id);
8377
8433
  return started;
8378
8434
  }
8379
8435
  //#endregion
8380
- //#region extensions/codex/src/app-server/attempt-deadlines.ts
8381
- function createCodexAttemptDeadlineController(params) {
8382
- let deadline = { kind: "closed" };
8383
- let timer;
8384
- const armDeadline = (next) => {
8385
- clearTimeout(timer);
8386
- deadline = next;
8387
- const deadlineAtMs = next.startedAtMs + next.timeoutMs;
8388
- params.onDeadlineChanged?.({
8389
- kind: "bounded",
8390
- deadlineAtMs
8391
- });
8392
- timer = setTimeout(() => {
8393
- if (deadline !== next || params.signal.aborted) return;
8394
- deadline = { kind: "closed" };
8395
- params.onTimeout({
8396
- kind: next.kind,
8397
- elapsedMs: Math.max(0, Date.now() - next.startedAtMs),
8398
- timeoutMs: next.timeoutMs
8399
- });
8400
- }, resolveTimerTimeoutMs(Math.max(1, deadlineAtMs - Date.now()), 1));
8401
- timer.unref?.();
8402
- };
8403
- const dispose = () => {
8404
- deadline = { kind: "closed" };
8405
- clearTimeout(timer);
8406
- params.signal.removeEventListener("abort", dispose);
8407
- };
8408
- if (!params.signal.aborted) {
8409
- params.signal.addEventListener("abort", dispose, { once: true });
8410
- if (params.timeoutMs >= MAX_TIMER_TIMEOUT_MS) {
8411
- deadline = { kind: "unlimited" };
8412
- params.onDeadlineChanged?.({ kind: "unlimited" });
8413
- } else armDeadline({
8414
- kind: "execution",
8415
- startedAtMs: params.startedAtMs,
8416
- timeoutMs: params.timeoutMs
8417
- });
8418
- }
8419
- return {
8420
- ownsExecutionWait: () => deadline.kind === "unlimited" || deadline.kind === "execution" && Date.now() < deadline.startedAtMs + deadline.timeoutMs,
8421
- beginSettlement: (startedAtMs) => {
8422
- if (deadline.kind === "closed" || deadline.kind === "settlement") return;
8423
- armDeadline({
8424
- kind: "settlement",
8425
- startedAtMs,
8426
- timeoutMs: TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS
8427
- });
8428
- },
8429
- dispose
8430
- };
8431
- }
8432
- //#endregion
8433
8436
  //#region extensions/codex/src/app-server/run-attempt-turn-state.ts
8434
8437
  const CODEX_NATIVE_HOOK_RELAY_RENEW_INTERVAL_MS = 6e4;
8435
8438
  var CodexAttemptState = class {
@@ -8459,7 +8462,11 @@ function createCodexAttemptTurnState(resources) {
8459
8462
  const { promise: completion, resolve: resolveCompletion } = createDeferred();
8460
8463
  const settlementExpired = createDeferred();
8461
8464
  const pendingOpenClawDynamicToolCompletionIds = /* @__PURE__ */ new Set();
8462
- const openClawDynamicToolExecutions = createCodexDynamicToolExecutionRegistry();
8465
+ const openClawDynamicToolExecutions = createAgentHarnessToolExecutionRegistry((call) => [
8466
+ call.threadId,
8467
+ call.turnId,
8468
+ call.callId
8469
+ ]);
8463
8470
  const activeTurnItemIds = /* @__PURE__ */ new Set();
8464
8471
  const turnIdRef = {};
8465
8472
  const userInputBridgeRef = {};
@@ -8521,9 +8528,10 @@ function createCodexAttemptTurnState(resources) {
8521
8528
  reason: `codex_app_server:${reason}`
8522
8529
  });
8523
8530
  };
8524
- const deadlines = createCodexAttemptDeadlineController({
8531
+ const deadlines = createAgentHarnessAttemptDeadlineController({
8525
8532
  startedAtMs: connection.attemptStartedAt,
8526
8533
  timeoutMs: params.timeoutMs,
8534
+ settlementTimeoutMs: TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS,
8527
8535
  signal: runAbortController.signal,
8528
8536
  onDeadlineChanged: params.onAttemptDeadlineChanged,
8529
8537
  onTimeout: (timeout) => {
@@ -8572,7 +8580,6 @@ function createCodexAttemptTurnState(resources) {
8572
8580
  steeringQueueRef,
8573
8581
  completeTurn,
8574
8582
  interruptTurn,
8575
- renewNativeHookRelayForTurnProgress,
8576
8583
  noteProgress,
8577
8584
  deadlines
8578
8585
  };
@@ -8604,7 +8611,10 @@ async function runCodexAppServerAttempt(params, options) {
8604
8611
  const turnRequest = await preparation.measure("turn-request", () => prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurrentThreadRoute, notifications.waitForActiveNativeTurnCompletion));
8605
8612
  preparation.ready();
8606
8613
  const turnStart = await startCodexAttemptTurn(resources, turnRuntime, notifications, turnRequest);
8607
- if ("result" in turnStart) return turnStart.result;
8614
+ if ("result" in turnStart) {
8615
+ connection.assertModelExecutionCurrent();
8616
+ return turnStart.result;
8617
+ }
8608
8618
  const activeTurn = activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notifications, turnStart);
8609
8619
  activeTurnOwnsCleanup = true;
8610
8620
  let finalizedResult;
@@ -8627,6 +8637,7 @@ async function runCodexAppServerAttempt(params, options) {
8627
8637
  delete finalizedResult.settledTurnFinalizationContext;
8628
8638
  }
8629
8639
  if (resources.state.executionDisconnectError && !connection.terminalState.explicitCancellationObserved) throw resources.state.executionDisconnectError;
8640
+ connection.assertModelExecutionCurrent();
8630
8641
  return finalizedResult;
8631
8642
  } finally {
8632
8643
  turnRuntime.deadlines.dispose();
@@ -8638,7 +8649,8 @@ async function runCodexAppServerAttempt(params, options) {
8638
8649
  await attemptTools.disposeTools(connection.runAbortController.signal.aborted ? "cancel" : "error");
8639
8650
  }
8640
8651
  } finally {
8641
- params.abortSignal?.removeEventListener("abort", connection.abortFromUpstream);
8652
+ connection.cancellation.dispose();
8653
+ connection.releaseModelExecution();
8642
8654
  }
8643
8655
  }
8644
8656
  //#endregion