@openclaw/codex 2026.9.6 → 2026.9.7

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-DFhbh1zz.mjs} +5 -5
  4. package/dist/.setup/{apply-DDOi8uNx.mjs → apply-D3GcSoSa.mjs} +22 -36
  5. package/dist/.setup/{attempt-client-cleanup-CEv1cKwF.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +128 -37
  6. package/dist/.setup/attempt-workspace-context-C5HigshI.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-Dbvq-QgB.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-CbjoN2OW.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-Da1_z0kd.mjs} +1 -1
  16. package/dist/.setup/{capabilities-CDXOOFdZ.mjs → capabilities-B3WEZl4e.mjs} +2 -10
  17. package/dist/.setup/{client-Cs08OXVQ.mjs → client-N0JpgSzF.mjs} +138 -399
  18. package/dist/.setup/{client-catalog-response-BMgt_4q4.mjs → client-catalog-response-5HHLdcde.mjs} +1 -1
  19. package/dist/.setup/{command-dispatch-B4JuOsOk.mjs → command-dispatch-BeAoaovI.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-ylTMS00z.mjs} +222 -343
  22. package/dist/.setup/{command-rpc-DixIj3HW.mjs → command-rpc-CGJGUQ6Y.mjs} +15 -18
  23. package/dist/.setup/compact-C2WamavS.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-3Min8qvP.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-CEP8X5JC.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-DzlsLUuS.mjs} +2305 -2606
  37. package/dist/.setup/{effective-mcp-catalog-CvnvnGIe.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
  38. package/dist/.setup/{ephemeral-turn-poidXgek.mjs → ephemeral-turn-CDsPJOa2.mjs} +3 -3
  39. package/dist/.setup/event-projector-assistant-message-CigreO4K.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-Dm3PzxJk.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-PAuZgJC6.mjs} +11 -10
  50. package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
  51. package/dist/.setup/{models-KnqBv0hE.mjs → models-DHXZtVVk.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-Dpsmf2wz.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-Y-QIvrKB.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-DsjsL1dr.mjs} +115 -175
  65. package/dist/.setup/{provider-BOsxQHOM.mjs → provider-DH8NSzGt.mjs} +11 -14
  66. package/dist/.setup/{provider-capabilities-BfE88FZ5.mjs → provider-capabilities-CAxoF-X1.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-BHZ1nz8d.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-D8RZUOzY.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-4sCdv5qx.mjs} +170 -324
  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-DePDzzjc.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-CZvDzC6z.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-DjhwGL6x.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-Cr5qP5Dj.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-Cn_nCqfq.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-qMTxkNx2.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-BsvEabkw.mjs} +14 -10
  107. package/dist/.setup/{shared-client-DA4VR4Eb.mjs → shared-client-DqyTMYug.mjs} +783 -412
  108. package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
  109. package/dist/.setup/{side-question-BJ1wSDcB.mjs → side-question-C4kCmQy1.mjs} +79 -143
  110. package/dist/.setup/{source-CUzJq5WN.mjs → source-CS_7GFJZ.mjs} +80 -137
  111. package/dist/.setup/{thread-lifecycle-B3mfz1TG.mjs → thread-lifecycle-DPflntEJ.mjs} +294 -737
  112. package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
  113. package/dist/.setup/{thread-ownership-DcTtAcXj.mjs → thread-ownership-roNP0l1c.mjs} +45 -10
  114. package/dist/.setup/{thread-policy-DGuQsuFC.mjs → thread-policy-DTd-DtkX.mjs} +46 -7
  115. package/dist/.setup/{thread-requests-BLvGkP2R.mjs → thread-requests-B_bRnMGN.mjs} +199 -302
  116. package/dist/.setup/{thread-resume-DIBXwOpE.mjs → thread-resume-CdDaoc7T.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-CBeVjBpT.mjs} +23 -23
  125. package/dist/.setup/{usage-BML0r-ua.mjs → usage-BMzNxeR_.mjs} +4 -4
  126. package/dist/.setup/{usage-limit-error-DUMbefVY.mjs → usage-limit-error-QXerDo3i.mjs} +4 -19
  127. package/dist/.setup/{web-search-provider.runtime-CDKlN-Rv.mjs → web-search-provider.runtime-P77OUeoo.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
@@ -0,0 +1,153 @@
1
+ import { n as defineCodexBuildState } from "./build-state-Da1_z0kd.mjs";
2
+ //#region extensions/codex/src/app-server/shared-client-lifecycle.ts
3
+ /** Client ownership and synchronous retirement, independent of startup/auth execution. */
4
+ const createCodexAppServerStartupLifetime = () => ({
5
+ controller: new AbortController(),
6
+ pending: /* @__PURE__ */ new Set()
7
+ });
8
+ function ownCodexStartup(lifetime, operation) {
9
+ lifetime.pending.add(operation);
10
+ const release = () => lifetime.pending.delete(operation);
11
+ operation.then(release, release);
12
+ return operation;
13
+ }
14
+ const getSharedCodexAppServerClientState = defineCodexBuildState("openclaw.codexAppServerClientState", () => ({
15
+ clients: /* @__PURE__ */ new Map(),
16
+ liveClients: /* @__PURE__ */ new Set(),
17
+ isolatedClients: /* @__PURE__ */ new Set(),
18
+ entriesByClient: /* @__PURE__ */ new WeakMap(),
19
+ desktopGenerationDrainChecks: /* @__PURE__ */ new Set(),
20
+ startup: createCodexAppServerStartupLifetime(),
21
+ startMetadata: /* @__PURE__ */ new WeakMap()
22
+ }));
23
+ function hasActiveSharedCodexAppServerWork() {
24
+ const state = getSharedCodexAppServerClientState();
25
+ if (state.startup.pending.size > 0 || state.startup.controller.signal.aborted) return true;
26
+ for (const entry of state.clients.values()) if (entry.activeLeases > 0 || entry.pendingAcquires > 0) return true;
27
+ for (const client of state.liveClients) {
28
+ const entry = state.entriesByClient.get(client);
29
+ if (entry && (entry.activeLeases > 0 || entry.pendingAcquires > 0)) return true;
30
+ }
31
+ return false;
32
+ }
33
+ function getCurrentSharedClientEntry(client) {
34
+ const state = getSharedCodexAppServerClientState();
35
+ const entry = client ? state.entriesByClient.get(client) : void 0;
36
+ return entry && entry.client === client && state.clients.get(entry.key) === entry ? entry : void 0;
37
+ }
38
+ /**
39
+ * Retires a matching shared client. Default is graceful: detach from the map
40
+ * (future acquisitions get a fresh client) and close once leases drain.
41
+ * `failActiveLeases` is for suspect clients only (timed-out turns): it closes
42
+ * the physical connection immediately so co-leased attempts hit the normal
43
+ * client-closed retry path, and pending acquires reject instead of leasing
44
+ * the poisoned process. Routine cleanup must NOT use it — it would abort
45
+ * healthy sibling turns on a working client.
46
+ */
47
+ function retireSharedCodexAppServerClientIfCurrent(client, opts) {
48
+ if (!client) return;
49
+ const state = getSharedCodexAppServerClientState();
50
+ const currentEntry = getCurrentSharedClientEntry(client);
51
+ const entry = currentEntry ?? state.entriesByClient.get(client);
52
+ if (!entry || entry.client !== client && !entry.closeError) return;
53
+ if (currentEntry) {
54
+ state.clients.delete(entry.key);
55
+ entry.closeWhenIdle = true;
56
+ }
57
+ if (opts?.failActiveLeases && (currentEntry || !entry.closeError)) {
58
+ entry.closeError = /* @__PURE__ */ new Error("codex app-server client is closed");
59
+ return {
60
+ activeLeases: entry.activeLeases,
61
+ closed: closeRetiredSharedClientEntry(entry)
62
+ };
63
+ }
64
+ return {
65
+ activeLeases: entry.activeLeases,
66
+ closed: currentEntry ? closeRetiredSharedClientEntryIfIdle(entry) : false
67
+ };
68
+ }
69
+ /** Gracefully retires exact clients attached to an older desktop generation. */
70
+ function retireSharedCodexAppServerClientsBeforeDesktopGeneration(generation) {
71
+ const state = getSharedCodexAppServerClientState();
72
+ for (const entry of state.clients.values()) {
73
+ const client = entry.client;
74
+ const attached = client ? state.startMetadata.get(client) : void 0;
75
+ if (client && attached?.desktopGeneration && attached.desktopGeneration.epoch < generation.epoch) retireSharedCodexAppServerClientIfCurrent(client);
76
+ }
77
+ }
78
+ function closeRetiredSharedClientEntryIfIdle(entry) {
79
+ if (!entry.closeWhenIdle || entry.activeLeases > 0 || entry.pendingAcquires > 0 || !entry.client) return false;
80
+ entry.closeWhenIdle = false;
81
+ return closeRetiredSharedClientEntry(entry);
82
+ }
83
+ function closeRetiredSharedClientEntry(entry) {
84
+ const client = entry.client;
85
+ if (!client) return false;
86
+ entry.client = void 0;
87
+ client.close();
88
+ return true;
89
+ }
90
+ function retirePendingSharedClientEntryIfUnclaimed(entry) {
91
+ if (entry.activeLeases > 0 || entry.pendingAcquires > 0) return;
92
+ entry.startupAbort?.abort(/* @__PURE__ */ new Error("Codex app-server startup was abandoned"));
93
+ entry.closeWhenIdle = true;
94
+ const state = getSharedCodexAppServerClientState();
95
+ if (state.clients.get(entry.key) === entry) state.clients.delete(entry.key);
96
+ if (!entry.client) return;
97
+ closeRetiredSharedClientEntry(entry);
98
+ }
99
+ /** Failed final claimants join physical cleanup; healthy peers keep their startup. */
100
+ async function waitForUnclaimedSharedClientStartup(entry) {
101
+ if (!entry.startupTransport || entry.activeLeases > 0 || entry.pendingAcquires > 0) return;
102
+ await entry.startupTransport.then((client) => client.closeAndWait(), () => {});
103
+ }
104
+ /** Exit registration also observes transports that have already terminated. */
105
+ function waitForCodexAppServerClientExit(client) {
106
+ const metadata = getSharedCodexAppServerClientState().startMetadata.get(client);
107
+ const exited = metadata?.transportExit ?? new Promise((resolve) => {
108
+ client.addTransportExitHandler(() => resolve());
109
+ });
110
+ if (metadata) metadata.transportExit = exited;
111
+ return exited;
112
+ }
113
+ /** Acquire the recorded owner atomically, or join its exit before a replacement writes. */
114
+ async function retainSharedCodexAppServerClientByInstanceId(clientId) {
115
+ const id = clientId?.trim();
116
+ if (!id) return;
117
+ const state = getSharedCodexAppServerClientState();
118
+ for (const client of state.liveClients) {
119
+ if (client.getInstanceId() !== id) continue;
120
+ const entry = state.entriesByClient.get(client);
121
+ if (entry?.client !== client || entry.closeError || client.getCloseError()) {
122
+ await waitForCodexAppServerClientExit(client);
123
+ return;
124
+ }
125
+ const release = retainSharedClientEntry(entry);
126
+ return {
127
+ client,
128
+ release: (waitForRetirement = false) => {
129
+ release();
130
+ return client.getCloseError() || waitForRetirement && entry.closeWhenIdle ? waitForCodexAppServerClientExit(client) : void 0;
131
+ }
132
+ };
133
+ }
134
+ }
135
+ function notifyDesktopGenerationDrainChecks(state) {
136
+ for (const check of state.desktopGenerationDrainChecks) check();
137
+ }
138
+ function retainSharedClientEntry(entry, counter = "activeLeases") {
139
+ let released = false;
140
+ entry[counter] += 1;
141
+ return () => {
142
+ if (released) return;
143
+ released = true;
144
+ releaseSharedClientEntry(entry, counter);
145
+ };
146
+ }
147
+ function releaseSharedClientEntry(entry, counter) {
148
+ entry[counter] -= 1;
149
+ closeRetiredSharedClientEntryIfIdle(entry);
150
+ notifyDesktopGenerationDrainChecks(getSharedCodexAppServerClientState());
151
+ }
152
+ //#endregion
153
+ export { notifyDesktopGenerationDrainChecks as a, retainSharedClientEntry as c, retireSharedCodexAppServerClientIfCurrent as d, retireSharedCodexAppServerClientsBeforeDesktopGeneration as f, hasActiveSharedCodexAppServerWork as i, retainSharedCodexAppServerClientByInstanceId as l, waitForUnclaimedSharedClientStartup as m, getCurrentSharedClientEntry as n, ownCodexStartup as o, waitForCodexAppServerClientExit as p, getSharedCodexAppServerClientState as r, releaseSharedClientEntry as s, createCodexAppServerStartupLifetime as t, retirePendingSharedClientEntryIfUnclaimed as u };
@@ -1,23 +1,23 @@
1
- import { m as sessionBindingIdentity } from "./session-binding-record-BGoz8wOK.mjs";
2
- import { l as shouldAutoApproveCodexAppServerApprovals, n as hasCodexMcpToolApprovalOverrides, u as withMcpElicitationsApprovalPolicy, y as readCodexRequirementsToml } from "./config-security-BEReZ6go.mjs";
3
- import { c as isCodexPairedNodeRemoteExecPlacementSandbox, d as readCodexPluginConfig, l as isCodexRemoteExecPlacementSandbox, u as isCodexSandboxExecServerEnabled } from "./config-parsing-CcB9iPoq.mjs";
4
1
  import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
5
- import { i as resolveCodexAppServerHomeScope, l as resolveCodexModelBackedReviewerPolicyContext } from "./config-options-BvaRs51b.mjs";
6
- import { n as formatCodexUsageLimitErrorMessage } from "./rate-limits-CMU3DUD0.mjs";
7
- import { i as resolveCodexBindingAppServerConnection, r as requireCodexSupervisionModelSelection } from "./binding-connection-ThoatDcb.mjs";
8
- import { n as resolveOpenClawExecPolicyForCodexAppServer, t as canUseCodexModelBackedApprovalsReviewerForModel } from "./config-BoTP_mrL.mjs";
9
- import { Z as resolveCodexAppServerPreparedAuthHandoff, c as getLeasedSharedCodexAppServerClient, m as releaseCodexAppServerClientLease, q as readRecentCodexRateLimits, x as withLeasedCodexAppServerClientStartSelectionRetry } from "./shared-client-DA4VR4Eb.mjs";
10
- import { C as readCodexDynamicToolCallParams, D as handleDynamicToolCallWithTimeout, E as createCodexElicitationResponse, L as resolveCodexToolAbortTerminalReason, S as assertCodexTurnStartResponse, i as isCodexAppServerApprovalRequest, j as resolveDynamicToolCallTimeoutMs, s as isCodexAppServerIndeterminateRequestCancellationError, y as assertCodexThreadForkResponse } from "./client-Cs08OXVQ.mjs";
11
- import { f as terminateCodexBackgroundTerminals, p as unsubscribeCodexThreadBestEffort, s as interruptCodexTurnAndWaitBestEffort, u as retireUnsafeCodexTurnClientBestEffort } from "./attempt-client-cleanup-CEv1cKwF.mjs";
12
- import { t as CodexEphemeralTurn } from "./ephemeral-turn-poidXgek.mjs";
13
- import { A as emitCodexNativePreToolUseFailureDiagnostic, D as buildCodexNativeHookRelayDisabledConfig, E as buildCodexNativeHookRelayConfig, S as CODEX_NATIVE_HOOK_RELAY_EVENTS, St as refreshCodexPluginAppApprovalPolicy, _ as resolveCodexAppServerRequestModelSelection, dt as resolveCodexDynamicToolsLoading, g as resolveCodexAppServerModelProvider, h as CODEX_NATIVE_PERSONALITY_NONE, p as resolveCodexWebSearchPlan, r as buildCodexRuntimeThreadConfig, xt as mergeCodexThreadConfigs, y as resolveCodexBindingModelProviderFallback } from "./thread-requests-BLvGkP2R.mjs";
14
- import { M as resolveCodexAppServerReasoningEffort, j as readCodexSupportedReasoningEfforts, o as buildCodexUserInput, r as buildCodexTemporalAdditionalContext } from "./thread-lifecycle-B3mfz1TG.mjs";
15
- import { o as resolveCodexSessionBinding } from "./session-binding-Cm0apEbd.mjs";
16
- import { a as refreshCodexThreadPolicy, i as assertCodexSupervisionThreadLineage, n as CodexThreadPolicyHandoffError } from "./thread-policy-DGuQsuFC.mjs";
17
- import { t as resolveCodexNativeExecutionBlock } from "./sandbox-guard-C2sRMOEY.mjs";
18
- import { C as shouldEnableCodexAppServerNativeToolSurface, S as resolveCodexSandboxEnvironmentSelection, a as emitDynamicToolStartedDiagnostic, b as resolveCodexExternalSandboxPolicyForOpenClawSandbox, c as ensureCodexSandboxExecServerEnvironment, i as emitDynamicToolErrorDiagnostic, l as releaseCodexSandboxExecServerEnvironment, m as buildDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as CodexNativeToolLifecycleProjector, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, w as shouldRequireCodexSandboxExecServerEnvironment, x as resolveCodexMessageToolProvider } from "./dynamic-tools-BDXl-8Cw.mjs";
19
- import { n as resolveCodexProviderWebSearchSupportForClient } from "./provider-capabilities-BfE88FZ5.mjs";
20
- import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy, t as CODEX_SESSION_PERMISSION_EXEC_MODES } from "./session-permission-policy-BI1QK_98.mjs";
2
+ import { v as sessionBindingIdentity } from "./session-binding-record-Oe9L-CNY.mjs";
3
+ import { c as shouldAutoApproveCodexAppServerApprovals, l as withMcpElicitationsApprovalPolicy, m as readCodexRequirementsToml, n as hasCodexMcpToolApprovalOverrides } from "./config-security-CE-FcGw9.mjs";
4
+ import { c as isCodexPairedNodeRemoteExecPlacementSandbox, d as readCodexPluginConfig, l as isCodexRemoteExecPlacementSandbox, u as isCodexSandboxExecServerEnabled } from "./config-parsing-b088LyhT.mjs";
5
+ import { i as resolveCodexAppServerHomeScope, l as resolveCodexModelBackedReviewerPolicyContext } from "./config-options-CzyWLTJt.mjs";
6
+ import { n as formatCodexUsageLimitErrorMessage } from "./rate-limits-B7-X2TgG.mjs";
7
+ import { i as resolveCodexBindingAppServerConnection, r as requireCodexSupervisionModelSelection } from "./binding-connection-DTtN1KrX.mjs";
8
+ import { n as canUseCodexModelBackedApprovalsReviewerForModel, r as resolveOpenClawExecPolicyForCodexAppServer } from "./config-DKhXquav.mjs";
9
+ import { X as readRecentCodexRateLimits, b as withLeasedCodexAppServerClientStartSelectionRetry, c as getLeasedSharedCodexAppServerClient, m as releaseCodexAppServerClientLease, tt as resolveCodexAppServerPreparedAuthHandoff } from "./shared-client-DqyTMYug.mjs";
10
+ import { A as handleDynamicToolCallWithTimeout, B as resolveCodexToolAbortTerminalReason, P as resolveDynamicToolCallTimeoutMs, S as assertCodexTurnStartResponse, i as isCodexAppServerApprovalRequest, k as createCodexElicitationResponse, s as isCodexAppServerIndeterminateRequestCancellationError, w as readCodexDynamicToolCallParams, y as assertCodexThreadForkResponse, z as toCodexDynamicToolProtocolResponse } from "./client-N0JpgSzF.mjs";
11
+ import { f as terminateCodexBackgroundTerminals, p as unsubscribeCodexThreadBestEffort, s as interruptCodexTurnAndWaitBestEffort, u as retireUnsafeCodexTurnClientBestEffort } from "./attempt-client-cleanup-DOP-cW5j.mjs";
12
+ import { t as CodexEphemeralTurn } from "./ephemeral-turn-CDsPJOa2.mjs";
13
+ import { Ct as refreshCodexPluginAppApprovalPolicy, D as buildCodexNativeHookRelayConfig, M as resolveCodexNativeHookRelayEvents, N as resolveCodexNativeHookRelayTtlMs, O as buildCodexNativeHookRelayDisabledConfig, St as mergeCodexThreadConfigs, ft as resolveCodexDynamicToolsLoading, g as CODEX_NATIVE_PERSONALITY_NONE, p as resolveCodexWebSearchPlan, r as buildCodexRuntimeThreadConfig, y as resolveCodexAppServerThreadModelSelection } from "./thread-requests-B_bRnMGN.mjs";
14
+ import { S as resolveCodexAppServerReasoningEffort, o as buildCodexUserInput, r as buildCodexTemporalAdditionalContext, x as readCodexSupportedReasoningEfforts } from "./thread-lifecycle-DPflntEJ.mjs";
15
+ import { o as resolveCodexSessionBinding } from "./session-binding-DGCYAfvD.mjs";
16
+ import { a as refreshCodexThreadPolicy, i as assertCodexSupervisionThreadLineage, n as CodexThreadPolicyHandoffError } from "./thread-policy-DTd-DtkX.mjs";
17
+ import { t as resolveCodexNativeExecutionBlock } from "./sandbox-guard-DjCz2eOw.mjs";
18
+ import { E as CodexNativeToolLifecycleProjector, a as emitDynamicToolStartedDiagnostic, b as createCodexNativePreToolUseFailureBuffer, c as buildDynamicTools, f as resolveCodexExternalSandboxPolicyForOpenClawSandbox, g as shouldRequireCodexSandboxExecServerEnvironment, h as shouldEnableCodexAppServerNativeToolSurface, i as emitDynamicToolErrorDiagnostic, m as resolveCodexSandboxEnvironmentSelection, o as emitDynamicToolTerminalDiagnostic, p as resolveCodexMessageToolProvider, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, v as ensureCodexSandboxExecServerEnvironment, y as releaseCodexSandboxExecServerEnvironment } from "./dynamic-tools-DzlsLUuS.mjs";
19
+ import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy, t as CODEX_SESSION_PERMISSION_EXEC_MODES } from "./session-permission-policy-Ci_fVX6y.mjs";
20
+ import { n as resolveCodexProviderWebSearchSupportForClient } from "./provider-capabilities-CAxoF-X1.mjs";
21
21
  import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
22
22
  import { randomUUID } from "node:crypto";
23
23
  import { isDeepStrictEqual } from "node:util";
@@ -89,10 +89,6 @@ var CodexSideQuestionTimeoutError = class extends Error {
89
89
  this.name = "TimeoutError";
90
90
  }
91
91
  };
92
- const CODEX_SIDE_NATIVE_HOOK_RELAY_MIN_TTL_MS = 18e5;
93
- const CODEX_SIDE_NATIVE_HOOK_RELAY_TTL_GRACE_MS = 3e5;
94
- const CODEX_SIDE_NATIVE_HOOK_RELAY_STARTUP_REQUEST_COUNT = 3;
95
- const CODEX_SIDE_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS = CODEX_NATIVE_HOOK_RELAY_EVENTS.filter((event) => event !== "permission_request");
96
92
  async function runCodexAppServerSideQuestion(params, options) {
97
93
  const bindingIdentity = sessionBindingIdentity({
98
94
  sessionId: params.sessionId,
@@ -144,26 +140,6 @@ async function runCodexAppServerSideQuestion(params, options) {
144
140
  subscriptionProfileRequiredError: "Prepared Codex subscription route requires a scoped native OAuth or token profile.",
145
141
  subscriptionProfileUnusableError: `Prepared Codex auth profile "${preparedRuntimeAuth.plan.forwardedAuthProfileId}" is unusable.`
146
142
  });
147
- const modelProvider = supervisionModelSelection ? supervisionModelSelection.modelProvider : resolveCodexAppServerModelProvider({
148
- provider: params.provider,
149
- authProfileId,
150
- authProfileStore: preparedRuntimeAuth.authProfileStore,
151
- agentDir: params.agentDir,
152
- config: params.cfg
153
- }) ?? resolveCodexBindingModelProviderFallback({
154
- provider: params.provider,
155
- currentModel: params.model,
156
- bindingModel: binding.model,
157
- bindingModelProvider: binding.modelProvider
158
- });
159
- const modelSelection = resolveCodexAppServerRequestModelSelection({
160
- model: supervisionModelSelection?.model ?? options.runtimeModelId ?? params.model,
161
- modelProvider,
162
- authProfileId,
163
- authProfileStore: preparedRuntimeAuth.authProfileStore,
164
- agentDir: params.agentDir,
165
- config: params.cfg
166
- });
167
143
  const reviewerPolicyContext = resolveCodexModelBackedReviewerPolicyContext({
168
144
  provider: usesSupervisionConnection ? "codex" : params.provider,
169
145
  model: supervisionModelSelection?.model ?? params.model,
@@ -204,6 +180,18 @@ async function runCodexAppServerSideQuestion(params, options) {
204
180
  ...reviewerContext,
205
181
  provider: reviewerContext.modelProvider
206
182
  });
183
+ const modelSelection = supervisionModelSelection ?? resolveCodexAppServerThreadModelSelection({
184
+ homeScope: appServer.start.homeScope,
185
+ provider: params.provider,
186
+ model: params.model,
187
+ requestModel: options.runtimeModelId ?? params.model,
188
+ binding,
189
+ inheritBindingAuthProfile: false,
190
+ authProfileId,
191
+ authProfileStore: preparedRuntimeAuth.authProfileStore,
192
+ agentDir: params.agentDir,
193
+ config: params.cfg
194
+ });
207
195
  const sessionPermissionPolicy = resolveCodexEffectiveSessionPermissionPolicy({
208
196
  appServer,
209
197
  permissionMode: params.sessionEntry.permissionMode,
@@ -282,31 +270,14 @@ async function runCodexAppServerSideQuestion(params, options) {
282
270
  let collector;
283
271
  const runAbortController = new AbortController();
284
272
  let nativeToolLifecycleProjector;
285
- const pendingNativePreToolUseFailures = [];
286
- let nativePreToolUseFailureFallbackActive = false;
287
273
  let nativeToolRunWasAbortedBeforeCleanup;
288
- let nativePreToolUseFailureFallbackTerminalReason;
289
- const emitNativePreToolUseFailure = (failure) => {
290
- emitCodexNativePreToolUseFailureDiagnostic({
291
- agentId: sessionAgentId,
292
- sessionId: params.sessionId,
293
- sessionKey: params.sessionKey,
294
- runId: sideRunParams.runId,
295
- signal: runAbortController.signal,
296
- failure,
297
- ...nativePreToolUseFailureFallbackActive ? { terminalReason: nativePreToolUseFailureFallbackTerminalReason ?? failure.disposition } : {}
298
- });
299
- };
300
- const flushPendingNativePreToolUseFailures = () => {
301
- for (const failure of pendingNativePreToolUseFailures.splice(0)) emitNativePreToolUseFailure(failure);
302
- };
303
- const activateNativePreToolUseFailureFallback = () => {
304
- if (!nativePreToolUseFailureFallbackActive) {
305
- nativePreToolUseFailureFallbackTerminalReason = nativeToolRunWasAbortedBeforeCleanup ? resolveCodexToolAbortTerminalReason(runAbortController.signal) : void 0;
306
- nativePreToolUseFailureFallbackActive = true;
307
- }
308
- flushPendingNativePreToolUseFailures();
309
- };
274
+ const nativePreToolUseFailures = createCodexNativePreToolUseFailureBuffer({
275
+ agentId: sessionAgentId,
276
+ sessionId: params.sessionId,
277
+ sessionKey: params.sessionKey,
278
+ runId: sideRunParams.runId,
279
+ signal: runAbortController.signal
280
+ });
310
281
  const abortFromUpstream = () => runAbortController.abort(params.opts?.abortSignal?.reason ?? "codex_side_question_abort");
311
282
  if (params.opts?.abortSignal?.aborted) abortFromUpstream();
312
283
  else params.opts?.abortSignal?.addEventListener("abort", abortFromUpstream, { once: true });
@@ -360,7 +331,7 @@ async function runCodexAppServerSideQuestion(params, options) {
360
331
  toolOverrides: params.sessionEntry.toolOverrides
361
332
  })
362
333
  });
363
- const approvalPolicy = hasCodexMcpToolApprovalOverrides(params.cfg?.mcp?.servers, Object.keys(projectedMcpServers), projectedMcpServers) ? withMcpElicitationsApprovalPolicy(appServer.approvalPolicy) : appServer.approvalPolicy;
334
+ const approvalPolicy = Object.keys(binding.pluginAppPolicyContext?.apps ?? {}).length > 0 || hasCodexMcpToolApprovalOverrides(params.cfg?.mcp?.servers, Object.keys(projectedMcpServers), projectedMcpServers) ? withMcpElicitationsApprovalPolicy(appServer.approvalPolicy) : appServer.approvalPolicy;
364
335
  const sandbox = appServer.sandbox;
365
336
  const nativeProviderWebSearchSupport = resolveCodexWebSearchPlan({
366
337
  config: params.cfg,
@@ -384,8 +355,7 @@ async function runCodexAppServerSideQuestion(params, options) {
384
355
  });
385
356
  const handleServerRequest = async (request, _scope, requestSignal, setExecutionTimeoutMs) => {
386
357
  const signal = AbortSignal.any([requestSignal, runAbortController.signal]);
387
- if (signal.aborted) return;
388
- if (!childThreadId || !turnId) return;
358
+ if (signal.aborted || !childThreadId || !turnId) return;
389
359
  if (request.method === "mcpServer/elicitation/request") {
390
360
  const approvalResult = await routeCodexAppServerElicitationRequest({
391
361
  requestParams: request.params,
@@ -400,7 +370,7 @@ async function runCodexAppServerSideQuestion(params, options) {
400
370
  });
401
371
  return approvalResult.kind === "handled" ? approvalResult.response : createCodexElicitationResponse("decline", null, { message: "OpenClaw Codex side questions do not support interactive MCP input." });
402
372
  }
403
- if (request.method === "item/tool/requestUserInput") return isSideUserInputRequest(request.params, childThreadId, turnId) ? emptySideUserInputResponse() : void 0;
373
+ if (request.method === "item/tool/requestUserInput") return isSideUserInputRequest(request.params, childThreadId, turnId) ? { answers: {} } : void 0;
404
374
  if (isCodexAppServerApprovalRequest(request.method)) return handleCodexAppServerApprovalRequest({
405
375
  method: request.method,
406
376
  requestParams: request.params,
@@ -445,10 +415,7 @@ async function runCodexAppServerSideQuestion(params, options) {
445
415
  response,
446
416
  durationMs: Math.max(0, Date.now() - toolStartedAt)
447
417
  });
448
- return {
449
- contentItems: response.contentItems,
450
- success: response.success
451
- };
418
+ return toCodexDynamicToolProtocolResponse(response);
452
419
  } catch (error) {
453
420
  emitDynamicToolErrorDiagnostic({
454
421
  ...diagnosticContext,
@@ -461,38 +428,45 @@ async function runCodexAppServerSideQuestion(params, options) {
461
428
  }
462
429
  };
463
430
  const serviceTier = binding.serviceTier ?? appServer.serviceTier;
464
- const nativeHookRelayEvents = resolveCodexSideNativeHookRelayEvents({
431
+ const nativeHookRelayEvents = resolveCodexNativeHookRelayEvents({
465
432
  configuredEvents: options.nativeHookRelay?.events,
466
- approvalPolicy: appServer.approvalPolicy
433
+ appServer
467
434
  });
468
- nativeHookRelay = options.nativeHookRelay ? registerCodexSideNativeHookRelay({
469
- options: options.nativeHookRelay,
470
- events: nativeHookRelayEvents,
471
- agentId: sessionAgentId,
472
- sessionId: params.sessionId,
473
- sessionKey: params.sessionKey,
474
- config: params.cfg,
475
- autoApproveMcpTools,
476
- projectedMcpServers,
477
- runId: sideRunParams.runId,
478
- channelId: buildAgentHookContextChannelFields({
435
+ if (options.nativeHookRelay && options.nativeHookRelay.enabled !== false) {
436
+ const channelId = buildAgentHookContextChannelFields({
479
437
  sessionKey: params.sessionKey,
480
438
  messageChannel: params.messageChannel,
481
439
  messageProvider: params.messageProvider,
482
440
  currentChannelId: params.currentChannelId
483
- }).channelId,
484
- requestTimeoutMs: appServer.requestTimeoutMs,
485
- completionTimeoutMs: SIDE_QUESTION_COMPLETION_TIMEOUT_MS,
486
- loopDetectionPreToolUseRelay: appServer.loopDetectionPreToolUseRelay,
487
- signal: runAbortController.signal,
488
- hostCapabilities: sideRunParams.hostCapabilities,
489
- assertCurrent,
490
- onPreToolUseFailure: (failure) => {
491
- if (nativePreToolUseFailureFallbackActive) emitNativePreToolUseFailure(failure);
492
- else if (nativeToolLifecycleProjector) nativeToolLifecycleProjector.recordPreToolUseFailure(failure, nativeToolRunWasAbortedBeforeCleanup);
493
- else pendingNativePreToolUseFailures.push(failure);
494
- }
495
- }) : void 0;
441
+ }).channelId;
442
+ nativeHookRelay = registerNativeHookRelayForBundledRuntime({
443
+ provider: "codex",
444
+ ...sessionAgentId ? { agentId: sessionAgentId } : {},
445
+ sessionId: params.sessionId,
446
+ ...params.sessionKey ? { sessionKey: params.sessionKey } : {},
447
+ ...params.cfg ? { config: params.cfg } : {},
448
+ autoApproveMcpTools,
449
+ projectedMcpServers,
450
+ runId: sideRunParams.runId,
451
+ ...channelId ? { channelId } : {},
452
+ allowedEvents: nativeHookRelayEvents,
453
+ preToolUseLoopDetection: appServer.loopDetectionPreToolUseRelay,
454
+ ttlMs: resolveCodexNativeHookRelayTtlMs({
455
+ explicitTtlMs: options.nativeHookRelay.ttlMs,
456
+ attemptTimeoutMs: SIDE_QUESTION_COMPLETION_TIMEOUT_MS,
457
+ startupTimeoutMs: appServer.requestTimeoutMs * 2,
458
+ turnStartTimeoutMs: appServer.requestTimeoutMs
459
+ }),
460
+ signal: runAbortController.signal,
461
+ runBeforeToolCall: sideRunParams.hostCapabilities.runBeforeToolCall,
462
+ assertActive: assertCurrent,
463
+ onPreToolUseFailure: (failure) => {
464
+ if (!nativePreToolUseFailures.active && nativeToolLifecycleProjector) nativeToolLifecycleProjector.recordPreToolUseFailure(failure, nativeToolRunWasAbortedBeforeCleanup);
465
+ else nativePreToolUseFailures.record(failure);
466
+ },
467
+ command: { timeoutMs: options.nativeHookRelay.gatewayTimeoutMs }
468
+ });
469
+ }
496
470
  await nativeHookRelay?.prepareInvocation();
497
471
  assertCurrent();
498
472
  const nativeHookRelayConfig = nativeHookRelay ? buildCodexNativeHookRelayConfig({
@@ -652,8 +626,8 @@ async function runCodexAppServerSideQuestion(params, options) {
652
626
  ...sideRunParams,
653
627
  agentId: sessionAgentId
654
628
  }, sideThreadId, turnId, { runAbortSignal: runAbortController.signal });
655
- for (const failure of pendingNativePreToolUseFailures) nativeToolLifecycleProjector.recordPreToolUseFailure(failure);
656
- pendingNativePreToolUseFailures.length = 0;
629
+ for (const failure of nativePreToolUseFailures.pending) nativeToolLifecycleProjector.recordPreToolUseFailure(failure);
630
+ nativePreToolUseFailures.pending.length = 0;
657
631
  if (!collector) throw new Error("Codex side thread route was not reserved");
658
632
  let result;
659
633
  try {
@@ -701,8 +675,8 @@ async function runCodexAppServerSideQuestion(params, options) {
701
675
  },
702
676
  () => collector?.route.release(),
703
677
  () => nativeToolLifecycleProjector?.finalizeActive(nativeToolRunWasAbortedBeforeCleanup),
704
- activateNativePreToolUseFailureFallback,
705
- flushPendingNativePreToolUseFailures,
678
+ () => nativePreToolUseFailures.activateFallback(nativeToolRunWasAbortedBeforeCleanup === true),
679
+ nativePreToolUseFailures.flush,
706
680
  releaseSandboxEnvironment,
707
681
  () => releaseCodexAppServerClientLease(clientLease),
708
682
  () => nativeHookRelay?.unregister(),
@@ -719,41 +693,6 @@ async function runCodexAppServerSideQuestion(params, options) {
719
693
  });
720
694
  }
721
695
  }
722
- function resolveCodexSideNativeHookRelayEvents(params) {
723
- if (params.configuredEvents?.length) return params.configuredEvents;
724
- return params.approvalPolicy === "never" ? CODEX_NATIVE_HOOK_RELAY_EVENTS : CODEX_SIDE_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS;
725
- }
726
- function registerCodexSideNativeHookRelay(params) {
727
- if (params.options.enabled === false) return;
728
- return registerNativeHookRelayForBundledRuntime({
729
- provider: "codex",
730
- ...params.agentId ? { agentId: params.agentId } : {},
731
- sessionId: params.sessionId,
732
- ...params.sessionKey ? { sessionKey: params.sessionKey } : {},
733
- ...params.config ? { config: params.config } : {},
734
- autoApproveMcpTools: params.autoApproveMcpTools,
735
- projectedMcpServers: params.projectedMcpServers,
736
- runId: params.runId,
737
- ...params.channelId ? { channelId: params.channelId } : {},
738
- allowedEvents: params.events,
739
- preToolUseLoopDetection: params.loopDetectionPreToolUseRelay,
740
- ttlMs: resolveCodexSideNativeHookRelayTtlMs({
741
- explicitTtlMs: params.options.ttlMs,
742
- requestTimeoutMs: params.requestTimeoutMs,
743
- completionTimeoutMs: params.completionTimeoutMs
744
- }),
745
- signal: params.signal,
746
- runBeforeToolCall: params.hostCapabilities.runBeforeToolCall,
747
- assertActive: params.assertCurrent,
748
- onPreToolUseFailure: params.onPreToolUseFailure,
749
- command: { timeoutMs: params.options.gatewayTimeoutMs }
750
- });
751
- }
752
- function resolveCodexSideNativeHookRelayTtlMs(params) {
753
- if (params.explicitTtlMs !== void 0) return params.explicitTtlMs;
754
- const relayBudgetMs = params.requestTimeoutMs * CODEX_SIDE_NATIVE_HOOK_RELAY_STARTUP_REQUEST_COUNT + params.completionTimeoutMs + CODEX_SIDE_NATIVE_HOOK_RELAY_TTL_GRACE_MS;
755
- return Math.max(CODEX_SIDE_NATIVE_HOOK_RELAY_MIN_TTL_MS, Math.floor(relayBudgetMs));
756
- }
757
696
  function buildSideRunAttemptParams(params, options) {
758
697
  return {
759
698
  params,
@@ -872,9 +811,6 @@ async function createCodexSideToolBridge(input) {
872
811
  webSearchPlan
873
812
  };
874
813
  }
875
- function emptySideUserInputResponse() {
876
- return { answers: {} };
877
- }
878
814
  function isSideUserInputRequest(value, threadId, turnId) {
879
815
  return isJsonObject(value) && value.threadId === threadId && value.turnId === turnId;
880
816
  }